2009-09-01 6 views
0

PHPのバックグラウンドに由来するORMマッピングにあまり慣れていません。私は一連の質問とそれらの可能な回答との間のリンクを、その集合からの正解と一緒に達成しようとしています。マップを使用してHibernate Annotationsを使用してプライマリキーを作成する

私はそれに対応するAnswersのために問い合わせることができるQuestionオブジェクトを作成しようとしていますが、残念ながら、私が作成した最高のJavaクラスは重複した(技術的に不必要な)フィールドにつながります。

理想的なデータベーススキーマは次のようになります。

CREATE TABLE `question` (
    `question_id`   BIGINT AUTO_INCREMENT, 
    `questionText`   VARCHAR(255), 
    `correctAnswerIndex` INT, 
    PRIMARY KEY (`question_id`), 
    INDEX correct_answer_idx (`question_id`, `correctAnswerIndex`), 
    FOREIGN KEY `correct_answer_idx` (`question_id`, `correctAnswerIndex`) REFERENCES answer(`question_id`, `index`) 
); 

CREATE TABLE `answer` (
    `question_id`   BIGINT, 
    `index`     INT, 
    `answerText`   VARCHAR(32), 
    PRIMARY KEY (`question_id`, `index`), 
    INDEX question_idx (`question_id`), 
    FOREIGN KEY `question_idx` (`question_id`) REFERENCES `question`(`question_id`) 
); 

残念ながら、私はリストアップしようとしていたJavaクラスは、Mapの(question_id、インデックス)の余分なセットを作成します。フィールドを主キーとして使用できるのであれば、これは受け入れられます。 さらに、correctAnswerは、現行のIDを使用するとQuestionとなる不必要な参照を生成します。

次は私が構造を作成するために使用していたクラスです:

@javax.persistence.Entity 
@javax.persistence.Table(name = "question") 
public class Question implements Serializable { 
    @Id 
    @TableGenerator(name = "question_seq", table = "hibernate_sequences", allocationSize = 5) 
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "question_seq") 
    private Long id; 

    @ManyToOne(optional = false) 
    @JoinColumns({ 
     @JoinColumn(name = "correct_answer_index", referencedColumnName = "index"), 
     @JoinColumn(name = "correct_answer_question", referencedColumnName = "question_id") 
    }) 
    private Answer correctAnswer; 

    @CollectionOfElements(fetch = FetchType.LAZY) 
    @JoinTable(name = "answer", joinColumns = @JoinColumn(name = "question_id")) 
    @MapKey(columns = { @Column(name = "index") }) 
    private Map<Integer, Answer> answers = new HashMap<Integer, Answer>(); 

    @Column(length = 255) 
    private String questionText; 

    //... Accessors, Equals(), Hashcode(), etc... 
} 

@javax.persistence.Entity 
@javax.persistence.Table(name = "answer") 
@AssociationOverrides({ 
    @AssociationOverride(name = "pk.index", joinColumns = @JoinColumn(name = "index")), 
    @AssociationOverride(name = "pk.question", joinColumns = @JoinColumn(name = "question_id")), 
}) 
public class Answer implements Serializable { 
    @EmbeddedId 
    private AnswerPK pk = new AnswerPK(); 

    @Column(length = 32) 
    private String answerText; 

    //... Accessors, Equals(), Hashcode(), etc... 
} 

@Embeddable 
public class AnswerPK implements Serializable { 
    @ManyToOne 
    @ForeignKey(name = "answer_for_question") 
    Question question; 

    Integer index; 

    //... Accessors, Equals(), Hashcode(), etc... 
} 

すべてのヘルプやアドバイスをいただければ幸いです。

答えて

0

回答にはMapではなく、Listを使用し、並べ替え順にはindexを使用してください。また、複合キーを使用する代わりに、各回答に一意のIDを割り当てます(質問と同様)。 Hibernateは(インデックスの代わりに)質問オブジェクトでこのIDを使用します。

このデザインの唯一の欠点は、正解が実際にこの質問の回答リストの項目であることを確認する必要があることです。ポジティブな面では、これはあなたのコードとマッピングをはるかに簡単にするでしょう。

+0

これはかなりうまくいくようですが、ありがたいことに、正解を制約するのは比較的簡単です。ありがとう! –