簡體   English   中英

兩個類之間具有多個關聯的休眠問題

[英]Hibernate problems with multiple associations between two classes

我在Playframework 1.2.4中使用了Hibernate。

我有兩節課:考試和問題。 問題始終具有引用考試的屬性。 考試總是有一個屬性指向一個名為specialQuestion的問題,一個屬性指向一個問題集合。

在此處輸入圖片說明

我的目標是創建一個涉及每個問題的特殊考試。 在創建考試時,我會創建一個特殊問題。 該問題已經很好地創建並保留在數據庫中, 檢查也保留了,但是在沒有引用特殊問題的情況下,匹配列用空值填充。

我不確定注解。 問題是什么 ?

此靜態方法返回默認的特殊問題

public static Question specialQuestion(Examination examination) {
        Question question = new Question();
        question.examination = examination;
        /* Other attributes affectations */
        return question;
}

在這里,它創建了考試,影響了specialQuestion屬性並持久化了對象:

Examination examination = new Examination();
examination.specialQuestion = Question.specialQuestion(examination);
examination.save();

班級考試包含以下屬性:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "examination", fetch = FetchType.LAZY)
    public Set<Question> questions = new HashSet<Question>();

@OneToOne(cascade= CascadeType.ALL, mappedBy = "examination")
    public Question specialQuestion;

課程問題包含:

@ManyToOne
@OneToOne
public Examination examination;

編輯:

如果如果刪除mappedBy在specialQuestion @OneToOne注釋和@OneToOne在問類考試的注釋,我得到的錯誤:我無法加載實體考試了。

這是DDL的重要部分:

CREATE TABLE `question` (
  `questionId` bigint(20) NOT NULL AUTO_INCREMENT,
  `examination_id` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`questionId`),
  KEY `FKBE5CA006E00B1456` (`examination_id`)
) ENGINE=MyISAM AUTO_INCREMENT=204 DEFAULT CHARSET=latin1;

CREATE TABLE `examination` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `specialQuestion` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=10 DEFAULT CHARSET=latin1;

您不能將@ManyToOne@OneToOne添加到同一屬性,因為Hibernate需要知道哪一個是正確的。

而且,由於擁有方是“ Question ”,Hibernate應該如何知道哪個問題是特殊問題? 從數據庫的角度考慮:將關系存儲在問題表中,您最終將獲得引用同一考試的多個問題。 如果這些是無序的(一組), 將如何根據可用數據確定特殊問題? 由於您無法做到這一點,Hibernate也不會做到這一點。

為了解決這個問題,您需要使Examination成為specialQuestion一面,並且可能也只有一個單向關系,即,您不將其映射到Question (刪除mappedBy並添加一列作為對檢查表的引用)。

您可以通過創建一個額外的實體來實現此目的,該實體實際上將充當考試和問題之間的“連接”實體。 這將使您可以靈活地將同一問題分配給多個考試,並為每個考試獨立設置特殊問題。

因此,對於包含相同問題但具有不同特殊問題的兩次考試,表格如下所示:

╔════════════════════════════════╗
║ exam_id question_id is_special ║
╠════════════════════════════════╣
║ 1        1          0          ║
║ 1        2          0          ║
║ 1        3          1          ║
║ 1        4          0          ║
║ 1        5          0          ║
║ 2        1          1          ║
║ 2        2          0          ║
║ 2        3          0          ║
║ 2        4          0          ║
║ 2        5          0          ║
╚════════════════════════════════╝

這三個實體的基本映射如下:

@Entity
public class Examination{

    @Id
    private int id;

    @OneToMany(mappedBy = "examination")
    private Set<ExaminationQuestion> examQuestions;

    public Set<Question> getNormalQuestions(){
        Set<Question> questions = new HashSet<>();

        for(ExaminationQuestion eq: examQuestions){
            if(! eq.getQuestion.isSpecialQuestion()){
                questions.add(eq.getQuestion());
            }
        }

        return questions;
    }

    public Question getSpecialQuestion(){
        Question specialQuestion = null;

        for(ExaminationQuestion eq: examQuestions){
            if(eq.getQuestion.isSpecialQuestion()){
                specialQuestion = eq.getQuestion();
                break;
            }
        }

        return specialQuestion; 
    }
}

@Entity
public class ExaminationQuestion{

    @Id
    private int id;

    @ManyToOne
    private Examination examination;

    @ManyToOne
    private Questions question;

    private boolean specialQuestion;
}

@Entity
public class Question{

    @Id
    private int id;

    @OneToMany(mappedBy = "question")
    private Set<ExaminationQuestion> examQuestions;
}

我根據托馬斯的答案找到了一個解決方案:

在不修改架構的情況下,這些類會變成

課堂問題:

@OneToOne
@JoinColumn(name = "examination_id")
public Examination examination;

班級考試:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "examination", fetch = FetchType.LAZY)
public Set<Question> questions = new HashSet<Question>();

@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "specialQuestion")
public Question specialQuestion;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM