2012-02-10 3 views
1

질문, 답변 및 QuestionDisplayRule 3 개의 항목을 매핑하려고합니다. 질문에는 하나의 질문에 속하는 많은 Answers 및 많은 QuestionDisplayRules가 있습니다. QuestionDisplayRule에는 질문이 하나, 답변이 하나, 문자열 값이 하나의 필드가 있습니다. QuestionDisplayRule의 DB 테이블은 다음과 같습니다JPA, Hibernate : 연관이있는 복합 키. 로드하고 저장하지 않는 이유는 무엇입니까?

create table question_display_rule(
    question_id int, 
    answer_id int, 
    answer_value varchar(128) 
); 

물론, question_id 및 answer_id는 PK입니다.

JPA 매핑은 다음과 같습니다

@Embeddable 
public class QuestionDisplayRulePK implements Serializable { 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name="question_id", insertable = false, updatable = false) 
    private Question question; 

    @ManyToOne 
    @JoinColumn(name = "answer_id", insertable = false, updatable = false) 
    private Answer answer; 
} 

@Entity 
@Table(name = "question_display_rule") 
public class QuestionDisplayRule implements Serializable { 

    @EmbeddedId 
    private QuestionDisplayRulePK id; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name="question_id", insertable = false, updatable = false) 
    private Question question; 

    @ManyToOne 
    @JoinColumn(name = "answer_id", insertable = false, updatable = false) 
    private Answer answer; 

    @Column(name="answer_value") 
    private String answerValue; 

} 

문제는 제가 DB에서 수동으로 레코드를 추가하지만, 그들을 저장하지 않을 경우는 QuestionDisplayRules이 잘로드 것입니다. 어떤 오류도없고, 아무것도 ..

테스트 코드 :

QuestionDisplayRulePK qPK = new QuestionDisplayRulePK(); 
    qPK.setQuestion(q); 
    qPK.setAnswer(a); 

    QuestionDisplayRule qr = new QuestionDisplayRule(qPK, "Yes"); 
    qr.setAnswerValue("whateva.."); 

    .... 
    // DAO code looks like: getSession().saveOrUpdate(qr); 

어떤 아이디어? 감사!

+0

복합 키를 사용하는 이유는 무엇입니까? 좋은 이유로, Hibernate와 JPA는이를 권장하지 않습니다. 그리고 QuestionDisplayRule에서 Question에 대한 협회가있는 이유는 무엇입니까? 그것은 이미 To-To to One을 가지고 있기 때문에 필요하지 않습니다. 단일 열 자동 생성 ID를 사용하면 삶이 훨씬 쉬워집니다. 마지막으로 동일한 연결을 ID에 한 번, 개체에 한 번 두 번 매핑합니다. –

+0

Answer Question에서 매핑 질문은 하나의 답변 참조와 다른 질문이기 때문에. QuestionDisplayRule은 '이 답변에 대한 답변 (및 그 질문)이 answerValue와 일치하면이 질문 표시'와 같습니다. 그리고 나는 데이터베이스 설계가 Hibernate에 의해 지시받는 것처럼 느껴지기 때문에 단일 열 ID를 소개하고 싶지 않습니다. 그것에 영향을주지 않아야합니다. 프레임 워크가오고, 데이터는 수년간 머물러 있습니다. –

답변

1

임베디드에서 엔터티를 매핑 중입니다. 잘못된 것입니다. 삽입 가능은 기본 유형 만 포함해야합니다. 즉, 엔티티는 다음과 같아야합니다.

@Entity 
public class Question 
{ 
    @Id 
    @GeneratedValue 
    @Column(name = "id") 
    private Long id; 
    @OneToMany(mappedBy = "question") 
    private Set<Answer> answers; 
} 

@Entity 
public class Answer 
{ 
    @Id 
    @GeneratedValue 
    @Column(name = "id") 
    private Long id; 

    @ManyToOne 
    private Question question; 
} 

@Entity 
public class QuestionDisplayRule 
{ 
    @EmbeddedId 
    private QuestionDisplayRulePK key; 

    @MapsId(value = "questionId") 
    @ManyToOne 
    @JoinColumn(name = "question_id", referencedColumnName = "id") 
    private Question question; 

    @MapsId(value = "answerId") 
    @ManyToOne 
    @JoinColumn(name = "answer_id", referencedColumnName = "id") 
    private Answer answer; 
} 

@Embeddable 
public class QuestionDisplayRulePK 
{ 
    @Column(name = "answer_id") 
    private Long answerId; 
    @Column(name = "question_id") 
    private Long questionId; 
}