我有四个实体一起映射,“关联”,“帐户”,“交易”和“交易事件”。 Association的id是一个简单的整数id。账户和交易每个都有嵌入的ID,包括到关联和数字的映射。
TransactionEvent应具有由一个帐户和一个关联组成的嵌入式ID。现在,每个都映射到一个Association,我希望它是一个TransactionEvent的同一个Association。
JPA Annotations用于Hibernate映射,但我无法使其工作。我已经尝试为Association键强制使用相同的列名,但是Hibernate抱怨重复的列。
这有可能解决,还是我不直接思考?
以下是带注释的类,但我从javax.persistence命名空间中删除了getter / setter和non-id列,注释:
@Entity
public class Association implements Serializable {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private long id;
}
@Embeddable
public class AccountPK implements Serializable {
@ManyToOne(optional=false)
private Association association;
@Column(nullable=false)
private int number;
}
@Embeddable
public class TransactionPK implements Serializable {
@ManyToOne
private Association association;
@GeneratedValue(strategy=GenerationType.AUTO)
private long number;
}
@Embeddable
public class AccountEventPK implements Serializable {
@ManyToOne(optional=false)
@JoinColumns({
@JoinColumn(name="association_id", referencedColumnName="association_id"),
@JoinColumn(name="account_number", referencedColumnName="number")
})
private Account account;
@ManyToOne(optional=false)
@JoinColumns({
@JoinColumn(name="association_id", referencedColumnName="association_id"),
@JoinColumn(name="transaction_number", referencedColumnName="number")
})
private Transaction transaction;
}
实际帐户,交易和AccountEvent实体位于表单
@Entity
public class Account implements Serializable {
@EmbeddedId
private AccountPK id;
}
答案 0 :(得分:2)
我没有太多将关联直接放在嵌入式id组件中的经验,因为JPA不支持这种关联,但是Hibernate是特定的。
作为替代方案,我的建议是使用JPA wikibook的Composite Primary Keys部分中描述的方法:
(...)JPA 1.0要求所有
@Id
映射是Basic
映射,所以如果 您的Id来自外键 通过OneToOne
或。列ManyToOne
映射,您还必须 定义一个基本的@Id映射 外键栏目。的原因 这部分是Id必须是a 身份和缓存的简单对象 用途,并用于IdClass
或EntityManager
find()
API。因为您现在有两个映射 你必须使用相同的外键列 定义将写入哪一个 数据库(必须是基础 一),所以
OneToOne
或ManyToOne
必须定义外键 只读。这是通过完成的 设置JoinColumn
属性insertable
和updatable
为假, 或者使用@PrimaryKeyJoinColumn
代替@JoinColumn
。强>具有两个映射的副作用 对于同一列,就是你现在 必须保持两者同步。这是 通常通过设置完成
OneToOne
属性的方法 还将Basic属性值设置为 目标对象的id。这个可以 如果目标变得非常复杂 对象的主键是aGeneratedValue
,在这种情况下你 必须确保目标对象的 id已在相关之前分配 这两个对象。(...)
示例
ManyToOne
ID注释... @Entity @IdClass(PhonePK.class) public class Phone { @Id @Column(name="OWNER_ID") private long ownerId; @Id private String type; @ManyToOne @PrimaryKeyJoinColumn(name="OWNER_ID", referencedColumnName="EMP_ID") private Employee owner; ... public void setOwner(Employee owner) { this.owner = owner; this.ownerId = owner.getId(); } ... }
这看起来像是你正在寻找的东西(也许不那么复杂)。我试着逐步实现这个解决方案。