2012-08-13 131 views
0

我想用Hibernate和JPA實現一對一的關係。我有兩個類是層次結構的一部分:問題層次結構和答案層次結構。休眠,JPA - 單向一對一

@Entity 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 
public abstract class QuestionUnit { 

    @Id 
    @GeneratedValue(strategy = GenerationType.TABLE) 
    private int id; 

    @OneToOne(cascade = CascadeType.ALL)  
    @PrimaryKeyJoinColumn 
    private AnswerUnit correctAnswer; 
...} 


@Entity 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 
public abstract class AnswerUnit { 

    @Id 
    private int id; 

    public abstract Object getAnswerContent(); 

    public abstract boolean isEqual(AnswerUnit otherAnswer); 

    public int getId() { 
     return id; 
    } 
} 

我們有OpenQuestion和OpenAnswer作爲實現。

我想讓OpenQuetions的表具有自動生成的主鍵,並且具有OpenAnswer的表的主鍵與OpenQuestion表中的主鍵具有相同的值。

我試圖按照這裏的例子: http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html part 2.2.5.1。一比一。

但是,當我堅持了OpenQuestion,我得到的列idquestionContent和OpenQuestionAnswer與idanswerContent表OpenQuestion,但IDS的值不匹配。

那麼,我在哪裏犯了一個錯誤?

回答

0

「OpenQuestion」中沒有「CorrectAnswer」列嗎?
這應該是「OpenAnswer」中的ID列的外鍵 -
即 - 這些應該是匹配的ID值。
如果您沒有此列 - 我懷疑您的JPA映射中有某種錯誤。
編輯 - 對我自己 -
請添加MappedSuperClass。請閱讀here

+0

這是問題所在,正如我所說,在OpenQuestion我只有'id'和'questionContent',一切有關映射在日我認爲的代碼。 – Andna 2012-08-13 15:22:49

+0

您還需要@MappedSupperClass - 請參閱我編輯的答案。花了一些時間來提醒它。 – 2012-08-14 14:36:49

+0

我不能使用MappedSuperClass,你不能使用映射到沒有用實體註解的類,並且我有類QuestionList,它具有QuestionUnits的ArrayList。 – Andna 2012-08-14 17:02:56

0

我不知道你在做什麼,爲什麼你有一對一的關係從問題回答??邏輯告訴我一個問題可以有很多答案(可能只有一個正確的答案)。

,並使用該方法,你不應該需要關心這兩個ID的都是平等的,如果多數民衆贊成的情況下,你應該有一個這樣的模式:

@Entity 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 
public abstract class QuestionUnit { 
    @Id ... private int id; 
    @OneToMany private List<AnswerUnit> answers; //optional assuming there's a list of answers for every question 
    @ManyToOne private AnswerUnit correctAnswer; 

    public void setCorrectAnswer(AnswerUnit answer){ 
     if(answer.getQuestion().equals(this)){ //or maybe instead answer.setQuestion(this) 
      this.correctAnswer = answer; 
     }else{ 
      throw new RuntimeError("Answer does not belong to this question"); 
     } 
    } 

    //Other getter and setters 
    //Override the "equals" method!!! 
} 


@Entity 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 
public abstract class AnswerUnit { 
    @Id private int id; 
    @OneToMany private QuestionUnit question; 

    public abstract Object getAnswerContent();  
    public abstract boolean isEqual(AnswerUnit otherAnswer); //should't you just overwrite the equals method in here?  
    //Other getter, setters, etc 
} 

然後使用它,像這樣:

QuestionUnit q = new OpenQuestion(); 
List<AnswerUnit> answers = new List<OpenAnswer>(); 

AnswerUnit a1 = new OpenAnswer(); 
AnswerUnit a2 = new OpenAnswer(); 
AnswerUnit a3 = new OpenAnswer(); 

a1.setQuestion(q); 
a2.setQuestion(q); 
a3.setQuestion(q); 

//Also set the contents and other required info for the questions... 

//And then associate the instances: 
q.setAnswers(answers); 
q.setCorrectAnswer(a3); 

em.persist(q); 

這甚至會用開放和定期解答工作

+0

這個問題只有一個答案,因爲在實現這個抽象類的類中,有一個叫做問題內容的字段。該字段的類型取決於問題的類型。但是所有問題都有一個共同點 - 他們有正確的答案,而且這個答案也是AnswerUnit具體類的一些具體子類。這就是爲什麼有一對一的正確答案。 – Andna 2012-08-14 16:59:29

+0

但是這意味着每個問題只能有一個答案,在這種情況下,我會建議你修改你的模型。也許可以將答案設置爲Embedabble實體,或者甚至刪除該實體並將答案字段直接包含在Question類中。 – 2012-08-14 19:01:46