2010-12-06 37 views
0

Je fais une preuve de concept pour un mappage un à plusieurs sans succès. Mon schéma est le suivant:Hibernate One To Many Problème

Student ---->Phone 

classe Student

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

classe Téléphone

public class Phone implements java.io.Serializable 
{ 
    private Student student; 
// other setters and getters and constructors 
} 

étudiant fichier de mappage:

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

Téléphone fichier de mappage:

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

Mais quand je fais ceci:

  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(); 

Je reçois les erreurs suivantes:

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 

aide quelqu'un peut dans la définition des attributs appropriés pour ce fichier xml mappage de téléphone

<many-to-one name="student" class="com.BiddingSystem.domain.Student" not-null="true"> 
      <column name="STUDENTID" not-null="true"/> 
</many-to-one> 

et Stude nt fichier de mappage

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

Répondre

2

Vous devez pousser l'objet de l'étudiant dans les objets Téléphone:

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

Un morceau plus typique de code serait créer l'instance d'étudiant d'abord, puis ajouter les numéros de téléphone à ce . J'ai souvent mis en œuvre une méthode pour aider à cela, par exemple. en 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)); 
} 

vous pouvez dire Alors maintenant student.addPhoneNumber("home", "12354") et il sera tout simplement DTRT.

+0

quelqu'un Cab me aider à mettre l'attribut pour cette – Noor

1

Étant donné que vous utilisez l'association Bi-Direction avec l'option inverse = true, les objets enfants seront conservés indépendamment. L'objet parent ne prend pas en charge la synchronisation avec les objets enfants. Donc, dans ce cas, il y aura une requête d'insertion pour l'objet parent et autant de requêtes d'insertion que les objets enfants. Ainsi, l'objet enfant doit avoir la référence de l'objet parent au moment de l'insertion. Vous avez également défini non-null = true au niveau du parent et du côté enfant. Lorsque nous utilisons inverse = false, le parent sera sauvegardé en premier, alors l'enfant sera sauvegardé sans référence de l'objet parent et enfin le parent mettra à jour sa relation avec l'enfant en utilisant les requêtes de mise à jour.

Espérons que cela aide.

1

1). Le numéro de téléphone doit avoir un étudiant afin de créer un objet étudiant (stu = new Student()) d'abord et puis appelez phone.setStudent (stu);

ex:

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