gpt4 book ai didi

java - Hibernate:insertable = false,updatable = false 属于涉及外键的复合主键星座中的哪里?

转载 作者:IT老高 更新时间:2023-10-28 21:00:01 28 4
gpt4 key购买 nike

在 Hibernate 或其他 ORM 中实现复合主键时,在使用标识关系的复合主键星座(作为 PK 的一部分的 FK)中,最多有三个位置可以放置 insertable = false、updatable = false:

  1. 进入复合 PK 类的 @Column 注释(仅限 @Embeddable 类)或
  2. 进入实体类的关联@JoinColumn/s注解或
  3. 进入实体类的冗余 PK属性的@Column注解(仅限@IdClass类)

第三种方法是使用 @IdClass 和 JPA 1.0 AFAIK 的唯一方法。见 http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Primary_Keys_through_OneToOne_Relationships .我将只考虑案例 1. 和 2。

问:通常将“insertable = false,updatable = false”放置在哪种方式的首选位置?

我在使用 Hibernate 时遇到了关于这个问题的问题。例如,Hibernate 3.5.x 会提示 Zips 表

CREATE TABLE Zips
(
country_code CHAR(2),
code VARCHAR(10),
PRIMARY KEY (country_code, code),
FOREIGN KEY (country_code) REFERENCES Countries (iso_code)
)

与:

org.hibernate.MappingException: Repeated column in mapping for entity: com.kawoolutions.bbstats.model.Zip column: country_code (should be mapped with insert="false" update="false")
org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:676)
org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:698)
...

如您所见,country_code 列既是 PK 也是 FK。以下是它的类:

实体类:

@Entity
@Table(name = "Zips")
public class Zip implements Serializable
{
@EmbeddedId
private ZipId id;

@ManyToOne
@JoinColumn(name = "country_code", referencedColumnName = "iso_code")
private Country country = null;
...
}

复合PK类:

@Embeddable
public class ZipId implements Serializable
{
@Column(name = "country_code", insertable = false, updatable = false)
private String countryCode;

@Column(name = "code")
private String code;
...
}

将 insertable = false, updatable = false 放入实体类关联的@JoinColumn 时,所有异常都会消失,一切正常。但是,我不明白为什么上面的代码不应该工作。可能是 Hibernate 有这个问题。所描述的是否是 Hibernate 错误,因为它似乎没有评估 @Column "insertable = false, updatable = false"?

本质上,什么是标准 JPA 方式、最佳实践或将“insertable = false, updatable = false”放在哪里的偏好?

最佳答案

让我一步一步回答。

1。什么时候需要`insertable = false, updatable = false`?

让我们看看下面的映射,

public class Zip {

@ManyToOne
@JoinColumn(name = "country_code", referencedColumnName = "iso_code")
private Country country = null

@Column(name = "country_code")
private String countryCode;

}

这里我们使用两个不同的属性来引用表中的同一列。在下面的代码中,

Zip z = new Zip();

z.setCountry(getCountry("US"));
z.setCountryCode("IN");

saveZip(z);

Hibernate 会在这里做什么?

为了防止这种不一致,Hibernate 要求您指定关系的更新点。这意味着您可以在表中引用同一列 n 次,但其中只有一个可用于更新,所有其他将是只读的。。 p>

2。为什么 Hibernate 提示您的映射?

在您的 Zip 类中,您指的是再次包含国家代码的嵌入式 id 类 ZipId。与上述场景一样,现在您可以从两个位置更新 country_code 列。因此,Hibernate 给出的错误是正确的。

3。在您的情况下如何解决?

没有。理想情况下,您希望您的 ZipId 类生成 id,因此您不应将 insertable = false, updatable = false 添加到 ZipId 内的 countryCode .所以修复如下修改你的 Zip 类中的 country 映射如下,

@ManyToOne
@JoinColumn(name = "country_code", referencedColumnName = "iso_code",
insertable = false, updatable = false)
private Country country;

希望这有助于您的理解。

关于java - Hibernate:insertable = false,updatable = false 属于涉及外键的复合主键星座中的哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3669883/

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