0

Most important structural description:

In my application is used Spring data JPA. I have a model part in my application:

@Entity
public class Event implements Identifiable {
  // ...
  @OneToMany(cascade = CascadeType.ALL, mappedBy = "event", orphanRemoval = true)
  @OrderColumn(name = "order_index")
  private List<Attendee> attendees = new ArrayList<>();
  // ...
}

@Entity
public class Attendee implements Identifiable {
  // ...
  @ManyToOne
  @JoinColumn(columnDefinition = "event_id")
  private Event event;
  // ...
}

It should be clear for all who knows JPA.

I've implemented test to save an event, as result dependent attendees collection saves also (hibernate magic used because of correspond relation settings shown in very beginning.)

eventRepository.save(event);

provides save|update event and replace all old nested attendees with new ones.

Problem description:

Some times I need use additional handlers in same transaction with saving event. They use repositories also:

// transaction starts... some handlers are used
eventRepository.save(event);
// some additional handlers2 are used
// transaction ends

If handlers2 contains any repository operation with independent entity, for example:

profileRepository.findAll();
// or
profileRepository.findByEmail("anyEmail");

, it fails with exception org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.nextiva.calendar.entity.Attendee. It seems Attendee collection should be saved because it was not.

To fix the issue I've used workaround like:

// transaction starts... some handlers are used
attendeeRepository.save(event.getAttendees());
eventRepository.save(event);
// some additional handlers2 are used
// transaction ends

It works now, but I do not like this way.

Questions:

  1. Is it my architectural issue?
  2. Is it hibernate issue?
  3. How should it be configured without redundant calling attendeeRepository.save(event.getAttendees());?
Sergii
  • 7,044
  • 14
  • 58
  • 116
  • Did not try to use `eventRepository.saveAndFlush(event)` (from JpaRepository)? – Cepr0 May 17 '17 at 20:43
  • No, i did not because of spring jpa repositories for example: `org.springframework.data.repository.PagingAndSortingRepository`, `org.springframework.data.jpa.repository.JpaRepository` do not provide `saveAndFlush` – Sergii May 18 '17 at 05:10
  • What does prevents to replace PagingAndSortingReposito‌​ry to JpaRepository? – Cepr0 May 18 '17 at 06:33
  • How will it help? – Sergii May 18 '17 at 06:37
  • 1
    http://docs.spring.io/autorepo/docs/spring-data-jpa/1.3.0.RELEASE/api/org/springframework/data/jpa/repository/JpaRepository.html#saveAndFlush(T) – Cepr0 May 18 '17 at 09:20
  • It really works, I missed this solution. ...you should answer my question, thank i'll vote it. – Sergii May 18 '17 at 10:27

1 Answers1

1

Try to switch to JpaRepository and use

eventRepository.saveAndFlush(event);

instead of eventRepository.save(event).

Or

eventRepository.save(event);
eventRepository.flush();

It will force the repo to flush all pending changes to the database.


Also check whether you set @Transactional(readOnly = true) on your repo interface that turn the flush mode to NEVER (as described in the reference, or MANUAL as described here) also for save methods. Perhaps this is the issue...

Community
  • 1
  • 1
Cepr0
  • 28,144
  • 8
  • 75
  • 101