休眠一对多问题 [英] Hibernate One To Many Problem
问题描述
我为一对多映射做了一个概念证明,没有成功。我的架构如下:
I am doing a proof of concept for one to many mapping with no success. My schema is as follows:
Student ---->Phone
class Student
class Student
public class Student implements java.io.Serializable
{
private Set<Phone> studentPhoneNumbers = new HashSet<Phone>();
// other setters and getters and constructors
}
class Phone
class Phone
public class Phone implements java.io.Serializable
{
private Student student;
// other setters and getters and constructors
}
学生映射文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Dec 5, 2010 7:56:05 PM by Hibernate Tools 3.4.0.Beta1 -->
<hibernate-mapping>
<class name="com.BiddingSystem.domain.Student" table="STUDENT">
<id name="studentId" type="long">
<column name="STUDENTID" />
<generator class="native" />
</id>
<property name="studentName" type="java.lang.String">
<column name="STUDENTNAME" />
</property>
<set name="studentPhoneNumbers" table="PHONE" inverse="true" cascade="all">
<key>
<column name="STUDENTID" not-null="true" />
</key>
<one-to-many class="com.BiddingSystem.domain.Phone" />
</set>
</class>
</hibernate-mapping>
电话映射文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Dec 5, 2010 7:56:05 PM by Hibernate Tools 3.4.0.Beta1 -->
<hibernate-mapping>
<class name="com.BiddingSystem.domain.Phone" table="PHONE">
<id name="phoneId" type="long">
<column name="PHONEID" />
<generator class="native" />
</id>
<property name="phoneType" type="java.lang.String">
<column name="PHONETYPE" />
</property>
<property name="phoneNumber" type="java.lang.String">
<column name="PHONENUMBER" />
</property>
<many-to-one name="student" class="com.BiddingSystem.domain.Student" not-null="true">
<column name="STUDENTID" not-null="true"/>
</many-to-one>
</class>
</hibernate-mapping>
但是当我这样做时:
Session session = gileadHibernateUtil.getSessionFactory().openSession();
Transaction transaction = session.beginTransaction();
Set<Phone> phoneNumbers = new HashSet<Phone>();
phoneNumbers.add(new Phone("house","32354353"));
phoneNumbers.add(new Phone("mobile","9889343423"));
Student student = new Student("Eswar", phoneNumbers);
session.save(student);
transaction.commit();
session.close();
我遇到以下错误:
Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value: com.BiddingSystem.domain.Phone.student
at org.hibernate.engine.Nullability.checkNullability(Nullability.java:101)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:313)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
at
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:677)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:669)
at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:252)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:425)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:362)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:338)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:476)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:354)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:705)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:693)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:689)
at com.BiddingSystem.server.GreetingServiceImpl.greetServer(GreetingServiceImpl.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at net.sf.gilead.gwt.PersistentRemoteService.processCall(PersistentRemoteService.java:174)
... 21 more
为此
电话映射xml文件设置正确的属性
Can someone help in setting the proper attributes for this phone mapping xml file
<many-to-one name="student" class="com.BiddingSystem.domain.Student" not-null="true">
<column name="STUDENTID" not-null="true"/>
</many-to-one>
和学生贴图文件
<set name="studentPhoneNumbers" table="PHONE" inverse="true" cascade="all">
<key>
<column name="STUDENTID" not-null="true" />
</key>
<one-to-many class="com.BiddingSystem.domain.Phone" />
</set>
推荐答案
您需要将Student对象推入Phone对象:
You need to push the Student object into the Phone objects:
foreach (Phone phone : student.getStudentPhoneNumbers()) {
phone.setStudent(student);
}
一个更典型的代码将先创建Student实例,然后添加电话号码给它。我经常实施一个方法来帮助这个,例如。 in Student.java:
A more typical piece of code would create the Student instance first, and then add the phone numbers to it. I've often implemented a method to help with this, e.g. in Student.java:
public void addPhoneNumber(Phone phone) {
phone.setStudent(this);
getStudentPhoneNumbers().add(phone);
}
public void addPhoneNumber(String type, String number) {
addPhoneNumber(new Phone(type, number));
}
现在你可以说 student.addPhoneNumber home,12354)
,它将简单地DTRT。
So now you can say student.addPhoneNumber("home", "12354")
and it will simply DTRT.
这篇关于休眠一对多问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!