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);
}
これらの関連する質問を見つけましたが、まだ修正できません。
- AppEngine データストア: 「ID のオブジェクト ... は別のオブジェクト マネージャによって管理されています」
- Google App Engine - ID "" のオブジェクトは別の JPA によって管理されています
- Datanucleus: @Transactional から非トランザクションへの移行
- 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 になります。それは私には普通のことのように思えるので、それを使ってデバッグする方法がはっきりしません。