@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;
}
}
Error given is "No identifier specified for entity". How can I specify that the entity field is both a primary and a foreign key? Note that there is no class hierarchy for 'UserData' here; it is just a single class. It just so happens that for every 'UserData' there will only be one 'Entity', hence we want to make it both a primary and a foreign key.
We have the same case in our application and it works with this (we annotate the properties not the getters, don't know if there is any difference):
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();
...
}
...
}
Note that in the constructor you should set the id
. Neither the id
nor the entity
should have a setter as it cannot change.
Also note that we don't use cascade in this case. We first save the Entity
that has a generated id, and then UserData
.
For one to one bidirectional mapping, just define the @MapsId annotation at the child entity.
@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);
}
}
}
For one to many unidirectional mapping, You have to use @ElementalCollection and @CollectionTable and annotate Entity.class with @Embeddable annotation
@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;
}
Kindly refers to the following articles for better understanding:
1. @OneToOne with shared primary key using @PrimaryKeyJoinColumn http://vard-lokkur.blogspot.my/2011/05/onetoone-with-shared-primary-key.html .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.