2010-12-06 131 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