您好我正在开发小应用程序来练习hibernate。我试图做一对多的关系而且我被卡住了。
我有2个课程问答:
package com.sample;
import java.util.List;
public class Question {
private int id;
private String qname;
private List<Answer> answers;
public Question() {
}
public Question(int id, String qname, List<Answer> answers) {
super();
this.id = id;
this.qname = qname;
this.answers = answers;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getQname() {
return qname;
}
public void setQname(String qname) {
this.qname = qname;
}
public List<Answer> getAnswers() {
return answers;
}
public void setAnswers(List<Answer> answers) {
this.answers = answers;
}
}
和
package com.sample;
public class Answer {
private int id;
private String answername;
private String postedBy;
private Question question;
public Answer() {
}
public Answer(int id, String answername, String postedBy, Question question) {
super();
this.id = id;
this.answername = answername;
this.postedBy = postedBy;
this.question = question;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAnswername() {
return answername;
}
public void setAnswername(String answername) {
this.answername = answername;
}
public String getPostedBy() {
return postedBy;
}
public void setPostedBy(String postedBy) {
this.postedBy = postedBy;
}
public Question getQuestion() {
return question;
}
public void setQuestion(Question question) {
this.question = question;
}
}
配置文件如下:
question.hbm.xml:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.sample.Question" table="question">
<id name="id">
<generator class="increment"></generator>
</id>
<property name="qname"></property>
<bag name="answers" table="answer" inverse="true" lazy="true"
fetch="select" cascade="all">
<key>
<column name="question_id" not-null="true">
</column>
</key>
<one-to-many class="com.sample.Answer"></one-to-many>
</bag>
</class>
</hibernate-mapping>
answer.hbm.xml:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.sample.Answer" table="answer">
<id name="id">
<generator class="increment"></generator>
</id>
<property name="answername"></property>
<property name="postedBy"></property>
<many-to-one name="question" class="com.sample.Question"
fetch="select">
<column name="question_id" not-null="true">
</column>
</many-to-one>
</class>
</hibernate-mapping>
我的主文件如下:
import java.util.ArrayList;
import org.hibernate.*;
import org.hibernate.cfg.*;
public class StoreData {
public static void main(String[] args) {
Session session = SessionFactoryUtil.getSessionFactory()
.getCurrentSession();
Transaction t = session.beginTransaction();
Answer ans1 = new Answer();
ans1.setAnswername("java is a programming language");
ans1.setPostedBy("Ravi Malik");
Answer ans2 = new Answer();
ans2.setAnswername("java is a platform");
ans2.setPostedBy("Sudhir Kumar");
Answer ans3 = new Answer();
ans3.setAnswername("Servlet is an Interface");
ans3.setPostedBy("Jai Kumar");
Answer ans4 = new Answer();
ans4.setAnswername("Servlet is an API");
ans4.setPostedBy("Arun");
ArrayList<Answer> list1 = new ArrayList<Answer>();
list1.add(ans1);
list1.add(ans2);
ArrayList<Answer> list2 = new ArrayList<Answer>();
list2.add(ans3);
list2.add(ans4);
Question question1 = new Question();
question1.setQname("What is Java?");
question1.setAnswers(list1);
Question question2 = new Question();
question2.setQname("What is Servlet?");
question2.setAnswers(list2);
session.persist(question1);
session.persist(question2);
t.commit();
// session.close();
System.out.println("success");
}
}
当我运行应用程序时,我收到以下错误:
Exception in thread "main" org.hibernate.PropertyValueException: not-null property references a null or transient value : com.sample.Answer.question
at org.hibernate.engine.internal.Nullability.checkNullability(Nullability.java:106)
at org.hibernate.action.internal.AbstractEntityInsertAction.nullifyTransientReferencesIfNotAlready(AbstractEntityInsertAction.java:132)
at org.hibernate.action.internal.AbstractEntityInsertAction.makeEntityManaged(AbstractEntityInsertAction.java:141)
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:203)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:181)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:168)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:332)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:288)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:137)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:801)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:794)
at org.hibernate.engine.spi.CascadingActions$7.cascade(CascadingActions.java:314)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:379)
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:319)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:296)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:460)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:294)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:137)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:356)
at com.sun.proxy.$Proxy0.persist(Unknown Source)
at com.sample.StoreData.main(StoreData.java:46)
答案 0 :(得分:0)
Hibernate尝试保存答案,该答案引用了在保存时没有id的问题。
首先尝试保存没有答案的问题,然后为每个答案调用setQuestion传递已保存的问题。只需保存答案。
答案 1 :(得分:0)
我通过先添加问题然后将问题设置为答案来修复它。
Question question1 = new Question();
question1.setQname("What is Java?");
Question question2 = new Question();
question2.setQname("What is Servlet?");
session.persist(question1);
session.persist(question2);
Answer ans1 = new Answer();
ans1.setAnswername("java is a programming language");
ans1.setPostedBy("Ravi Malik");
ans1.setQuestion(question1);
Answer ans2 = new Answer();
ans2.setAnswername("java is a platform");
ans2.setPostedBy("Sudhir Kumar");
ans2.setQuestion(question1);
Answer ans3 = new Answer();
ans3.setAnswername("Servlet is an Interface");
ans3.setPostedBy("Jai Kumar");
ans3.setQuestion(question2);
Answer ans4 = new Answer();
ans4.setAnswername("Servlet is an API");
ans4.setPostedBy("Arun");
ans4.setQuestion(question2);
session.persist(ans1);
session.persist(ans2);
session.persist(ans3);
session.persist(ans4);