在休眠或其他ORMS中实现复合主键时,最多可以将插入可插入= false的三个位置放在复合主密钥星座中,这些键在使用识别关系(属于PK的一部分)中:

  1. 进入复合PK类'@Column注释(仅@embeddable类)或
  2. 进入实体类协会 @joincolumn/s注释或
  3. 进入实体类' 多余的 PK属性的@Column注释(仅@IDClass类)

第三是@IDClass和JPA 1.0 AFAIK的唯一方法。看 http://en.wikibooks.org/wiki/java_persistence/indestity_and_secorncing#primary_keys_keys_through_through_onetoone_relationships. 。我将仅考虑案例1.和2。

问:将“插入= false,更新= false”放置的首选位置通常是哪种方式?

关于这个问题,我遇到了冬眠的问题。例如,Hibernate 3.5.x将抱怨邮政编码表

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

将插入= false放置时,更新= false进入实体类协会的@joincolumn,所有异常都消失了,一切正常。但是,我不明白为什么上述代码不应该工作。这可能是有问题的冬眠。描述的是一个冬眠错误,因为它似乎没有评估@column“ insertable = false,fordsable = false”?

从本质上讲,标准JPA的方式,最佳实践或偏好是放置“插入= false,更新= false”的位置?

有帮助吗?

解决方案

让我逐步回答。

1.什么时候需要`插入= 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.为什么冬眠抱怨您的映射?

在你的 Zip 您指的是嵌入式ID类 ZipId 这再次包含国家代码。与上述情况一样,现在您有可能更新 counry_code 列来自两个地方。因此,冬眠给出的错误是正确的。

3.如何在您的情况下修复它?

否。理想情况下,您想要您的 ZipId 生成ID的课程,因此您不应该添加 insertable = false, updatable = false 到达内部的乡村代码 ZipId. 。因此,修复如下修改 country 映射您的 Zip 下面的课,

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

希望这有助于您的理解。

其他提示

您也可以使用 @PrimaryKeyJoinColumn 注释。主键列注释指定了一个主键列,该列被用作外键连接到另一个表。

主要的keyjoincolumn注释用于将实体子类的主要表连接到其超级类的主表中。它被用于辅助注释中,将辅助表与主表连接在一起。它可以用于ONETOONE映射中,其中参考实体的主要键用作参考实体的外键。如果未在连接的映射策略中为子类指定主要的键列注释,则假定外键列具有与超级类主表的主键列相同的名称。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top