我有三个实体User,Company和Address,声明如下:
@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;
. . .
}
创建用户后,我会在设置地址和其他信息之后保留用户拥有的两家公司:
company.setCreatorKey(currentUser.getKey());
pm.makePersistent(company);
当我检索公司并从该对象引用创建者时出现问题。显然,JDO认为两家公司的地址属于用户,而不是公司,并记录以下错误:
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)
并且两个地址的密钥是
User(email@email.com)\Company(1)\Address(1)
User(email@email.com)\Company(1)\Address(2)
我对层次数据库很陌生,所以我想知道为什么这两个地址被持久化/解释为用户的子节点,而不是公司用户和子节点的后代。对于这种情况,正确的层次结构是什么?感谢。
答案 0 :(得分:0)
您使用的是什么版本的应用引擎sdk?周一,他们发布了一个新版本,其中包含许多针对JDO问题的修复程序。 (release notes)四个或五个修复程序与对象之间的关系有关,所以这个问题可能已经解决,或以新方式破坏:) OTOH,您的问题可能与此公开ticket有关。
我对分层数据库很陌生,所以我想知道为什么这两个地址被持久化/解释为用户的子代,而不是用户和子公司的后代。
您看到的密钥层次结构基于实体组。就数据存储而言,您可以将您的公司放在与用户不同的实体组中,从而产生如下关键结构:
User(email@email.com)
Company(1)\Address(1)
Company(1)\Address(2)
数据存储区不一定了解一对一映射或一对多映射。它只是让你引用你喜欢的其他实体的键。但是,JDO层会自动将所有实体置于同一实体组中,这可能是因为它可以强制执行以事务方式发生的更改。
说了这么多,你的结构看起来还不错。看起来JDO层只是检查具有类型地址的任何实体组后代,而不是专门查找公司的直接子项。