【问题标题】:Google App Engine: Object with id “” is managed by a different Object Manager - RevisitedGoogle App Engine:ID 为“”的对象由不同的对象管理器管理 - 重新访问
【发布时间】:2013-02-07 21:52:57
【问题描述】:

我在使用 GAE、JPA 和 Spring 时遇到以下错误

ID为“”的对象由不同的对象管理器管理

当我第一次创建帐户时,我将 User 对象放入会话中。然后,当我在初始会话期间更新用户配置文件时,我合并了分离的用户。一切都很好。

然后我注销并稍后创建一个新会话。这一次,我加载 User 对象并将其放入会话中。仍然可以,但问题是当我更新用户配置文件时,合并失败并出现上述错误。

public boolean loadProfile(String openId, String email) {
    User user = null;
    try {
        user = userDao.findByOpenId(openId);
    } catch (NoResultException e) {
    }
    if (user != null) {
        logger.error(JDOHelper.getPersistenceManager(user));
        getSessionBean().setUser(user);
        return true;
    } else {
        user = createNewAccount(openId, email);
        getSessionBean().setUser(user);
        return false;
    }

}

@Transactional(propagation=Propagation.REQUIRES_NEW)
private User createNewAccount(String openId, String email) {
    User user = new User();
    user.setDisplayName(Long.toString(System.currentTimeMillis()));
    OpenIdentifier oid = new OpenIdentifier();
    oid.setOpenId(openId);
    oid.setEmail(email);
    oid.setUser(user);
    Set<OpenIdentifier> openIds = new HashSet<OpenIdentifier>();
    openIds.add(oid);
    user.setOpenIds(openIds);
    user = userDao.merge(user);
    return user;
}

@Transactional(propagation=Propagation.REQUIRED)
public void createOrUpdate(ActionEvent e) {
    logger.error(JDOHelper.getPersistenceManager(userFacade.getDelegate()));
    User user = userDao.merge(userFacade.getDelegate());
    sessionBean.setUser(user);
}

我找到了这些相关的问题,但我仍然无法解决。

  1. AppEngine datastore: "Object with id ... is managed by a different Object Manager"
  2. Google App Engine - Object with id "" is managed by a different - JPA
  3. Datanucleus: moving from @Transactional to non-transactional
  4. http://www.atentia.net/2010/03/object-with-id-is-managed-by-a-different-object-manager/

WRT 关闭 PM(根据 1 和 2),我无法显式关闭 PM,因为我使用的是 Spring org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter。从日志来看,它似乎是在每个页面请求时打开和关闭的。

WRT 使实体可拆卸(根据 3 和 4),首先,我使用的是 JPA,使用 JDO 相关的注释似乎是错误的。其次,我试了也没用。

对于额外的功劳,您如何使用 JDOHelper.getPersistenceManager(obj) 进行调试?在这种情况下,我得到空值,因为用户在页面请求之间分离。这对我来说似乎很正常,所以我不清楚如何使用它进行调试。

【问题讨论】:

    标签: spring google-app-engine jpa datanucleus


    【解决方案1】:
    1. 您没有 PM,只有 EM。不知道你在说什么。
    2. 可分离:使用 JPA,所有类都(增强为)可分离
    3. 您在那里使用了一些古老的 GAE JPA 插件(v1.x?),并且使用不受支持的旧版本 DataNucleus。使用 GAE JPA v2.x。 “ObjectManager”在 DataNucleus 中已经存在多年了。
    4. 您(或您正在使用的软件)必须关闭 EM,否则资源会到处泄漏。

    NucleusJPAHelper.getEntityManager(obj);是如何获得管理对象的 EntityManager(在 DataNucleus v3.x 中,由 GAE JPA v2.x 使用)

    【讨论】:

    • 是的,我确信这是由于我在最初设置它时复制/粘贴的依赖项的大杂烩。我什至发现了一些 JDO 注释,其中大部分是 JPA 代码。我也意识到一直使用默认为 JDO 的 DN 增强器。不知何故,它大部分时间都在工作。
    • 无论如何,我升级到 JPA v2.x/DataNucleus v3.x 并删除了 JDO 引用。不知道这是否修复了它,因为我得到“javax.persistence.PersistenceException:mypackage.OpenIdentifier 没有元数据。也许你需要在这个类上运行增强器?”。日志显示增强器正在运行,并且类在目标目录中就地更新。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-12
    • 2011-06-05
    相关资源
    最近更新 更多