MountainClimb / datanucleus-appengine

Automatically exported from code.google.com/p/datanucleus-appengine
0 stars 0 forks source link

One-to-One bidir relation insert in single persist throws exception #165

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. class A owns one class B1 instance which has mapped relation to parent A
2. begin transaction, a=new A(), new B1( a ); makepersist(a)

What is the expected output? What do you see instead?
Separate transactions for new A and new B work fine.
Single combined transaction throws datanucleus NPE

What version of the product are you using? On what operating system?
GAE 1.2.6
GWT 1.7.1
Windows Vista
Eclipse 3.5
Java 1.6 

Please provide any additional information below.
Full stack trace and sample project attached. 

Caused by: java.lang.NullPointerException
    at 
org.datanucleus.store.mapped.mapping.PersistenceCapableMapping.postInsert(P
ersistenceCapableMapping.java:1039)
    at 
org.datanucleus.store.appengine.DatastoreRelationFieldManager.runPostInsert
MappingCallbacks(DatastoreRelationFieldManager.java:225)
    at 
org.datanucleus.store.appengine.DatastoreRelationFieldManager.access$300(Da
tastoreRelationFieldManager.java:49)
    at 
org.datanucleus.store.appengine.DatastoreRelationFieldManager$1.apply(Datas
toreRelationFieldManager.java:112)
    at 
org.datanucleus.store.appengine.DatastoreRelationFieldManager.storeRelation
s(DatastoreRelationFieldManager.java:80)
    at 
org.datanucleus.store.appengine.DatastoreFieldManager.storeRelations(Datast
oreFieldManager.java:795)
    at 
org.datanucleus.store.appengine.DatastorePersistenceHandler.insertPostProce
ss(DatastorePersistenceHandler.java:288)
    at 
org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObjects(D
atastorePersistenceHandler.java:241)
    at 
org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject(Da
tastorePersistenceHandler.java:225)
    at 
org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent(JDOStateMa
nagerImpl.java:3185)
    at 
org.datanucleus.state.JDOStateManagerImpl.makePersistent(JDOStateManagerImp
l.java:3161)
    at 
org.datanucleus.ObjectManagerImpl.persistObjectInternal(ObjectManagerImpl.j
ava:1298)
    at 
org.datanucleus.ObjectManagerImpl.persistObject(ObjectManagerImpl.java:1175
)
    at 
org.datanucleus.jdo.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceM
anager.java:669)
    at 
org.datanucleus.jdo.JDOPersistenceManager.makePersistent(JDOPersistenceMana
ger.java:694)
    at 
com.stevko.example.server.PersistTestServiceImpl.greetServer(PersistTestSer
viceImpl.java:57)

Original issue reported on code.google.com by andy.stevko on 25 Nov 2009 at 10:24

Attachments:

GoogleCodeExporter commented 8 years ago
While reviewing this post and comparing it with others, I figure it would be 
best to 
extract the specific schema from the project. Here it is in three parts.

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable="true")
public class A  {

    /**
     * automatically generated primary key
     */
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    @Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = 
"true")
    private String id;

    @Persistent
    private B1 b1;

<snip>
}
-------------------------------------
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable="true")
public class B1  {

    /**
     * automatically generated primary key
     */
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    @Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = 
"true")
    private String id;

    @Persistent(mappedBy="b1")
    private A a;
<snip>
}
-------------------------------------------------
switch (testcase) {
case NEW_A:
    { 
        // this test case works
pm.currentTransaction().begin();
A a = new A();
pm.makePersistent(a); 
pm.currentTransaction().commit();
// unload populated variables
        result = new TestCaseResult(a.getId(), a.getTimestamp());
    } 
    break;
case NEW_B1:
    { 
        // this test case works too
pm.currentTransaction().begin();
// lookup A
A a = pm.getObjectById(A.class, id);
B1 b1 = new B1( a );
//pm.makePersistent(a); 
pm.currentTransaction().commit();
// unload populated variables
        result = new TestCaseResult(b1.getId(), b1.getTimestamp());
    } 
    break;
case NEW_AB1:
{
    // this test case FAILS
pm.currentTransaction().begin();
A a = new A();
B1 b1 = new B1( a );
pm.makePersistent(a);   // BLOWS UP HERE!
pm.currentTransaction().commit();
// unload populated variables
    result = new TestCaseResult(a.getId(), a.getTimestamp());

}

Original comment by andy.stevko on 25 Nov 2009 at 10:50

GoogleCodeExporter commented 8 years ago
Your test is passing for me under SDK 1.2.8 (preview release is available now). 
 Can
you please verify on your end with this same SDK?

Thanks,
Max

Original comment by max.r...@gmail.com on 27 Nov 2009 at 11:28

GoogleCodeExporter commented 8 years ago
Hello Max,
I've downloaded, installed, and rebuilt test harness using the SDK 1.2.8 
prerelease 
as you suggested.
The New AB1 test case still breaks for me.
While I did see updates in dependent jar filenames, I did not see an change in 
the 
version number for the affected jar file datanucleus-core-1.1.5.jar

I've attached a basic stack trace and a DN FINEST log capture to this post.
While I've been able to fake a workaround solution by using a single element 
collection, I would rather have a clean data model when I let others use this 
app.
Please LMK if there is anything else I can do to assist in this situation.

--Andy

Original comment by andy.stevko on 1 Dec 2009 at 7:39

Attachments:

GoogleCodeExporter commented 8 years ago
The version of datanucleus isn't changing for 1.2.8 but there is a new
datanucleus-appengine jar.  I can see from the line numbers in your stacktrace 
that
you're using this new jar.

I still can't reproduce the exception.  In your testcase I see that you have a 
switch
statement.  Do you perhaps have a loop around this switch that is executing all 
3
tests?  I've just been ignoring the tests you posted that pass.  Could you 
please
boil your test down to the minimum code that generates the exception?

Thanks,
Max 

Original comment by m...@google.com on 1 Dec 2009 at 8:50

GoogleCodeExporter commented 8 years ago
I've boiled down the test harness to just the essential classes and single UI 
button 
to trigger it.

While going to this exercise in removing extra schema, I've figured out that 
the A - 
B2 relationship is what is messing up the A - B1 relationship. 
I.E. A contains one B1 reference and a TreeSet<B2> reference.
Without the B2 collection in A, the test case works. Add it and it fails.

Hope this helps.

Original comment by andy.stevko on 1 Dec 2009 at 11:18

Attachments:

GoogleCodeExporter commented 8 years ago
Is this issue not very similar to googleappengine Issue 2274
(java.lang.NullPointerException PersistenceCapableMapping.java:1039)?

The exception stack traces do diverge lower down, but the first several lines 
do match.

Original comment by IanMarsh...@gmail.com on 13 Jan 2010 at 12:21

GoogleCodeExporter commented 8 years ago
Well, i had the same problem. The problem was solved, if u can persist all the 
related (One-to-One BiDirectional) each in a different function. 

Original comment by ashwanth...@gmail.com on 17 Jun 2010 at 7:18

GoogleCodeExporter commented 8 years ago
Issue 228 has been merged into this issue.

Original comment by googleco...@yahoo.co.uk on 14 Aug 2011 at 8:12

GoogleCodeExporter commented 8 years ago
Due to the GAE/J plugin persistence process fragility. Currently has no 
specific handling for bidir relations where need to insert the parent in two 
steps i.e
1. "put" parent with no relation field -> parent key
2. "put" child with parent key
3. "put" parent with relation field set.

Original comment by googleco...@yahoo.co.uk on 14 Aug 2011 at 8:14

GoogleCodeExporter commented 8 years ago
testcase is present in SVN trunk under tests_bugs

Original comment by googleco...@yahoo.co.uk on 21 Sep 2011 at 11:02

GoogleCodeExporter commented 8 years ago
SVN trunk passes on that test now. Test now moved to 
"tests/com/google/appengine/datanucleus/jdo/Issue165Test"

Original comment by googleco...@yahoo.co.uk on 21 Sep 2011 at 12:36