私の問題
新しい 1.7.5 GAE/J SDK を使用して、バージョン 1.x から 2.0 の GAE/J 用 DataNucleus プラグインにアプリケーションを移植しています。これにより、JDO のバージョンが 2.3 から 3.0.1 に変更されます。私の永続エンティティ クラスには、オブジェクトの数値 ID への読み取り専用アクセスと共に、エンコードされた文字列型の主キーがあります。各インスタンスは、そのエンティティ グループの唯一のメンバーです (子と親は数値 ID のみでリンクされます)。
以前は、新しいMyEntity
インスタンスを作成して保持し、すぐにその数値 ID にアクセスして、親MyEntity
インスタンスの子 ID のリストに格納することができました。
新しいインスタンスの数値 ID は、生成されて保存され、後で使用できるようになったとしても、永続化の直後には使用できないことがわかりました。
私の質問
オブジェクトの作成と永続化の直後に数値 ID へのアクセスを復元するためにできることはありますか?
「jdoconfig.xml」構成抽出
<persistence-manager-factory name="big-table">
<property
name="javax.jdo.PersistenceManagerFactoryClass"
value="org.datanucleus.api.jdo.JDOPersistenceManagerFactory"
/>
<property name="datanucleus.DetachAllOnCommit" value="true"/>
<property name="javax.jdo.option.NontransactionalRead" value="true"/>
<property name="javax.jdo.option.NontransactionalWrite" value="true"/>
<property
name="datanucleus.appengine.autoCreateDatastoreTxns"
value="true"
/>
[...]
</persistence-manager-factory>
永続エンティティ クラス コードの抜粋
@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
//
}
3 つのロギング ポイントを含む持続性コード
/**
* 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 <code>null</code> 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<Long> 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;
}
開発サーバーのログ出力
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
JDO 拡張バージョンの検証
ビルド プロセスは次の出力フラグメントで成功しました。
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
ソフトウェア環境
- Web サーバー: Google App Engine for Java バージョン 1.7.5
- Web フレームワーク: Apache Wicket 6.5.0
- Java バージョン: 1.6.0_39; Java HotSpot(TM) クライアント VM 20.14-b01
- GAE/J DataNucleus プラグインのバージョン: 2.1.2
- DataNucleus アクセス プラットフォームのバージョン: 3.1.3
- JDO バージョン: 3.0.1
- オペレーティング システム: x86 で動作する Microsoft Windows XP バージョン 5.1
- IDE: NetBeans 7.2 (ビルド 201207171143)