Предположим, что такое отображение
@Entity
public class User {
private Integer id
private List<Info> infoList;
@Id
public getId() {
return this.id;
}
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="USER_ID", insertable=false, updateable=false, nullable=false)
public getInfoList() {
return this.infoList;
}
public void addQuestion(Info question) {
info.setInfoCategory(InfoCategory.QUESTION);
info.setInfoId(new InfoId(getId(), getInfoList().size()));
getInfoList().add(question);
}
public void addAnswer(InfoRepository repository, Integer questionIndex, Info answer) {
Info question = repository.getInfoById(new InfoId(getId(), questionIndex));
if(question.getInfoCategory().equals(InfoCategory.ANSWER))
throw new RuntimeException("Is not a question");
if(question.getAnswer() != null)
throw new RuntimeException("You can not post a new answer");
answer.setInfoCategory(InfoCategory.ANSWER);
answer.setInfoId(new InfoId(getId(), getInfoList().size()));
getInfoList().add(answer);
question.setAnswer(answer);
}
}
И вопрос и ответ, сопоставленный с классом Info
@Entity
public class Info implements Serializable {
private InfoId infoId;
private Info answer;
private InfoCategory infoCategory;
public Info() {}
@Embeddable
public static class InfoId {
private Integer userId;
private Integer index;
public InfoId(Integer userId, Integer index) {
this.userId = userId;
this.index = index;
}
@Column("USER_ID", updateable=false, nullable=false)
public getUserId() {
return this.userId;
}
@Column("INFO_INDEX", updateable=false, nullable=false)
public getIndex() {
return this.index;
}
// equals and hashcode
}
// mapped as a ManyToOne instead of @OneToOne
@ManyToOne
JoinColumns({
JoinColumn(name="USER_ID", referencedColumnName="USER_ID", insertable=false, updateable=false),
JoinColumn(name="ANSWER_INDEX", referencedColumnName="INFO_INDEX", insertable=false)
})
public Info getAnswer() {
return this.answer;
}
@EmbeddedId
public InfoId getInfoId() {
return this.infoId;
}
}
В getAnswer я использую ManyToOne вместо OneToOne, потому что некоторые проблемы связаны с отображением OneToOne. OneToOne может быть отображен как ManyToOne (уникальный = true в @JoinColumn). INFO_INDEX не связан с какой-либо конкретной целью. Просто ключ для поддержки составного первичного ключа в системе LEGACY.
Прежде чем ответить, позаботьтесь о следующем:
Если объект имеет назначенный идентификатор или составной ключ, идентификатор ДОЛЖЕН БЫТЬ ПРИВЯЗАН к экземпляру объекта ПЕРЕД вызовом save ()
Так что мне нужно отобразить JoinColumn (name = "USER_ID", referencedColumnName = "USER_ID", вставляемый = false, updateable = false) в getAnswer, поскольку Hibernate не позволяет двум изменяемым свойствам совместно использовать один и тот же столбец (userId также использует USER_ID) в противном случае я получу USER_ID в свойстве ответа, которое должно быть сопоставлено с inserttable = false, updateable = false
Теперь взглянем на отображение getAnswer
@ManyToOne
JoinColumns({
JoinColumn(name="USER_ID", referencedColumnName="USER_ID", insertable=false, updateable=false),
JoinColumn(name="ANSWER_INDEX", referencedColumnName="INFO_INDEX", insertable=false)
})
Из-за этого, Hibernate жалуется, что вы не можете смешивать разные вставляемые и обновляемые
Что я должен сделать, чтобы передать его?
Позаботьтесь, чтобы это была система LEGACY.
С уважением,