JPA,Hibernate:具有关联的复合键。为什么加载而不保存?
我试图映射3个实体:问题、答案和问题显示规则。这个问题有许多答案和许多问题,每个答案和问题都属于一个问题。QuestionDisplayRule有一个问题、一个答案和一个带字符串值的字段。QuestionDisplayRule的db表如下所示:JPA,Hibernate:具有关联的复合键。为什么加载而不保存?,hibernate,jpa,composite-key,many-to-one,embeddable,Hibernate,Jpa,Composite Key,Many To One,Embeddable,我试图映射3个实体:问题、答案和问题显示规则。这个问题有许多答案和许多问题,每个答案和问题都属于一个问题。QuestionDisplayRule有一个问题、一个答案和一个带字符串值的字段。QuestionDisplayRule的db表如下所示: create table question_display_rule( question_id int, answer_id int, answer_value varchar(128) ); 当然,问题id和答案id是PK
create table question_display_rule(
question_id int,
answer_id int,
answer_value varchar(128)
);
当然,问题id和答案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
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;
}
及
问题是,如果我在数据库中手动添加记录,但不保存记录,它会加载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);
有什么想法吗?谢谢 您将实体映射到可嵌入对象中,这是错误的。可嵌入文件应仅包含基类型。简而言之,您的实体应如下所示:
@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
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;
}
@实体
公开课问题
{
@身份证
@生成值
@列(name=“id”)
私人长id;
@OneToMany(mappedBy=“问题”)
私人设定答案;
}
@实体
公开课答案
{
@身份证
@生成值
@列(name=“id”)
私人长id;
@许多酮
私人问题;
}
@实体
公共类问题显示规则
{
@嵌入ID
私钥;
@MapsId(value=“questionId”)
@许多酮
@JoinColumn(name=“question\u id”,referencedColumnName=“id”)
私人问题;
@MapsId(value=“answerId”)
@许多酮
@JoinColumn(name=“answer\u id”,referencedColumnName=“id”)
私人回答;
}
@可嵌入
公共类问题显示规则PK
{
@列(name=“answer\u id”)
私人长回答;
@列(name=“question\u id”)
私人长问卷;
}
您将实体映射到可嵌入对象中,这是错误的。可嵌入文件应仅包含基类型。简而言之,您的实体应如下所示:
@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
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;
}
@实体
公开课问题
{
@身份证
@生成值
@列(name=“id”)
私人长id;
@OneToMany(mappedBy=“问题”)
私人设定答案;
}
@实体
公开课答案
{
@身份证
@生成值
@列(name=“id”)
私人长id;
@许多酮
私人问题;
}
@实体
公共类问题显示规则
{
@嵌入ID
私钥;
@MapsId(value=“questionId”)
@许多酮
@JoinColumn(name=“question\u id”,referencedColumnName=“id”)
私人问题;
@MapsId(value=“answerId”)
@许多酮
@JoinColumn(name=“answer\u id”,referencedColumnName=“id”)
私人回答;
}
@可嵌入
公共类问题显示规则PK
{
@列(name=“answer\u id”)
私人长回答;
@列(name=“question\u id”)
私人长问卷;
}
为什么要使用组合键?Hibernate和JPA有充分的理由不鼓励这样做。你为什么要在规则中质疑关联?这是没有必要的,因为它已经有了一个要回答的问题,而这个问题也有一个要问的问题。坚持使用单列自动生成的ID,你的生活就会轻松得多。最后,映射同一关联两次:一次在ID中,一次在实体中。映射QuestionDisplayRule中的问题,因为它与答案引用的问题不同。QuestionDisplayRule类似于“如果此答案(以及随后的问题)的答案与answerValue匹配,则显示此问题”。我不想引入一个列id,因为它让我觉得我的数据库设计是由Hibernate决定的。它不应该对它有任何影响。框架来来去去,数据保存多年……为什么要使用复合键?Hibernate和JPA有充分的理由不鼓励这样做。你为什么要在规则中质疑关联?这是没有必要的,因为它已经有了一个要回答的问题,而这个问题也有一个要问的问题。坚持使用单列自动生成的ID,你的生活就会轻松得多。最后,映射同一关联两次:一次在ID中,一次在实体中。映射QuestionDisplayRule中的问题,因为它与答案引用的问题不同。QuestionDisplayRule类似于“如果此答案(以及随后的问题)的答案与answerValue匹配,则显示此问题”。我不想引入一个列id,因为它让我觉得我的数据库设计是由Hibernate决定的。它不应该对它有任何影响。框架来来去去,数据保存多年。。