Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Eclipselink JPA merge problem(Eclipselink sometimes misses changes made to entities when merging)
Eclipselink JPA merge problem [message #696768] Thu, 14 July 2011 19:36 Go to next message
Jeroen Peelaerts is currently offline Jeroen Peelaerts
Messages: 8
Registered: July 2011
Junior Member
Dear,

I have been using Eclipselink 2.3 for a while in my standalone J2SE swing application, communicating with a remote MySQL database. Lately I have been experiencing some problems with merging entities. It seems that when calling merge, Eclipselink sometimes does not commit changes made to recently detached persisted entities. Here a log dump showing the exact problem

12:01:08,078 [INFO] [JpaDao#pool-1-thread-2] - Merging Gert Eyskens
12:01:08,078 [DEBUG] [RunwalkVideoApp$RunwalkLogger#pool-1-thread-2] - SELECT 1
12:01:08,078 [DEBUG] [RunwalkVideoApp$RunwalkLogger#pool-1-thread-2] - communication_failure_attempting_begintransaction_retry
12:01:08,078 [DEBUG] [RunwalkVideoApp$RunwalkLogger#pool-1-thread-2] - disconnect
12:01:08,078 [DEBUG] [RunwalkVideoApp$RunwalkLogger#pool-1-thread-2] - connecting
12:01:08,109 [INFO] [StatusPanel#AWT-EventQueue-0] - Wijzigingen bewaren..
12:01:08,234 [DEBUG] [RunwalkVideoApp$RunwalkLogger#pool-1-thread-2] - connected_user_database_driver
12:01:08,250 [DEBUG] [RunwalkVideoApp$RunwalkLogger#pool-1-thread-2] - UPDATE phppos_people SET VERSION = ? WHERE ((person_id = ?) AND (VERSION = ?))
	bind => [2, 5155, 1]
12:01:08,281 [DEBUG] [RunwalkVideoApp$RunwalkLogger#pool-1-thread-2] - UPDATE analysis SET COMMENTS = ? WHERE (id = ?)
	bind => [2160 m  10 narrow , 8011]


Entity and DAO source code can be found in attachment.

When creating a person entity in my swing application, it is persisted to the database first with an empty last name and firstname. This way it can have an id generated for the hashcode and equals to be consistent. After this, it is detached (tx after persist is closed) and added to a List which is shown in the GUI using the beans binding framework.

At that time, the user can edit the entity, and when he is done, save and merge the changes using the entityManager.merge opertation.

the entityManager.merge operation starts at the first line. There a person.toString() is dumped to the log, where one can clearly see that the name and the first name of the person entity are set by the user. 80% of the time the changed first name and last name are commited to the db.

By analyzing the eclipselink logging for a while now, I found that Eclipselink sometimes seems to refresh the entity from the database before performing an UPDATE, and sometimes not.

Can anybody here tell me when Eclipselink decides to check the values of an entity with the database when using the AUTO (=DEFERRED) change tracking setting ? I feel that this can be a possible reason to this issue. that Eclipselink thinks the entity in its cache is the latest version and takes the state of the entity as it was persisted at first to make the merge (so with empty last name and first name). Does anybody know a programmatical way to invalidate the cache here and force eclipselink to make a lookup before merging (so bypassing the change tracking algorithm)?

At this moment, I do not use any weaving for compatbility reasons (beans bindings seems to have trouble with it), so changeTracking should prolly stick with DEFERRED. I have heavily optimized the logic behind the merging, and only entities that are really dirty (edited by the user) are merged to the db. So invalidating the cache should not have too much of a performance impact here.



Thanks in advance
  • Attachment: JpaDao.java
    (Size: 5.41KB, Downloaded 150 times)
  • Attachment: Person.java
    (Size: 4.32KB, Downloaded 112 times)
Re: Eclipselink JPA merge problem [message #698013 is a reply to message #696768] Mon, 18 July 2011 15:40 Go to previous messageGo to next message
Gordon Yorke is currently offline Gordon Yorke
Messages: 77
Registered: July 2009
Member
Can you verify that the Entity loaded by EclipseLink does not have the name set? Can you do a em.find().toString() and then the merge? Also try removing the lock code. If the Entity has changes the version value will be updated automatically.
Re: Eclipselink JPA merge problem [message #698133 is a reply to message #698013] Mon, 18 July 2011 20:50 Go to previous messageGo to next message
Jeroen Peelaerts is currently offline Jeroen Peelaerts
Messages: 8
Registered: July 2011
Junior Member
I will add some logging to check that. For the locking, are you sure that the version will increment in case an entity changes that is owned by a relationship with the Person?

My domain model consists of an object graph in which the Person entity owns all the other entities (mostly one to many relationships). If something changes to any of those descendants, will the version still increment when merging the person? Or does this only happen when the person entity itself is updated?

Thanks for the tips alright..
Re: Eclipselink JPA merge problem [message #701050 is a reply to message #698133] Sun, 24 July 2011 14:07 Go to previous messageGo to next message
Jeroen Peelaerts is currently offline Jeroen Peelaerts
Messages: 8
Registered: July 2011
Junior Member
Ok after adding the logging I have another clue on what is going on here. It seems that eclipselink is maintaining an up to date version in its persistence context after persisting the person entity the first time using em.persist() . I added a em.find() before the em.merge() and it seems that when the entity retrieved from the find() has a different name and firstname, eclipselink will go back to the db to query for this entity and do the updates correctly. In this case, it seems that the entity is not directly available from the persistence context.

When the find() returns an entity that has the same name, eclipselink will not go back to the db, as shown in the logging in my first post, and wil fail to save the updated entity. In this case, the entity seems to be available from the persistence context, despite being detached.

I'm wondering why sometimes these entities are up to date in the persistence context while the transaction in which they were persisted at first was committed and the related entitymanager closed. When I do a merge, they should not be available from the persistence context according to the jpa spec, or do I need to do a clear() after persisting every entity anyway?

For some reason eclipselink seems to be keeping track of the entity in its persistence context after it is persisted using persist(), even when the tx was committed and the entitymanager closed. Does anybody have a reasonable explanation for this?

Thanks.
(no subject) [message #701052 is a reply to message #698133] Sun, 24 July 2011 14:07 Go to previous messageGo to next message
Jeroen Peelaerts is currently offline Jeroen Peelaerts
Messages: 8
Registered: July 2011
Junior Member
Ok after adding the logging I have another clue on what is going on here. It seems that eclipselink is maintaining an up to date version in its persistence context after persisting the person entity the first time using em.persist() . I added a em.find() before the em.merge() and it seems that when the entity retrieved from the find() has a different name and firstname, eclipselink will go back to the db to query for this entity and do the updates correctly. In this case, it seems that the entity is not directly available from the persistence context.

When the find() returns an entity that has the same name, eclipselink will not go back to the db, as shown in the logging in my first post, and wil fail to save the updated entity. In this case, the entity seems to be available from the persistence context, despite being detached.

I'm wondering why sometimes these entities are up to date in the persistence context while the transaction in which they were persisted at first was committed and the related entitymanager closed. When I do a merge, they should not be available from the persistence context according to the jpa spec, or do I need to do a clear() after persisting every entity anyway?

For some reason eclipselink seems to be keeping track of the entity in its persistence context after it is persisted using persist(), even when the tx was committed and the entitymanager closed. Does anybody have a reasonable explanation for this?

Thanks.
Re: (no subject) [message #701881 is a reply to message #701052] Mon, 25 July 2011 17:45 Go to previous messageGo to next message
James Sutherland is currently offline James Sutherland
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

EclipseLink maintains a shared cache by default.

To disable the shared cache see,
http://wiki.eclipse.org/EclipseLink/FAQ/How_to_disable_the_shared_cache%3F

To refresh the cache see,
http://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching#How_to_refresh_the_cache



James : Wiki : Book : Blog : Twitter
(no subject) [message #701914 is a reply to message #701052] Mon, 25 July 2011 17:45 Go to previous messageGo to next message
James is currently offline James
Messages: 272
Registered: July 2009
Senior Member
EclipseLink maintains a shared cache by default.

To disable the shared cache see,
http://wiki.eclipse.org/EclipseLink/FAQ/How_to_disable_the_shared_cache%3F

To refresh the cache see,
http://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching#How_to_refresh_the_cache


--
James : http://wiki.eclipse.org/EclipseLink : http://en.wikibooks.org/wiki/Java_Persistence : http://java-persistence-performance.blogspot.com/
Re: (no subject) [message #735365 is a reply to message #701914] Tue, 11 October 2011 15:36 Go to previous messageGo to next message
Jeroen Peelaerts is currently offline Jeroen Peelaerts
Messages: 8
Registered: July 2011
Junior Member
Evicting every entity after persisting it the first time solved the problem for me.

Strangely the cache gets out of date once in a while.

Thanks
Re: (no subject) [message #735395 is a reply to message #701914] Tue, 11 October 2011 15:36 Go to previous message
Jeroen Peelaerts is currently offline Jeroen Peelaerts
Messages: 8
Registered: July 2011
Junior Member
Evicting every entity after persisting it the first time solved the problem for me.

Strangely the cache gets out of date once in a while.

Thanks
Previous Topic:Map Key ManyToMany Relationships
Next Topic:SQL to JPA
Goto Forum:
  


Current Time: Fri Sep 19 05:54:31 GMT 2014

Powered by FUDForum. Page generated in 0.08409 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software