Hibernate,JPA - 单向一对一

时间:2012-08-13 14:52:24

标签: hibernate jpa

我想使用Hibernate和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 第2.2.5.1部分。一比一。

但是当我坚持OpenQuestion时,我得到的表格OpenQuestion包含idquestionContent列和OpenQuestionAnswer idanswerContent,但ids的值不是不匹配。

那么,我在哪里弄错了?

2 个答案:

答案 0 :(得分:0)

“OpenQuestion”中没有“CorrectAnswer”栏吗?
这应该是“OpenAnswer”中ID列的外键 -
即 - 这些应该是匹配的ID值。
如果您没有此列 - 我怀疑您的JPA映射中存在某种错误。
编辑 - 给自己 -
请添加MappedSuperClass。请阅读here

答案 1 :(得分: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);

即使是公开和定期的答案,这也会起作用