I'm not too used to ORM mapping, having come from a PHP background. I'm trying to achieve a link between a series of questions and their possible answers, along with the correct answer from that set.
I'm trying to create a Question object that can be queried for it's corresponding Answers, but unfortunately, the best Java classes I've crafted lead to duplicate (technically unneccessary) fields.
The ideal database schema would look like this:
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`)
);
Unfortunately, the Java classes I'm about to list will create an extra set of (question_id, index) for the Map. This would be acceptable if I could use the fields as the primary key. In addition, correctAnswer will generate an unneccessary reference to Question when using the current id would be fine.
The following are the classes that I'm using to create the structure:
@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...
}
Any help or advice would be greatly appreciated.