Google App Engine 用の Java アプリケーションを作成しています。双方向の所有されていない 1 対 1 の関係としてモデル化する必要がある 2 つのエンティティがあります。
最初のオブジェクト「ContainableObject」
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class ContainableObject {
/*=== Data Model ===*/
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long key;
@Persistent
@Unowned
private Container container;
そして2番目の「コンテナ」
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class Container {
/*=== Data Model ===*/
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long key;
@Persistent
@Unowned
private ContainableObject containable;
Container は空にすることも、1 つの ContainableObject を含めることもできます。ContainableObject は、Container 内にある場合も、Container オブジェクト間を移動する場合も、Container を持たない場合もあります。Container --> ContainableObject および ContainableObject --> Container から取得できる必要があります
私は datanucleus プラグインの v2 を使用しています。Maven を介して統合テストを実行すると、このモデルはうまく機能しますが、REST API を介してアクセスしようとすると、スタック オーバーフローが発生します。
java.lang.StackOverflowError
at java.util.concurrent.FutureTask.<init>(FutureTask.java:45)
at java.util.concurrent.AbstractExecutorService.newTaskFor(AbstractExecutorService.java:72)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:91)
at com.google.appengine.tools.development.ApiProxyLocalImpl$PrivilegedApiAction.run(ApiProxyLocalImpl.java:277)
at com.google.appengine.tools.development.ApiProxyLocalImpl$PrivilegedApiAction.run(ApiProxyLocalImpl.java:262)
at java.security.AccessController.doPrivileged(Native Method)
at com.google.appengine.tools.development.ApiProxyLocalImpl.doAsyncCall(ApiProxyLocalImpl.java:216)
at com.google.appengine.tools.development.ApiProxyLocalImpl.makeAsyncCall(ApiProxyLocalImpl.java:179)
at com.google.apphosting.api.ApiProxy.makeAsyncCall(ApiProxy.java:184)
at com.google.appengine.api.datastore.DatastoreApiHelper.makeAsyncCall(DatastoreApiHelper.java:59)
at com.google.appengine.api.datastore.AsyncDatastoreServiceImpl.doBatchGetBySize(AsyncDatastoreServiceImpl.java:351)
at com.google.appengine.api.datastore.AsyncDatastoreServiceImpl.get(AsyncDatastoreServiceImpl.java:296)
at com.google.appengine.api.datastore.DatastoreServiceImpl$1.runInternal(DatastoreServiceImpl.java:78)
at com.google.appengine.api.datastore.DatastoreServiceImpl$1.runInternal(DatastoreServiceImpl.java:75)
at com.google.appengine.api.datastore.TransactionRunner.runInTransaction(TransactionRunner.java:31)
at com.google.appengine.api.datastore.DatastoreServiceImpl.get(DatastoreServiceImpl.java:75)
at com.google.appengine.api.datastore.DatastoreServiceImpl.get(DatastoreServiceImpl.java:62)
at com.google.appengine.datanucleus.WrappedDatastoreService.get(WrappedDatastoreService.java:60)
at com.google.appengine.datanucleus.FetchFieldManager.lookupOneToOneChild(FetchFieldManager.java:426)
at com.google.appengine.datanucleus.FetchFieldManager.fetchRelationField(FetchFieldManager.java:341)
at com.google.appengine.datanucleus.FetchFieldManager.fetchObjectField(FetchFieldManager.java:248)
at org.datanucleus.state.AbstractStateManager.replacingObjectField(AbstractStateManager.java:2228)
at com.whatever.ContainableObject.jdoReplaceField(ContainableObject.java)
at com.whatever.ContainableObject.jdoReplaceFields(ContainableObject.java)
at org.datanucleus.state.JDOStateManager.replaceNonLoadedFields(JDOStateManager.java:1988)
at com.google.appengine.datanucleus.EntityUtils$1.fetchNonLoadedFields(EntityUtils.java:976)
at org.datanucleus.ObjectManagerImpl.findObject(ObjectManagerImpl.java:2857)
at com.google.appengine.datanucleus.EntityUtils.entityToPojo(EntityUtils.java:1013)
at com.google.appengine.datanucleus.FetchFieldManager.lookupOneToOneChild(FetchFieldManager.java:427)
at com.google.appengine.datanucleus.FetchFieldManager.fetchRelationField(FetchFieldManager.java:341)
at com.google.appengine.datanucleus.FetchFieldManager.fetchObjectField(FetchFieldManager.java:248)
at org.datanucleus.state.AbstractStateManager.replacingObjectField(AbstractStateManager.java:2228)
at com.whatever.Container.jdoReplaceField(Container.java)
at com.whatever.Container.jdoReplaceFields(Container.java)
at org.datanucleus.state.JDOStateManager.replaceNonLoadedFields(JDOStateManager.java:1988)
at com.google.appengine.datanucleus.EntityUtils$1.fetchNonLoadedFields(EntityUtils.java:976)
at org.datanucleus.ObjectManagerImpl.findObject(ObjectManagerImpl.java:2857)
at com.google.appengine.datanucleus.EntityUtils.entityToPojo(EntityUtils.java:1013)
at com.google.appengine.datanucleus.FetchFieldManager.lookupOneToOneChild(FetchFieldManager.java:427)
at com.google.appengine.datanucleus.FetchFieldManager.fetchRelationField(FetchFieldManager.java:341)
at com.google.appengine.datanucleus.FetchFieldManager.fetchObjectField(FetchFieldManager.java:248)
at org.datanucleus.state.AbstractStateManager.replacingObjectField(AbstractStateManager.java:2228)
at com.whatever.ContainableObject.jdoReplaceField(ContainableObject.java)
at com.whatever.ContainableObject.jdoReplaceFields(ContainableObject.java)
at org.datanucleus.state.JDOStateManager.replaceNonLoadedFields(JDOStateManager.java:1988)
at com.google.appengine.datanucleus.EntityUtils$1.fetchNonLoadedFields(EntityUtils.java:976)
at org.datanucleus.ObjectManagerImpl.findObject(ObjectManagerImpl.java:2857)
at com.google.appengine.datanucleus.EntityUtils.entityToPojo(EntityUtils.java:1013)
at com.google.appengine.datanucleus.FetchFieldManager.lookupOneToOneChild(FetchFieldManager.java:427)
at com.google.appengine.datanucleus.FetchFieldManager.fetchRelationField(FetchFieldManager.java:341)
at com.google.appengine.datanucleus.FetchFieldManager.fetchObjectField(FetchFieldManager.java:248)
at org.datanucleus.state.AbstractStateManager.replacingObjectField(AbstractStateManager.java:2228)
at com.whatever.Container.jdoReplaceField(Container.java)
at com.whatever.Container.jdoReplaceFields(Container.java)
at org.datanucleus.state.JDOStateManager.replaceNonLoadedFields(JDOStateManager.java:1988)
at com.google.appengine.datanucleus.EntityUtils$1.fetchNonLoadedFields(EntityUtils.java:976)
これはこれをモデル化する間違った方法ですか、それとも AppEngine のバグを見つけましたか?