Java 使用映射使用Hibernate注释创建主键
我不太习惯ORM映射,因为我有PHP背景。我试图在一系列问题和他们可能的答案之间建立一种联系,并从中找出正确的答案 我试图创建一个可以查询其相应答案的问题对象,但不幸的是,我创建的最好的Java类会导致重复技术上不必要的字段 理想的数据库架构如下所示:Java 使用映射使用Hibernate注释创建主键,java,hibernate,Java,Hibernate,我不太习惯ORM映射,因为我有PHP背景。我试图在一系列问题和他们可能的答案之间建立一种联系,并从中找出正确的答案 我试图创建一个可以查询其相应答案的问题对象,但不幸的是,我创建的最好的Java类会导致重复技术上不必要的字段 理想的数据库架构如下所示: CREATE TABLE `question` ( `question_id` BIGINT AUTO_INCREMENT, `questionText` VARCHAR(255),
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类将为映射创建一组额外的问题id索引。如果我可以使用字段作为主键,这是可以接受的。
此外,correctAnswer将在使用当前id时生成对问题的不必要引用
以下是我用来创建结构的类:
@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...
}
如果您能提供任何帮助或建议,我们将不胜感激。不要使用地图,而是使用列表作为答案,并使用索引作为排序顺序。还可以为每个答案分配一个唯一的ID,就像问题一样,而不是使用复合键。Hibernate将在问题对象中使用此ID,而不是索引
这种设计的唯一缺点是,您必须确保正确答案实际上是该问题答案列表中的一项。从积极的方面来看,这将使代码和映射更加简单。这似乎非常有效,谢天谢地,约束正确答案相对容易。谢谢