[ 
https://issues.apache.org/jira/browse/OPENJPA-1873?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12978771#action_12978771
 ] 

Mark Struberg commented on OPENJPA-1873:
----------------------------------------

Hi!

This is just a small summary about the discussions I had with Rick at our 
yesterdays debugging session.

It seems that the DetachStateManager is almost in the original state as 
imported by Patrick in early 2006 and might not reflect all things needed for 
JPA2.

The attach() in line #108 is of special interrest. It consists of 3 parts:

1.) (line #131 - #166) prepare old Values from the database to be able to 
restore those values in case of a rollback.
 comment: Imo this is NOT needed if openjpa.RestoreState is RESTORE_NONE!

2.) (handled in the same block somehow) if optimistic locking is used (does the 
whole merging make any sense for row-locking at all?): Check the version in the 
database to make sure that we didn't have a concurrent modification already.

3.) (line #168 - #295) perform the actual 'merging'. by setting the values from 
the toAttach entity into the one from the DB.

so far so good.

Now to the problematic spots. 

Depending on the situation (_loaded and _dirty states) 1.) xor 3.) fire the 
@PostLoad event. The logic for the lifecyle event is to get fired if all fields 
(or all fields of a FetchGroup if fgs are used) got set. If all fields have 
been made dirty in the detached entity then this will happen in 1.) If not, it 
will happen in 3.). The problem here is that in 1.) the entity from the DB is 
not complete and in 3.) has nothing to do with any load from the database, 
since it contains the dirty values from the toAttach entity.

It's really problematic that both the load() from the database and the attach() 
use the same StateManagerImpl#storeStringField() without any distinction. So 
those highly different tasks will both fire the same @PostLoad lifecycle event. 
Imo this must not happen while attaching.

Rick, are you d' accord so far?


> EntityManager#merge sometimes passes wrong entity values to @PostLoad 
> EntityListeners 
> --------------------------------------------------------------------------------------
>
>                 Key: OPENJPA-1873
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-1873
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: kernel
>    Affects Versions: 2.0.0, 2.0.1, 2.0.2
>            Reporter: Mark Struberg
>         Attachments: OPENJPA-1873-unittest.patch, postloadtest.zip
>
>
> I've tested this with the latest from branches/2.0.x.
> My entity has an @EntityListeners which observes the @PostLoad lifecycle 
> event. This listener stores the 'old' values from the database for later use 
> (see http://struberg.wordpress.com/2010/07/31/howto-changelog-with-jpa/ for 
> the intention behind). All works well if the table has only a few rows. But 
> if you add more rows, OpenJPA tries to optimize the access and only loads the 
> @Version field + the dirty fields. In this case the merging seems to be 
> wrong, because I get the NEW values from the dirty fields instead of the 
> original values from the database passed to my @PostLoad method.
> Did cost me a few grey hairs to track down the differences between the 
> working and the broken scenarios here ;) But finally I was able to creat a 
> unit test showing the problem

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to