2010-12-06 2 views
0

Я делаю доказательство концепции для одного-многих карт без успеха. Моя схема выглядит следующим образом:Hibernate One To Many Problem

Student ---->Phone 

класс Student

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 
} 

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> 

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 нт отображение файла

<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, а затем добавить телефонные номера к нему , Я часто применял метод, помогающий с этим, например. в 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

Cab кто-то помочь мне в определении атрибута для этого – Noor 2010-12-06 05:56:20

1

Поскольку вы используете связь Bi-Direction с опцией inverse = 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