2010-12-06 25 views
0

私は1対多マッピングで成功の証明なしの概念証明をしています。次のように私のスキーマは次のとおりです。Hibernate One To Many問題

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> 

とStude

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

コードの多くの典型的な作品は、最初の学生のインスタンスを作成し、それに電話番号を追加します。あなたが電話オブジェクトに学生オブジェクトをプッシュする必要がありマッピングファイル

<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

NT 。私はしばしばこれを手助けする方法を実装しました。 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

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