Supposons une application comme celui-ciUne cartographie Stackoverflow (Hibernate)
@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);
}
}
Et une question et réponse mis en correspondance par une classe Infos
@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;
}
}
En RenvoieQuestion j'utilise ManyToOne au lieu de OneToOne parce que certaines questions lié à la cartographie OneToOne. Un OneToOne peut être mappé en tant que ManyToOne (unique = true dans @JoinColumn). INFO_INDEX n'est pas lié à un but spécifique. Juste une clé pour soutenir une clé primaire composée dans un système LEGACY.
Avant de répondre, prendre en charge les éléments suivants:
Si un objet a un identifiant attribué, ou une clé composite, l'identificateur doit être attribué à l'instance d'objet avant d'appeler save()
Donc je dois mapper JoinColumn (name = "USER_ID", referencedColumnName = "USER_ID", insérable = false, updateable = false) dans getAnswer car Hibernate ne permet pas à deux propriétés mutables de partager la même colonne (userId utilise également USER_ID) sinon j'obtiendra USER_ID en réponse pr opriété doit être mis en correspondance avec insérable = false, actualisable = false
Maintenant, jetez un oeil à la cartographie RenvoieQuestion
@ManyToOne
JoinColumns({
JoinColumn(name="USER_ID", referencedColumnName="USER_ID", insertable=false, updateable=false),
JoinColumn(name="ANSWER_INDEX", referencedColumnName="INFO_INDEX", insertable=false)
})
Parce que, Hibernate se plaint que vous ne pouvez pas mélanger différents insérables et actualisable
Que dois-je faire pour le passer?
Faites attention, c'est un système LEGACY.
salutations,
Bonne CHSS, en fait ManyToOne. Je l'utilise à la place de OneToOne car certains problèmes liés au mapping OneToOne. Un OneToOne peut être mappé en tant que ManyToOne (unique = true dans @JoinColumn). INFO_INDEX n'est pas lié à un but spécifique. Juste une clé pour soutenir une clé primaire composée dans un système LEGACY. Je vais essayer demain. Cordialement, –