Hibernate一对多问题
我正在对一对多映射进行概念验证,但没有成功。我的架构如下:
Student ---->Phone
class Student
public class Student implements java.io.Serializable
{
private Set<Phone> studentPhoneNumbers = new HashSet<Phone>();
// other setters and getters and constructors
}
class Phone
public class Phone implements java.io.Serializable
{
private Student student;
// other setters and getters and constructors
}
Student 映射文件:
<?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 文件
<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>
I am doing a proof of concept for one to many mapping with no success. My schema is as follows:
Student ---->Phone
class Student
public class Student implements java.io.Serializable
{
private Set<Phone> studentPhoneNumbers = new HashSet<Phone>();
// other setters and getters and constructors
}
class Phone
public class Phone implements java.io.Serializable
{
private Student student;
// other setters and getters and constructors
}
Student Mapping File:
<?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>
Phone Mapping File:
<?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>
But when I am doing this:
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();
I am getting the following errors:
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
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>
and Student mapping file
<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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您需要将 Student 对象推入 Phone 对象:
更典型的代码片段将首先创建 Student 实例,然后向其中添加电话号码。我经常实现一个方法来帮助解决这个问题,例如在 Student.java 中:
所以现在你可以说
student.addPhoneNumber("home", "12354")
它会简单地执行 DTRT。You need to push the Student object into the Phone objects:
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:
So now you can say
student.addPhoneNumber("home", "12354")
and it will simply DTRT.由于您使用带有 inverse=true 选项的双向关联,因此子对象将独立保留。父对象不关心与子对象的同步。因此,在这种情况下,将有一个针对父对象的插入查询和与子对象一样多的插入查询。因此,子对象在插入时需要具有父对象的引用。此外,您还在父级和子级定义了 not-null=true 。
当我们使用 inverse=false 时,将首先保存父对象,然后在不引用父对象的情况下保存子对象,最后父对象将使用更新查询更新其与子对象的关系。
希望这有帮助。
Since you are using Bi-Direction association with inverse=true option, the child objects will be persisted independently. The parent object doesn't take care about synchronization with child objects. So in this case, there will one insert query for parent object and as many insert query as the child objects. So, child object need to have reference of parent object at insert time. Also you have defined not-null=true at parent as well as child side.
When we use inverse=false, parent will be saved first, then child will be saved without reference of parent object and at last the parent will update its relationship with child using the update queries.
Hope this helps.
1).电话号码必须有学生,因此首先创建一个学生对象 (stu = new Student()) 并
然后调用phone.setStudent(stu);
前任:
1). Phone number must have a student so create a student object (stu = new Student()) first and
then call phone.setStudent(stu);
ex: