当前位置: 首页 > 面试题库 >

Hibernate:在涉及外键的复合主键星座中,insertable = false,可更新= false在哪里?

程毅
2023-03-14
问题内容

在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,可更新= 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,可更新= false”吗?

本质上,什么是标准的JPA方法,最佳实践或在何处放置“ insertable = false,可更新= false”的首选项?


问题答案:

让我一步一步地回答。

1.您何时需要insertable = false,可更新= 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多次引用表中的同一列,但是只能使用其中之一来更新,而所有其他都将是只读的

2.为什么hibernate状态会抱怨您的映射?

在您的Zip类中,您引用的ZipId是再次包含国家/地区代码的Embedded
id类。与上述情况一样,现在您可以counry_code从两个位置更新该列。因此,hibernate给出的错误是正确的。

3.如何解决您的情况?

不能。理想情况下,您希望您的ZipId类生成ID,因此您不应该在中添加insertable = false, updatable = falsecountryCount ZipId。因此,解决方法如下所示,如下所示修改类中的country映射Zip

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

希望这有助于您的理解。



 类似资料:
  • 问题内容: 我有一个类似的问题,如下所示,但解决方案无法解决我的问题。 休眠复合主键包含复合外键,如何映射 我正在尝试加入2个表,每个表都有一个带有部分外键引用的复合主键。 在一个: 在BPK中: 上面的方法给我这个异常: 你能帮忙吗? 问题答案: 假设f1和F2唯一标识A并存在于APK中,则可以通过几种方式使用JPA 2.0的派生ID。最容易显示的是: 这里的关键点是B对A的引用控制了外键字段f

  • 问题内容: 我有一个类似的问题,如下所示,但解决方案无法解决我的问题。 休眠复合主键包含复合外键,如何映射 我正在尝试加入2个表,每个表都有一个带有部分外键引用的复合主键。 在一个: 在BPK中: 上面的方法给我这个异常: 你能帮忙吗? 问题答案: 假设f1和F2唯一标识A并存在于APK中,则可以通过几种方式使用JPA 2.0的派生ID。最容易显示的是: 这里的关键点是B对A的引用控制了外键字段f

  • 我有一个类似的问题如下,但解决方案没有解决我的问题。 hibernate复合主键包含复合外键,如何映射此 我试图连接2个表,每个表都有一个复合主键和部分外键引用。 你能帮忙吗?

  • 我在使用复合主键的hibernate实体集时遇到了问题。 我们的应用程序中有一个概念“Target”。目标id应该是其他三个表(实体)主id的组合。目标也有一个int标记。员工应该有一系列目标。SQL如下所示: 这个SQL工作正常,它允许我每个role_id(员工)多个目标,只要应用程序和项目分类不同。 这是目标ID类 这是目标类 这是employee类,我想在其中为每个员工存储一组目标。 通过h

  • 我有一些实体: 当我试图保存新的cbonus记录时,出现异常: org.postgresql.util.PSQLException: ERROR: null值在列"bank_id"的关系"cBonus"违反了非空约束详细信息:失败的行包含(773, gp3, null, null, f)。 和查询 DEBUG 24817-[nio-8080-exec-4]org . hibernate . SQL

  • 问题内容: 我在这里搜索,但未找到任何类似的主题,因此我发布了一个新问题。 我正在使用现有数据库上的Hibernate。我们不允许更改表的结构和数据。该应用程序正在从数据库读取数据,并根据某种逻辑迁移到另一个数据存储。 现在的问题是关于复合PK映射。例如 表A具有复合PK。 表B也有一个复合PK,此复合PK的一部分是A的PK,此处也用作FK。 我尝试了几种方法,但都无济于事。谁能告诉一个有效的Hi