所有される 1 対 1 関係および親子関係の問題
-
16-09-2019 - |
質問
次のような宣言を持つ User、Company、Address の 3 つのエンティティがあります。
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class User implements Serializable {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;
@Persistent(mappedBy="creator")
@Order(extensions = @Extension(vendorName="datanucleus", key="list-ordering", value="title asc"))
private Collection<Company> companies;
@Persistent
private Address address;
. . .
}
public class Company implements Serializable {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;
@Persistent
@Extension(vendorName="datanucleus", key="gae.parent-pk", value="true")
private Key creatorKey;
@Persistent
private User creator;
@Persistent
private Address address;
. . .
}
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Address implements Serializable{
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;
. . .
}
ユーザーを作成した後、アドレスやその他の情報を次のように設定して、ユーザーが所有する 2 つの会社を永続化します。
company.setCreatorKey(currentUser.getKey());
pm.makePersistent(company);
問題は、会社を取得し、そのオブジェクトから作成者を参照するときに発生します。どうやら JDO は 2 つの会社のアドレスが会社ではなくユーザーに属していると考えており、次のエラーがログに記録されます。
address is mapped as a 1 to 1 relationship but there is more than one enity of kind Address that is a child of User(email@email.com)
ユーザーのキーは
User(email@email.com)
会社の鍵は
User(email@email.com)\Company(1)
2 つのアドレスのキーは次のとおりです。
User(email@email.com)\Company(1)\Address(1)
User(email@email.com)\Company(1)\Address(2)
私は階層データベースにはあまり慣れていないので、なぜ 2 つのアドレスがユーザーの子孫や会社の子ではなくユーザーの子として永続化/解釈されるのか疑問に思っていました。このような状況における正しい階層は何でしょうか?ありがとう。
解決
使用しているアプリ エンジン SDK のバージョンは何ですか?月曜日に、彼らは JDO の問題に対する多くの修正を含む新しいバージョンをリリースしました。(リリースノート)4つまたは5つの修正はオブジェクト間の関係に関係しているため、この問題が解決されたか、新しい方法で破られた可能性があります:) OTOH、あなたの問題はこのオープンに関連している可能性があります チケット.
私は階層データベースにはあまり慣れていないので、なぜ 2 つのアドレスがユーザーの子孫や会社の子ではなくユーザーの子として永続化/解釈されるのか疑問に思っていました。
表示されているキー階層はエンティティ グループに基づいています。データストアに関する限り、ユーザーとは異なるエンティティ グループに会社を含めることができ、その結果、キー構造は次のようになります。
User(email@email.com)
Company(1)\Address(1)
Company(1)\Address(2)
データストアは、1 対 1 マッピングまたは 1 対多マッピングについて必ずしも認識しているわけではありません。他のエンティティのキーを好きなだけ参照できるようになります。ただし、JDO レイヤーは、所有関係にあるすべてのエンティティを同じエンティティ グループに自動的に配置します。これはおそらく、変更がトランザクション形式で発生することを強制できるためです。
以上のことを踏まえると、あなたの構造は私には問題ないようです。JDO レイヤーは、Company の直接の子であるエンティティ グループを特に探しているのではなく、種類アドレスのエンティティ グループの子孫をチェックしているだけのようです。