![](/img/trans.png)
[英]How to use a Primary Key also as a Foreign Key reference with JPA and Hibernate?
[英]Hibernate class with primary key that is also a foreign key
@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”,因此我们要使其成为主键和外键。
我们的应用程序中有相同的情况,并且可以与此一起工作(我们注释属性而不是获取方法,不知道是否存在任何区别):
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();
...
}
...
}
请注意,在构造函数中,应设置id
。 id
和entity
都不应该有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<Entity> entities = new LinkedHashSet<>();
public void setEntities(Set<Entity> entities) {
this.entities.clear();
if (null != entities) {
this.entities.addAll(entities);
}
}
}
@Embeddable
public class Entity {
@Column
@Access(AccessType.FIELD)
private String name;
}
请参考以下文章,以更好地理解:
1.使用@PrimaryKeyJoinColumn http://vard-lokkur.blogspot.my/2011/05/onetoone-with-shared-primary-key.html共享主键的@OneToOne。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.