外部で生成されたキー (物理カードから読み取った) を持つ JDO カード エンティティがあります。これは、Card エンティティと同時に作成される User エンティティにリンクします。カードを読み取ってメソッドを呼び出すと、以前に作成したカードとユーザーを返すか、新しいカードを作成するよう AppEngine に要求します。ただし、このメソッドを立て続けに 2 回呼び出すと、最終的に Card エンティティが上書きされ、2 つのユーザー ID が作成されます。
これが私のコードです(ゲッターとセッターを削除しました):
CardEntity.java
@PersistenceCapable public class CardEntity {
@PrimaryKey
private Key Id;
@Persistent
@Unowned
private UserEntity user;
}
UserEntity.java
@PersistenceCapable
public class CustomerEntity {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;
@Persistent
private String name;
}
Controller.java のメソッド
public UserEntity getOrCreateUser(String id) {
CardEntity cardEntity;
UserEntity userEntity;
Query query;
PersistenceManager mgr = getPersistenceManager();
Transaction tx = mgr.currentTransaction();
boolean complete = false;
while (!complete) {
try {
tx.begin();
query = mgr.newQuery(CardEntity.class);
query.setUnique(true);
// rootkey is a key for a CardEntity that I am using as the parent for
// all CardEntities, so they are in the same enitity group, as a hack
// to try to solve this problem.
Key key = KeyFactory.createKey(rootKey, "CardEntity", id);
query.setFilter("id == :id");
cardEntity = (CardEntity) query.execute(key);
if (CardEntity == null) {
cardEntity = new CardEntity();
cardEntity.setId(key);
userEntity = new UserEntity();
mgr.makePersistent(userEntity);
nfcCardEntity.setUser(UserEntity);
mgr.makePersistent(cardEntity);
CardEntity rootCardEntity =
(CardEntity) mgr.getObjectById(CardEntity.class, rootKey);
rootCardEntity.setUser(userEntity);
// this is another hack to ensure that something changes in this transaction
// so that if there's a conflict, it will be rolled back
mgr.makePersistent(rootCardEntity);
} else {
userEntity = cardEntity.getUser();
}
tx.commit();
} finally {
if (tx.isActive()) {
tx.rollback();
} else {
complete = true;
}
}
}
mgr.close();
return userEntity;
}
私は多くのことを試しましたが、多くの場合、複数の UserEntities が作成されてしまいます。上記のコードには、すべての CardEntities が 1 つのエンティティ グループ (rootkey で定義) に含まれており、ルート エンティティにも変更を加えています。これは役に立たないようです。
ヒント、指針はありますか?