具有主键的Hibernate类也是外键

@Entity @Table(name = "USER_DATA") public class UserData { Entity entity; @OneToOne(fetch = FetchType.EAGER) @PrimaryKeyJoinColumn(name="PK_FK_ENTITY") @Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE}) public Entity getEntity() { return entity; } public void setEntity(Entity entity) { this.entity = entity; } } 

给出的错误是“没有为实体指定标识符”。 如何指定实体字段既是主键又是外键? 请注意,此处没有“UserData”的类层次结构; 它只是一个单一的课程。 事实恰恰相反,对于每个’UserData’,只有一个’Entity’,因此我们希望它既是主键,也是外键。

我们在我们的应用程序中有相同的情况,它适用于此(我们注释属性而不是getter,不知道是否有任何区别):

 public class UserData { @Id @Column(name="PK_FK_ENTITY") private int id; @OneToOne @JoinColumn(name="PK_FK_ENTITY") private Entity entity; ... public UserData (Entity entity, ...) { this.id = entity.getId(); ... } ... } 

请注意,在构造函数中,您应该设置ididentity都不应该有一个setter,因为它不能改变。

另请注意,在这种情况下我们不使用级联。 我们首先保存具有生成ID的Entity ,然后保存UserData

对于一对一双向映射,只需在子实体上定义@MapsId注释即可。

 @Entity @Table(name = "USER_DATA") public class UserData { @OneToOne(cascade = CascadeType.ALL, mappedBy = "userData", orphanRemoval = true) private Entity entity; public void setEntity(Entity entity) { this.entity = entity; if (null != entity && entity.getUserData() != this) { entity.setUserData(this); } } } @Entity @Table(name = "ENTITY") public class Entity { @Id private Long id; @MapsId @OneToOne @JoinColumn(name = "user_data_id") private UserData userData; public void setUserData(UserData userData) { this.userData = userData; if (null != userData && userData.getEntity() != this) { userData.setEntity(this); } } } 

对于一对多单向映射,您必须使用@ElementalCollection和@CollectionTable并使用@Embeddable注释注释Entity.class

  @Entity @Table(name = "USER_DATA") public class UserData { @ElementCollection @CollectionTable(name = "entity", joinColumns = @JoinColumn(name = "user_data_id"), uniqueConstraints = { @UniqueConstraint(columnNames = { "user_data_id", "name" }) }) private final Set entities = new LinkedHashSet<>(); public void setEntities(Set entities) { this.entities.clear(); if (null != entities) { this.entities.addAll(entities); } } } @Embeddable public class Entity { @Column @Access(AccessType.FIELD) private String name; } 

请参阅以下文章以便更好地理解:
1. @OneToOne使用@PrimaryKeyJoinColumn共享主键http://vard-lokkur.blogspot.my/2011/05/onetoone-with-shared-primary-key.html 。

  1. @OneToOne使用@MapsId共享主键http://vard-lokkur.blogspot.my/2014/05/onetoone-with-shared-primary-key.html