gpt4 book ai didi

java - 在 hibernate 中使用共享外键列映射两个实体

转载 作者:行者123 更新时间:2023-12-02 08:29:35 25 4
gpt4 key购买 nike

我有四个实体要映射在一起,“关联”、“帐户”、“交易”和“交易事件”。 Association的id是一个简单的整数id。帐户和交易均嵌入了由关联映射和数字组成的 ID。

TransactionEvent 应该有一个嵌入的 ID,由一个帐户和一个关联组成。现在,其中每一个都映射到一个关联,我希望它与一个 TransactionEvent 是相同的关联。

JPA 注释用于 Hibernate 映射,但我无法使其工作。我尝试强制关联键使用相同的列名称,但 Hibernate 提示重复的列。

这可以解决吗,还是我思路不清晰?

这里是带注释的类,但我删除了 getter/setter 和非 id 列以及 javax.persistence 命名空间中的注释:


@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;
}

最佳答案

对于将关联直接放置在嵌入的 id 组件中,我没有太多的经验,因为 JPA 不支持这种方式,而是 Hibernate 特有的。

作为替代方案,我的建议是使用 Composite Primary Keys 中描述的方法。 JPA wikibook 的部分:

(...) JPA 1.0 requires that all @Id mappings be Basic mappings, so if your Id comes from a foreign key column through a OneToOne or ManyToOne mapping, you must also define a Basic @Id mapping for the foreign key column. The reason for this is in part that the Id must be a simple object for identity and caching purposes, and for use in the IdClass or the EntityManager find() API.

Because you now have two mappings for the same foreign key column you must define which one will be written to the database (it must be the Basic one), so the OneToOne or ManyToOne foreign key must be defined to be read-only. This is done through setting the JoinColumn attributes insertable and updatable to false, or by using the @PrimaryKeyJoinColumn instead of the @JoinColumn.

A side effect of having two mappings for the same column is that you now have to keep the two in synch. This is typically done through having the set method for the OneToOne attribute also set the Basic attribute value to the target object's id. This can become very complicated if the target object's primary key is a GeneratedValue, in this case you must ensure that the target object's id has been assigned before relating the two objects.

(...)

Example ManyToOne id annotation

...
@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();
}
...
}

这看起来就是您正在寻找的东西(也许不那么复杂)。我会尝试(增量)实现这个解决方案。

关于java - 在 hibernate 中使用共享外键列映射两个实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3755762/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com