Note that there are some explanatory texts on larger screens.

plurals
  1. POUnable to get ID of newly-created JDO persistent entity using GAE/J DataNucleus plug-in version 2.1.2
    text
    copied!<p><strong>My problem</strong></p> <p>I am porting my application from version 1.x to 2.0 of the DataNucleus plug-in for GAE/J using the new 1.7.5 GAE/J SDK. This changes my JDO version from 2.3 to 3.0.1. My persistent entity class has a primary key of type encoded string, along with read-only access to the object’s numeric ID. Each instance is the sole member of its entity group (children and parent are linked by numeric ID only).</p> <p>Previously, I have been able to create and persist a new <code>MyEntity</code> instance and then immediately access its numeric ID to store in the parent <code>MyEntity</code> instance’s list of child IDs.</p> <p>Now I find that the new instance’s numeric ID is not available immediately after persistence – even though it is generated and stored and is available later.</p> <p><strong>My question</strong></p> <p>Is there anything I can do to restore access to the numeric ID immediately following object creation and persistence?</p> <p><strong>"jdoconfig.xml" configuration extract</strong></p> <pre><code>&lt;persistence-manager-factory name="big-table"&gt; &lt;property name="javax.jdo.PersistenceManagerFactoryClass" value="org.datanucleus.api.jdo.JDOPersistenceManagerFactory" /&gt; &lt;property name="datanucleus.DetachAllOnCommit" value="true"/&gt; &lt;property name="javax.jdo.option.NontransactionalRead" value="true"/&gt; &lt;property name="javax.jdo.option.NontransactionalWrite" value="true"/&gt; &lt;property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true" /&gt; [...] &lt;/persistence-manager-factory&gt; </code></pre> <p><strong>Persistent entity class code extract</strong></p> <pre><code>@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true") public class MyEntity implements Serializable { private static final long serialVersionUID = 1L; // No setter for this read-only data member @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true") private String sEncodedKey; // No setter for this read-only data member @Persistent @Extension(vendorName="datanucleus", key="gae.pk-id", value="true") private Long loID; @Persistent private Long loParentID; // // Other persistent data members // public Long getID() { return loID; } // // Other getters and setters // } </code></pre> <p><strong>Persistence code including 3 logging points</strong></p> <pre><code>/** * Create a new entity. * @param loParentID * The ID of the entity, * a new child of which is to be created. * @param sChildName * The name of the new child to be created. * @return * The created entity child, * or &lt;code&gt;null&lt;/code&gt; if the operation was carried out unsuccessfully. */ public static MyEntity createEntityChild(Long loParentID, String sChildName) { MyEntity meResult = null; MyEntity mePersistedChild = null; PersistenceManagerFactory pmf = DataExchange.getPersistenceManagerFactory(); // My own method PersistenceManager pm = pmf.getPersistenceManager(); Transaction tx = pm.currentTransaction(); try { tx.begin(); MyEntity meChild = new MyEntity(); meChild.setParentID(loParentID); meChild.setName(sChildName); meChild.setActive(true); mePersistedChild = pm.makePersistent(meChild); // "Touch" data member not in the default fetch group ArrayList&lt;Long&gt; liChildIDs = mePersistedChild.getChildIDs(); if (liChildIDs != null) liChildIDs.size(); if (mePersistedChild != null) g_logger.log(Level.FINE, String.format( "Pre-commit: mePersistedChild.getID() = %d," + " mePersistedChild.getEncodedKey() = \"%s\".", mePersistedChild.getID(), mePersistedChild.getEncodedKey())); tx.commit(); if (mePersistedChild != null) g_logger.log(Level.FINE, String.format( "Post-commit: mePersistedChild.getID() = %d," + " mePersistedChild.getEncodedKey() = \"%s\".", mePersistedChild.getID(), mePersistedChild.getEncodedKey())); } finally { try { if (tx.isActive()) // Because of an exception, say tx.rollback(); } finally { pm.close(); } } if (mePersistedChild != null) g_logger.log(Level.FINE, String.format( "Post-pm-close: mePersistedChild.getID() = %d," + " mePersistedChild.getEncodedKey() = \"%s\".", mePersistedChild.getID(), mePersistedChild.getEncodedKey())); [...] return meResult; } </code></pre> <p><strong>Dev server logging output</strong></p> <pre><code>24-Feb-2013 13:28:02 [...].MyEntityBusiness createMyEntityChild FINE: Pre-commit: mePersistedChild.getID() = null, mePersistedChild.getEncodedKey() = "agttYXJrZXQtdHJlZXISCxIMSXRlbUNhdGVnb3J5GAUM". 24-Feb-2013 13:28:03 [...].MyEntityBusiness createMyEntityChild FINE: Post-commit: mePersistedChild.getID() = null, mePersistedChild.getEncodedKey() = "agttYXJrZXQtdHJlZXISCxIMSXRlbUNhdGVnb3J5GAUM". 24-Feb-2013 13:28:03 [...].MyEntityBusiness createMyEntityChild FINE: Post-pm-close: mePersistedChild.getID() = null, mePersistedChild.getEncodedKey() = "agttYXJrZXQtdHJlZXISCxIMSXRlbUNhdGVnb3J5GAUM". 24-Feb-2013 13:28:07 com.google.appengine.api.datastore.dev.LocalDatastoreService$PersistDatastore persist INFO: Time to persist datastore: 141 ms </code></pre> <p><strong>JDO enhancement version verification</strong></p> <p>The build process succeeded with output fragment:</p> <pre><code>datanucleusenhancer: 09:33:00,531 (main) INFO [DataNucleus.Enhancer] - DataNucleus Enhancer for API "JDO" 09:33:01,125 (main) INFO [DataNucleus.Enhancer] - DataNucleus Enhancer (version 3.1.1) : Enhancement of classes DataNucleus Enhancer (version 3.1.1) : Enhancement of classes 09:33:03,281 (main) INFO [DataNucleus.Enhancer] - Writing class file "[Path]\MyEntity.class" with enhanced definition [... (N entries in all)] 09:33:04,046 (main) INFO [DataNucleus.Enhancer] - DataNucleus Enhancer completed with success for [N] classes. Timings : input=1922 ms, enhance=984 ms, total=2906 ms. Consult the log for full details DataNucleus Enhancer completed with success for [N] classes. Timings : input=1922 ms, enhance=984 ms, total=2906 ms. Consult the log for full details </code></pre> <p><strong>Software environment</strong></p> <ul> <li>Web server: Google App Engine for Java version 1.7.5</li> <li>Web framework: Apache Wicket 6.5.0</li> <li>Java version: 1.6.0_39; Java HotSpot(TM) Client VM 20.14-b01</li> <li>GAE/J DataNucleus plug-in version: 2.1.2</li> <li>DataNucleus Access Platform version: 3.1.3</li> <li>JDO version: 3.0.1</li> <li>Operating system: Microsoft Windows XP version 5.1 running on x86</li> <li>IDE: NetBeans 7.2 (build 201207171143)</li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload