Frage

Nehmen wir eine Abbildung wie diese

@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);
    }

}

Und eine Frage und Antwort durch eine Info-Klasse zugeordnet

@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;
    }

}

In getAnswer verwenden i ManyToOne statt OneToOne, weil einige Fragen im Zusammenhang mit OneToOne Kartographie. Ein OneToOne kann als ManyToOne (unique = true in @JoinColumn) abgebildet werden. INFO_INDEX ist nicht auf einen bestimmten Zweck verwendet. Nur ein Schlüssel, um eine Verbindung unterstützt Primärschlüssel in einem Altsystem.

Vor der Beantwortung, kümmern sich um die folgenden:

  

Wenn ein Objekt eine zugewiesene Kennung hat, oder einen zusammengesetzten Schlüssel, sollte die Kennung an die Objektinstanz zugeordnet wird vor dem Aufruf von save ()

Also ich habe zur Karte JoinColumn (name = "BENUTZER_ID", referencedColumnName = "BENUTZER_ID", einführbar = false, aktualisierbare = false) in getAnswer weil Hibernate nicht zwei erlaubt veränderbare Eigenschaften die gleichen teilen collumn (userId auch BENUTZER_ID verwendet) sonst i BENUTZER_ID in Antwort Eigenschaft erhalten werden muss einführbar abgebildet werden = false, aktualisierbare = false

Jetzt einen Blick auf getAnswer Mapping nehmen

@ManyToOne
JoinColumns({
    JoinColumn(name="USER_ID", referencedColumnName="USER_ID", insertable=false, updateable=false),
    JoinColumn(name="ANSWER_INDEX", referencedColumnName="INFO_INDEX", insertable=false)
})

Weil es, Hibernate klagt man nicht anders einsetzbar mischen und aktualisierbar

Was soll ich tun, um es zu übergeben?

Achten Sie darauf, es ist ein Altsystem.

Grüße,

War es hilfreich?

Lösung 2

Nach Frage in getAnswer Mapping

@ManyToOne
JoinColumns({
    JoinColumn(name="USER_ID", referencedColumnName="USER_ID", insertable=false, updateable=false),
    JoinColumn(name="ANSWER_INDEX", referencedColumnName="INFO_INDEX", insertable=false)
})

Ruhezustand wird sich beschweren, weil es mischen sich erlaubt nicht anders einsetzbar und aktualisierbar. Beachten Sie ein einsetzbar und aktualisierbar in BENUTZER_ID JoinColumn und nur einsetzbar in ANSWER_INDEX JoinColumn.

Also, um es zu passieren, i einrichten ANSWER_INDEX JoinCollumn accortding zu

JoinColumn(name="ANSWER_INDEX", referencedColumnName="INFO_INDEX", insertable=false, updateable=false)

Auf diese Weise Hibernate nicht beschweren.

Und ich gründe eine neue Eigenschaft namens answerIndex

private Integer answerIndex;   

@Column(name="ANSWER_INDEX", insertable=false)
public void getAnswerIndex() {
    return this.answerIndex;
}

Dann in Benutzer addAnswer

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);

    // Added in order to set up AnswerIndex property
    question.setAnswerIndex(answer.getInfoId().getIndex());
}

Andere Tipps

Sie würde drastisch vereinfacht Ihr Mapping durch eingebettete ID verzichten und ein Surrogat PK stattdessen verwenden.

Wenn Sie InfoId.index für einen bestimmten Zweck verwenden müssen (Fragen / Antworten bestellen? Sie, dass in list Mapping angeben), halten Sie es als eine regelmäßige Eigenschaft.

UserId wird durch ManyToOne auf User ersetzt werden; die anderen Assoziationsende (in User Klasse) als @OneToMany(mappedBy="User") abgebildet werden

Warum ist Antwort als ManyToOne abgebildet? Sollte es nicht OneToMany (zum Beispiel 1 Frage viele Antworten) werden? So oder so, Mapping-Klasse auf sich selbst ist weniger als ideal - Sie sind im Grunde eine „Adjazenzliste“ Modellhierarchie Implementierung, die ineffizient ist; und in Ihrem Fall müssen Sie sicherstellen, dass es nicht mehr als 2 Ebenen. Ich würde Question und Answer als separate Klassen zuordnen; Sie können sie eine gemeinsame Schnittstelle haben implementieren oder die gleiche Basis (möglicherweise abstrakte) Klasse erweitern; In beiden Fällen können Sie impliziten Polymorphismus von Hibernate zur Verfügung gestellt genießen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top