Issue Details (XML | Word | Printable)

Key: NUCRDBMS-645
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Unassigned
Reporter: Rp
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
DataNucleus Store RDBMS

NPE in UpdateRequest when using optimistic txns, new-table inheritance, version in a field and updating field in subclass

Created: 08/Feb/13 09:36 PM   Updated: 20/Feb/13 12:05 PM   Resolved: 14/Feb/13 03:12 PM
Component/s: ORM
Affects Version/s: 2.2.4, 3.0.10, 3.1.4, 3.2.0.m3
Fix Version/s: 3.2.0.m4

File Attachments: 1. Zip Archive 645.zip (34 kB)
2. Zip Archive dn-bug-proof.zip (4 kB)

Environment:
* Linux-3.2.0
* openjdk-7-jdk
* datanucleus-core, datanucleus-rdbms, datanucleus-api-jpa
* GWT, with RequestFactoryServlet
* Spring 3.1.2.RELEASE
* PostgreSQL 9.1

Forum Thread URL: http://www.datanucleus.org/servlet/forum/viewthread_thread,7370
Datastore: PostgreSQL
Severity: Production


 Description  « Hide
Trying to update a field from an entity that inherits from an abstract entity causes NPE

[INFO] 19:29:39 ERROR [btpool0-2][CustomRequestFactoryServlet$ApplicationExceptionLogger] Server Error
[INFO] java.lang.NullPointerException: null
[INFO] at org.datanucleus.store.rdbms.request.UpdateRequest.execute(UpdateRequest.java:368) ~[datanucleus-rdbms-3.2.0-m1.jar:na]
[INFO] at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.updateTable(RDBMSPersistenceHandler.java:411) ~[datanucleus-rdbms-3.2.0-m1.jar:na]
[INFO] at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.updateTable(RDBMSPersistenceHandler.java:407) ~[datanucleus-rdbms-3.2.0-m1.jar:na]
[INFO] at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.updateObject(RDBMSPersistenceHandler.java:384) ~[datanucleus-rdbms-3.2.0-m1.jar:na]
[INFO] at org.datanucleus.state.JDOStateManager.flush(JDOStateManager.java:3723) ~[datanucleus-core-3.2.0-m1.jar:na]
[INFO] at org.datanucleus.ExecutionContextImpl.flushInternalWithOrdering(ExecutionContextImpl.java:3929) ~[datanucleus-core-3.2.0-m1.jar:na]
[INFO] at org.datanucleus.ExecutionContextImpl.flushInternal(ExecutionContextImpl.java:3852) ~[datanucleus-core-3.2.0-m1.jar:na]
[INFO] at org.datanucleus.ExecutionContextImpl.flush(ExecutionContextImpl.java:3794) ~[datanucleus-core-3.2.0-m1.jar:na]
[INFO] at org.datanucleus.ExecutionContextImpl.preCommit(ExecutionContextImpl.java:4182) ~[datanucleus-core-3.2.0-m1.jar:na]
[INFO] at org.datanucleus.ExecutionContextImpl.transactionPreCommit(ExecutionContextImpl.java:427) ~[datanucleus-core-3.2.0-m1.jar:na]
[INFO] at org.datanucleus.TransactionImpl.internalPreCommit(TransactionImpl.java:397) ~[datanucleus-core-3.2.0-m1.jar:na]
[INFO] at org.datanucleus.TransactionImpl.commit(TransactionImpl.java:286) ~[datanucleus-core-3.2.0-m1.jar:na]
[INFO] at org.datanucleus.api.jpa.JPAEntityTransaction.commit(JPAEntityTransaction.java:103) ~[datanucleus-api-jpa-3.2.0-m1.jar:na]
[INFO] at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:512) ~[spring-orm-3.1.2.RELEASE.jar:3.1.2.RELEASE]

Rp added a comment - 08/Feb/13 09:38 PM
I attached the entities. Run the code from "Main".

Rp made changes - 08/Feb/13 09:38 PM
Field Original Value New Value
Attachment dn-bug-proof.zip [ 11890 ]
nicolas added a comment - 10/Feb/13 04:18 PM
I do not think this is a valid use of JPA.
Retrieval by navigation from detached objects is not supported, so only persistent fields that have been loaded before detachment should be used. Changes to detached entity objects are not stored in the database unless modified detached objects.

See JPA spec, section 3.2.7 Detached Entities: "Detached entity instances continue to live outside of the persistence context in which they were persisted or retrieved. Their state is no longer guaranteed to be synchronized with the database state.
[..]
If the persistent field or property is an association, the available state of an associated instance may only
be safely accessed if the associated instance is available. The available instances include:
• Any entity instance retrieved using find().
• Any entity instances retrieved using a query or explicitly requested in a fetch join.
• Any entity instance for which an instance variable holding non-primary-key persistent state
was accessed by the application."

In other words, the entity must be merged (em.merge()) back first. Also, the @Version needs to be added on D. Then it works.

Without the @Version though there is a problem:
Feb 10, 2013 4:16:43 PM org.datanucleus.store.rdbms.request.UpdateRequest execute
SEVERE: Object "D@e1baffa" (id="2") has been changed in the datastore since your last read. Your transaction is using version "1" but this doesnt exist in the datastore now
Feb 10, 2013 4:16:43 PM Main main
INFO: >> Exception thrown retrieving objects
javax.persistence.RollbackException: Transaction failed to commit
at org.datanucleus.api.jpa.JPAEntityTransaction.commit(JPAEntityTransaction.java:122)
at Main.main(Main.java:54)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: javax.persistence.OptimisticLockException: Some instances failed to flush successfully due to optimistic verification problems.
at org.datanucleus.api.jpa.NucleusJPAHelper.getJPAExceptionForNucleusException(NucleusJPAHelper.java:421)
at org.datanucleus.api.jpa.JPAEntityTransaction.commit(JPAEntityTransaction.java:116)
... 6 more
Caused by: org.datanucleus.exceptions.NucleusOptimisticException: Object "D@e1baffa" (id="2") has been changed in the datastore since your last read. Your transaction is using version "1" but this doesnt exist in the datastore now
at org.datanucleus.store.rdbms.request.UpdateRequest.execute(UpdateRequest.java:385)
at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.updateTable(RDBMSPersistenceHandler.java:412)
at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.updateTable(RDBMSPersistenceHandler.java:408)
at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.updateObject(RDBMSPersistenceHandler.java:385)
at org.datanucleus.state.JDOStateManager.flush(JDOStateManager.java:3729)
at org.datanucleus.ExecutionContextImpl.flushInternalWithOrdering(ExecutionContextImpl.java:4019)
at org.datanucleus.ExecutionContextImpl.flushInternal(ExecutionContextImpl.java:3942)
at org.datanucleus.ExecutionContextImpl.flush(ExecutionContextImpl.java:3876)
at org.datanucleus.ExecutionContextImpl.preCommit(ExecutionContextImpl.java:4272)
at org.datanucleus.ExecutionContextImpl.transactionPreCommit(ExecutionContextImpl.java:581)
at org.datanucleus.TransactionImpl.internalPreCommit(TransactionImpl.java:404)
at org.datanucleus.TransactionImpl.commit(TransactionImpl.java:293)
at org.datanucleus.api.jpa.JPAEntityTransaction.commit(JPAEntityTransaction.java:103)
... 6 more



Made a simpler zip to reproduce the problem with a pom file.

mvn clean
mvn compile
run Main

nicolas added a comment - 10/Feb/13 04:18 PM
simplified package.

nicolas made changes - 10/Feb/13 04:18 PM
Attachment 645.zip [ 11900 ]
Andy Jefferson made changes - 14/Feb/13 03:10 PM
Summary NPE in UpdateRequest NPE in UpdateRequest when using optimistic txns, new-table inheritance, version in a field and updating field in subclass
Fix Version/s 3.2.0.m4 [ 11883 ]
Affects Version/s 3.1.4 [ 11811 ]
Affects Version/s 3.0.10 [ 11535 ]
Affects Version/s 2.2.4 [ 11183 ]
Andy Jefferson added a comment - 14/Feb/13 03:12 PM - edited
SVN trunk works.

PS, there is no need for em.persist() or em.merge(). Objects from a query (in an extended context, or within a transaction) are in managed state. Modifying a managed object means it is then in "persistent-dirty" state and all changed go to the datastore. Obviously other JPA implementations may require that you call em.merge since they can't detect changes as easily, but then that's their problem.

Andy Jefferson made changes - 14/Feb/13 03:12 PM
Status Open [ 1 ] Resolved [ 5 ]
Resolution Fixed [ 1 ]
Andy Jefferson made changes - 20/Feb/13 12:05 PM
Status Resolved [ 5 ] Closed [ 6 ]