1

Some background, I use JPA/Hibernaate/Spring in my web application I also use org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter and an extended persistence context to handle my entities.

The problem:

  1. user clicks the edit link for an entity

  2. Entity is loaded from the database using find methods and entity gets stored in session

  3. user makes changes to entity and hits save

  4. user changes are reflected on the entity stored in session (in the controller)

  5. entity is sent to a method (annotated with @Transactional) in a service class

  6. no changes to the entity (or any other entity) happens in the service class (it does some other none persistence related stuff)

  7. no changes are flushed to the database after the service method is done!!!?

NOTE: The service class is a spring component, I debugged the spring proxy created for it, when calling the service method annotated with @Transactional I saw spring create a NEW transaction before service method call and I also saw it commit the transaction successfully. From my understanding that even though the changes to the entity didn't happen in transaction boundaries it still should be flushed to the database. why is the changes are not being flushed?!

Yazan Jaber
  • 2,068
  • 25
  • 36

2 Answers2

1

For an entity to be flushed, it has to be managed. The entity is probably detached.

I can think of two possible reasons for it to be detached in this case:

  1. Even for an extended persistence context, the entity manager is created and closed. Perhaps you open and close it in each call to the server? Then, because you try to save the entity in a different call to the server that the one where that entity was created, the entity manager is a new one and therefore the entity is not managed.

  2. The entity is serialized between those calls to the server. When an entity is serialized, it becomes detached. This can happen easily because servers often write session data to disk between calls.

Pablo
  • 3,655
  • 2
  • 30
  • 44
  • Point 1 is what is happening in my case, since OpenEntityManagerInViewFilter closes the entitymanager used to load my entities at the end of each request, the entities become detached and need to be merged in order for the changes made to them in any following request to take effect. I wonder if this also the case when using container managed entity manager (with extended persistence context) in stateful session beans in EJB? – Yazan Jaber Jan 16 '13 at 21:11
-1

If the users changes are made outside your service layer, the changes wont be persisted automatically unless you call persist inside your service layer:

entityManager.persist()

and you can see here why to use persist over merge.

I hope that was helpful.

Community
  • 1
  • 1
Zaroual Mohamed
  • 315
  • 2
  • 7
  • Because the entity is detached, the `persist` method cannot be used. – Mohammad Dehghan Jan 16 '13 at 12:08
  • @MD.Unicorn as I said I use extended persistence context and so the entity is not detached. – Yazan Jaber Jan 16 '13 at 12:17
  • @Zaroual Thanks, is there any reference you could make to support your answer and explains this case? because its obvious that I can solve the issue by using APIs but I'm more interested in understanding the problem and using a best practice. – Yazan Jaber Jan 16 '13 at 12:19
  • I didnt say you have to call persist outside your service layer, it's clear that will not work because the entity is detached and if you try this you will get an exception : Detached entity passed to be persisted or smthing like that. So, Call the persist method inside your service layer. – Zaroual Mohamed Jan 16 '13 at 13:05