2009-09-10 52 views
12

我正在使用Google AppEngine和Java。当我使用一些数据存储功能,我收到一条错误消息:AppEngine数据存储区:“带ID的对象...由不同的对象管理器管理”

Object with id "[email protected]" is managed by a different Object Manager 

我不知道这意味着什么或如何解决它或在哪里寻找这个错误文档。谁能帮我?我正在使用的代码是:

@PersistenceCapable(identityType = IdentityType.APPLICATION) 
public class School { 
@PrimaryKey 
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) 
private String shortname; 

@Persistent 
private String fullname; 

@Persistent 
@Order(extensions = @Extension(vendorName="datanucleus", key="list-ordering", value="code asc")) 
private List<Teacher> Teachers; 

... 

public Teacher FindOrCreateTeacher(String code) 
{ 
    // Can we find the teacher without any database code? 
    Teacher newTeacher = FindTeacher(code); 
    if (newTeacher != null) 
     return newTeacher; 

    // Create the teacher: 
    PersistenceManager pm = PMF.get().getPersistenceManager(); 
    Transaction tx = pm.currentTransaction(); 
    try { 
     tx.begin(); 
     for (Teacher teacher : Teachers) { 
      if (teacher.getCode() == code) { 
       tx.rollback(); 
       return teacher; 
      } 
     } 
     newTeacher = new Teacher(code); 
     Teachers.add(newTeacher); 
     pm.makePersistent(newTeacher); 
     pm.makePersistent(Teachers); 
     tx.commit(); 
    } finally { 
     tx.commit(); 
    } 
    return newTeacher; 
} 

我相信“private List<Teacher> Teachers;”是指“拥有一对多”的关系。

回答

9

持久对象只能由一个PersistenceManager“管理”。在DataNucleus中,这由“ObjectManager”在内部支持。该消息表示您正尝试将由一个PM管理的对象与另一个PM关联。您可以轻松地调试打印出PM每个(持久)对象

JDOHelper.getPersistenceManager(obj); 

既然你不定义该消息从何而来,没有太多可说。 DataNucleus日志条目会告诉你更多的方式。

关闭PM总是做的(除非你想资源泄漏)

+0

有趣的解释。 +1 – VonC 2009-10-07 17:36:42

+0

您能否进一步向我解释PM实例的适合寿命?假设我正在编写一个Web应用程序。我应该在每个页面请求中打开并关闭它吗?或者在流程的整个过程中保持一个实例打开? (如果我提交了一个事务但不关闭PM,这是否意味着发生的最坏情况是内存泄漏?我的意思是,我的数据是安全的?) – 2009-10-09 06:51:17

+1

这个过程需要多长时间?一个典型的网络系统将使用每个请求的PM。创建PM并不昂贵(创建PMF *是昂贵的)。如果使用txns,那么只要您还没有对该PM执行非事务性更新,就可以安全地让PM打开。 – DataNucleus 2009-10-09 07:10:35

3

this ticket所示,您不应该关闭下午(PersistenceManager)吗?

} finally { 
    tx.commit(); 
    pm.close(); 
} 
+0

我原本以为这解决了我的问题,但事实并非如此。首先,我仍然不知道发生了什么,为什么关闭持久性管理器是必要的,或者何时应该完成。其次,AppEngine文档鼓励在PersistenceManager中使用单例模式,pm.close()意味着您在剩下的过程中不能对Google数据存储做更多的事情。 – 2009-09-19 16:44:19

+0

带有PMF的单身模式,而不是PM。 pm.close()* not * pmf.close() – DataNucleus 2009-10-07 16:45:52

2

DataNucleus将必不可少的东西,

谢谢你的pm.close();提示。 我是在查询一个EM

em = EMF.get().createEntityManager();

并且与另一个的承诺,而关闭的第一个。