Description
I have a simple example. A customer has a reference to an address and a (primary) contact (an extension of person). Find the customer, get the contact and evict it from L2. Now find the customer again using a new entity manager. Begin a Tx and change the address of the contact and then call Customer.getPrimaryContact() (this is important) Rollback the Tx. Now find the customer again using another new EntityManager and call Customer.getPrimaryContact().getAddress(). The address associated with the contact is Null and not the original address as expected. The same scenario works fine under OpenJPA 1.2.2.
The reason this is a big problem for us is we use L2 caching in our application and the application is clustered. The same problem occurs if different nodes in the cluster operate on the same objects. In a cluster "evict" is not directly called, but the RemoteCommitProvider will evict the L2 and create the same problem.
I have attached example code to reproduce the problem using a single JVM and calling Evict. I also have another example where you can deploy the code on two nodes in a cluster and see the problem occurs that way as well. Each example contains Unix shell scripts and Windows cmd files as well. Each are paired for JPA 1.0 and JPA 2.0. Again, the problem only occurs under JPA 2.0.
This is a block for us. We cannot ship our product with this type of problem as it means objects and their graph can be corrupted.
Attachments
Attachments
- OPENJPA-1899.test.patch
- 14 kB
- Richard G. Curtis
- evictproblem.zip
- 6.25 MB
- Robert Krier
Activity
One more thing to note:
1) The problem does not occur if L2 caching is not enabled. This is not a viable workaround for us.
2) The problem does not occur if eager fetching is used in the object graph instead of lazy. This is not a viable workaround for us.
Bob
...thanks for the test case but we can't use it and probably shouldn't look at it? Can I have you re-upload your Entities / the test case and check the "Grant license to ASF for inclusion in ASF works" box when you upload. I'll use that info to create a OpenJPA unit test to more easily recreate the problem.
Hi Rick,
I have re-uploaded the test case zip file with the ASF inclusion option.
Let me know if you still have problems with it. I can send it directly to
you if needed.
The entities are in src/com/foo/bar/models and the test cases are in
src/com/foo/bar/app. It should be pretty straight forward to see what's
going on. If something isn't clear, let me know and I'll be happy to
assist.
Thanks for your response on this.
Bob
----------------------------------------------------------------------------->>
-
Hi Ric,
Has anyone had a chance to look into this issue? Do you have everything
you need from me?
Thanks,
Bob
Attaching a OpenJPA style unit test.... but I must be missing something because I'm getting a NPE from test code[1]. It looks like when you have openjpa.DetachState set to fgs, we null out the reference to primaryContact on rollback... if openjpa.DetachState is set to loaded, it seems to work properly?
Robert – Can you look at the patch that I've posted to see if I missed something in my butchering of your test?
Thanks,
Rick
[1] System.out.println("The address after rollback is: "
+ (cust2.getPrimaryContact().getAddress() == null ? "null" : cust2.getPrimaryContact().getAddress() <- NPE from this line
.getStreet()) + "\n");
Thanks Rick, I'll look at it this morning.
Regards,
Bob
----------------------------------------------------------------------------->>
-
Hi Ric,
What exactly do you want me to look at. I've been trying to get Openjpa set
up with Maven and I'm having a lot of problems. You comment about primary
contact getting nulled out after rollback is the problem I'm reporting.
That shouldn't be happening.
I've tried running my tests with openjpa.DetachState=loaded and it still
fails. Again, everything works fine under OpenJPA 1.2.2.
Thanks and regards,
Bob
https://issues.apache.org/jira/browse/OPENJPA-1899?page=com.atlassian.jira.pl>>
u
----------------------------------------------------------------------------->>
Bob -
Just so we're clear, the problem you're reporting is that cust2.getPrimaryContact() returns null after calling rollback? The test that I posted also fails on 1.2.x.... so I must be missing something.
Thanks,
Rick
Yes that's the problem, however it doesn't fail under 1.2.2 for me. If I
run EvictTest with 2.0.1 libraries, the output is as follows:
In order to run this test, you must configure the remote commit provider
setting for SJVM.
The address from first find is: This is the original street address
The address from second find is: This is the original street address
The address before rollback is: This is a new street address
The address after rollback is: This is the original street address
The address from third find is: null
If I run EvictTest with the 1.2.2 libraries, the output is as follows:
In order to run this test, you must configure the remote commit provider
setting for SJVM.
The address from first find is: This is the original street address
The address from second find is: This is the original street address
The address before rollback is: This is a new street address
The address after rollback is: This is the original street address
The address from third find is: This is the original street address
Make sense?
----------------------------------------------------------------------------->>
-
Ok, my test must be not quite the same scenario..... I'm getting a NPE from EvictTest:49. The NPE is calling .getAddress() on a null getPrimaryContact().
Thanks,
Rick
No problem. Thanks Rick.
----------------------------------------------------------------------------->>
-
Robert -
I ran with your provided example this morning with 2.1.x and here is the result that I'm seeing:
C:\dev\jpa\tmp\evictproblem\bin>c:\java6-sun\bin\java.exe -cp ..\conf;..\classes;..\lib\jdbcdrivers\mysql-connector-java-3.1.13-bin.jar;..\lib\openjpa2.0.1\openjpa-all-2.1.0-SNAPSHOT.jar com.foo.bar.app.EvictTest
In order to run this test, you must configure the remote commit provider setting for SJVM.
58 evictproblem INFO [main] openjpa.Runtime - Starting OpenJPA 2.1.0-SNAPSHOT
139 evictproblem INFO [main] openjpa.jdbc.JDBC - Using dictionary class "org.apache.openjpa.jdbc.sql.MySQLDictionary".
770 evictproblem INFO [main] openjpa.Runtime - The Entity "com.foo.bar.models.Contact" was enhanced at level "2", but the current level of enhancement is "961,774".
774 evictproblem INFO [main] openjpa.Runtime - A down level Entity was detected and logged. Please enable RUNTIME trace to see all down level Entities.
The address from first find is: This is the original street address
The address from second find is: This is the original street address
The address before rollback is: This is a new street address
The address after rollback is: This is the original street address
The address from third find is: This is the original street address
Thanks,
Rick
Hi Rick,
I just tried it with the 2.1.0 snapshot and you are correct, the problem
seems to be fixed. Correct me if I'm wrong, but 2.1.0 is not officially
released yet, right? Do you know what changes were made to fix this
problem? Is it something I can back port into 2.0.1 easily?
Thanks!
Bob
----------------------------------------------------------------------------->>
-
Bob -
Honestly I didn't spend any time looking at the test with 2.0.1, but nothing comes to mind that would have changed. Can I have you try one of the nightly 2.0.x snapshots? Then at least we can figure out if this is something that has already been fixed in the 2.0.x stream.
I'm in the middle of another JIRA currently, but I should have some time later on to take another look at this one.
Thanks,
Rick
Sure, I'll give it a try.
----------------------------------------------------------------------------->>
-
Hi Rick,
I don't see any 2.0.x snapshots on OpenJPA's site. Let me know if I can get
them some other way.
Bob
----------------------------------------------------------------------------->>
-
Hi again,
I did find the 2.0.2 snapshot and tried it. It fails.
The address from first find is: This is the original street address
The address from second find is: This is the original street address
The address before rollback is: This is a new street address
The address after rollback is: This is the original street address
The address from third find is: null
https://issues.apache.org/jira/browse/OPENJPA-1899?page=com.atlassian.jira.pl>>
u
gin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12973256#action_1>>
2
Hi Rick,
Is there something you wanted me to look at? The attachment doesn't come
through.
Bob
----------------------------------------------------------------------------->>
-
Bob -
Sorry, no. I was removing the non-asf licensed attachment. I'm just digging into your issue now... hopefully I'll come up with something shortly here.
Thanks,
Rick
Bob -
I can't quite explain it yet, but OPENJPA-1884 is the change that fixed this problem in 2.1.x and trunk. It appears that we are putting a dirty entity back into the datacache.. I haven't completely got my head around this one yet, but I can fix the problem. That being said, 2.0.x is a WebSphere maintained branch and it might be tough to get this fix into that branch.
What are your thoughts on using 2.1.0 for your application? We haven't cut a release yet, but I expect we will shortly after the new year.
Thanks,
Rick
If it is early in the year that it is released, we can probably be fine with
that. I would like to make the change locally for myself so our QA people
can test with the fix now. Is there an easy way for me to diff the change
so I can modify my own copy of the class?
Thanks Rick!
Bob
----------------------------------------------------------------------------->>
-
Never mind, I found the changes made. I'm attempting to back port them to
2.0.1 and I'll try it out. I'll keep you posted.
Bob
https://issues.apache.org/jira/browse/OPENJPA-1899?page=com.atlassian.jira.pl>>
u
gin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12974207#action_1>>
2
Hi Rick,
I back ported the changes made for JIRA OPENJPA-1884 locally and it seemed
to fix the problem. We should be able to live with it this way for now
until 2.1.0 is GA. Thanks for all your help on this!!!
Have a great holiday!!!!
Bob
--------------------------------------------------------------------------->>>>
-
Instructions:
Unzip the attached file. In the conf directory, there is a file called schema_mysql.sql.
1) Create a new MySQL database and install the tables in the script.
2) Edit conf/openjpa.properties and set the openjpa.ConnectionProperties to your database.
3) In the shell script and/or cmd files in the bin directory, change JAVA_HOME as appropriate for your environment.
4) Run bin/simple-evict-sjvm-1.0 and bin/simple-evict-sjvm-2.0. You will see there is no problem under OpenJPA 1.0 but there is a problem 2.0.
You can also deploy the application on two nodes and run the two node tests on each node. There are instructions given in each script on how to configure. Basically you just need to edit the RemoteCommitProvider settings as appropriate on each node and run the tests on each node and follow the prompts given in the application.
Note: I removed openjpa-all-2.0.1.jar from the lib/openjpa2.0.1 in order to keep the size of this upload small enough to attach.
Bob