1

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 データストア: 「ID のオブジェクト ... は別のオブジェクト マネージャによって管理されています」
  2. Google App Engine - ID "" のオブジェクトは別の JPA によって管理されています
  3. Datanucleus: @Transactional から非トランザクションへの移行
  4. http://www.atentia.net/2010/03/object-with-id-is-managed-by-a-different-object-manager/

PM を閉じる WRT (1 & 2 のように)、Spring org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter を使用しているため、PM を明示的に閉じることができません。ログから、ページ要求ごとに開いたり閉じたりしているように見えます。

エンティティを取り外し可能にする WRT (3 & 4 のように)。まず、私は JPA を使用していますが、JDO 関連の注釈を使用するのは間違っているようです。第二に、私が試したときにうまくいきませんでした。

追加のクレジットとして、JDOHelper.getPersistenceManager(obj) を使用してどのようにデバッグしますか? ユーザーがページ要求間で切り離されたため、この場合は null になります。それは私には普通のことのように思えるので、それを使ってデバッグする方法がはっきりしません。

4

1 に答える 1

1
  1. あなたはPMではなく、EMを持っています。あなたがそこで何を指しているのか分かりません。
  2. Detachable : 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 で使用されます)。

于 2013-02-08T10:08:54.973 に答える