2010-12-06 130 views
0

我正在做一对多的映射的概念证明没有成功。我的架构如下:休眠一对多问题

Student ---->Phone 

类学生

public class Student implements java.io.Serializable 
{ 
    private Set<Phone> studentPhoneNumbers = new HashSet<Phone>(); 
    // other setters and getters and constructors 
} 

类电话

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文件

设置适当的属性别人的帮助
<many-to-one name="student" class="com.BiddingSystem.domain.Student" not-null="true"> 
      <column name="STUDENTID" not-null="true"/> 
</many-to-one> 

and Stude NT映射文件

<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> 

回答

2

您需要Student对象推到电话对象:

foreach (Phone phone : student.getStudentPhoneNumbers()) { 
    phone.setStudent(student); 
} 

的代码将首先创建学生实例,然后添加电话号码给它一个更典型的一块。我经常实施一种方法来帮助解决这个问题,例如在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。

+0

驾驶室有人能帮助我在设置属性此 – Noor 2010-12-06 05:56:20

1

由于您正在使用逆向= true选项的双向关联,所以子对象将独立保持。父对象不关心与子对象的同步。因此,在这种情况下,将有一个插入查询用于父对象,并有多少插入查询作为子对象。所以,子对象在插入时需要有父对象的引用。此外,您还在父级和子级上定义了not-null = true。

当我们使用inverse = false时,父节点会先保存,然后子节点将被保存而不引用父节点对象,最后父节点将使用更新查询更新它与子节点的关系。

希望这会有所帮助。

1

1)。电话号码必须有一个学生,因此先创建一个学生对象(stu = new Student()),然后拨打电话phone.setStudent(stu);

例如:

Set<Phone> phoneNumbers = new HashSet<Phone>(); 

    Phone p1 = new Phone("house", "32354353"); 

    phoneNumbers.add(p1); 
    Phone p2 = new Phone("mobile", "9889343423"); 
    phoneNumbers.add(p2); 

    Student student = new Student("Eswar", phoneNumbers); 
    student.setPhones(phoneNumbers); 
    session.save(student); //Till now, This code is work if you use cascade = 'all' in   //my_mapping_file.xml or 

    session.save(p1); session.save(p2); //call session.save on both phone objects