我正在为Google App Engine编写一个Java应用程序。我有两个实体,我需要将它们建模为双向的无主一对一关系:
第一个对象'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;第二个“Container”
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class Container {
/*=== Data Model ===*/
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long key;
@Persistent
@Unowned
private ContainableObject containable;容器可以是空的,也可以包含一个ContainableObject。ContainableObject可以在容器中,可以在容器对象之间移动,也可以没有容器。我需要能够从容器--> ContainableObject和ContainableObject -->容器中获取
我使用的是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错误?
发布于 2012-09-19 15:37:42
你说它是一个双向关系,但是在这个关系的一端没有一个"mappedBy"。因此,目前是2个1-1 uni关系。
如果它打算是2 1-1单一关系,那么您需要在GAE JDO/JPA插件项目上向Google报告问题,并提供测试用例来重现它。
发布于 2012-09-18 09:49:27
我猜问题在于您的类ContainableObject有一个对容器类型对象的引用,而在类容器中有一个对ContainableObject类型对象的引用,因此它可能会创建一个循环引用,这可能会导致疯狂的JDO。
试着去掉引用,看看这是否有效。
https://stackoverflow.com/questions/12469300
复制相似问题