Hibernate один ко многим проблема - PullRequest
0 голосов
/ 06 декабря 2010

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

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>

и файла сопоставления 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>

Ответы [ 3 ]

2 голосов
/ 06 декабря 2010

Вам необходимо вставить объект Student в объекты Phone:

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.

1 голос
/ 02 октября 2014

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
1 голос
/ 06 декабря 2010

Поскольку вы используете связь двунаправленного текста с опцией inverse = true, дочерние объекты будут сохраняться независимо. Родительский объект не заботится о синхронизации с дочерними объектами. Таким образом, в этом случае будет один запрос на вставку для родительского объекта и столько же запросов на вставку, сколько дочерних объектов. Таким образом, дочерний объект должен иметь ссылку на родительский объект во время вставки. Также вы определили not-null = true как на родительской, так и на дочерней стороне.

Когда мы используем inverse = false, сначала будет сохранен родительский элемент, затем дочерний элемент будет сохранен без ссылки на родительский объект, и, наконец, родительский объект обновит свои отношения с дочерним элементом, используя запросы на обновление.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...