0

私は Hibernate が初めてで、POJO クラスの Person と Event の間のマッピングを作成しようとしています。Person には、次に示すように一連のイベントがあります。

Event クラスの POJO とそのマッピング ファイル:

public class Event {
    private Long id;
    private String title;
    private Date date;
    // setter & getter methods
}

<class name="Event" table="EVENTS">
    <id name="id" column="EVENT_ID">
        <generator class="native" />
    </id>
    <property name="title" />
    <property name="date" type="timestamp" column="EVENT_DATE" />      
 </class>

Person の POJO とそのマッピング:

public class Person {
        private Long id;
private int age;
private String firstname;
private String lastname;
private Set<Event> events = new HashSet<Event>();
    // setter & getter methods
}

<class name="Person" table="PERSON_NEW">
    <id name="id" column="PERSON_ID">
        <generator class="native" />
    </id>
    <property name="firstname" />
<property name="age" />
    <property name="lastname" />    
    <set name="events" table="PERSON_EVENTS">
        <key column="PERSON_ID" />
        <many-to-many column="EVENT_ID" class="Event" />
    </set>
</class>

イベント、人物を作成し、イベントを人物にマッピングするサンプル プログラム:

public class EventManager {

    public static void main(String[] args) {
        EventManager mgr = new EventManager();

        Long eventId = mgr.createAndStoreEvent("Hibernate");
        Long personId = mgr.createAndStorePerson("Smith");
        mgr.addPersonToEvent(personId, eventId);
        System.out.println("Added person " + personId + " to event " + eventId);
        HibernateUtil.getSessionFactory().close();
    }

    private Long createAndStoreEvent(String title) {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();

        Event theEvent = new Event();
        theEvent.setTitle(title);
        Long eventId = (Long) session.save(theEvent);
        session.getTransaction().commit();
        return eventId;
    }

    private Long createAndStorePerson(String firstName) {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        Person person = new Person();
        person.setFirstname(firstName);
        Long personId = (Long) session.save(person);
        session.getTransaction().commit();
        return personId;
    }

    private void addPersonToEvent(Long personId, Long eventId) {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();

        Person aPerson = (Person) session.load(Person.class, personId);
        Event anEvent = (Event) session.load(Event.class, eventId);
        aPerson.getEvents().add(anEvent);

        session.getTransaction().commit();
    }
}

このプログラムを実行すると、親キーが見つからないという例外を含むログが表示されます。

Hibernate: select hibernate_sequence.nextval from dual
Hibernate: insert into EVENTS (EVENT_DATE, title, EVENT_ID) values (?, ?, ?)
Hibernate: select hibernate_sequence.nextval from dual
Hibernate: insert into PERSON_NEW (age, firstname, lastname, PERSON_ID) values (?, ?, ?, ?)
Hibernate: select person0_.PERSON_ID as PERSON1_1_0_, person0_.age as age1_0_, person0_.firstname as firstname1_0_, person0_.lastname as lastname1_0_ from PERSON_NEW person0_ where person0_.PERSON_ID=?
Hibernate: select events0_.PERSON_ID as PERSON1_1_1_, events0_.EVENT_ID as EVENT2_2_1_, event1_.EVENT_ID as EVENT1_0_0_, event1_.EVENT_DATE as EVENT2_0_0_, event1_.title as title0_0_ from PERSON_EVENTS events0_, EVENTS event1_ where events0_.EVENT_ID=event1_.EVENT_ID and events0_.PERSON_ID=?
Hibernate: insert into PERSON_EVENTS (PERSON_ID, EVENT_ID) values (?, ?)
02:18:59,095  WARN SqlExceptionHelper:143 - SQL Error: 2291, SQLState: 23000
02:18:59,095 ERROR SqlExceptionHelper:144 - ORA-02291: integrity constraint (LEARNING.FK4A94943B0A1327A) violated - parent key not found

Exception in thread "main" org.hibernate.exception.ConstraintViolationException: ORA-02291: integrity constraint (LEARNING.FK4A94943B0A1327A) violated - parent key not found

    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:128)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129)

私は Hibernate 3.x を使用しています。このコードのどこで間違いを犯したか教えてください。私の Oracle データベースから、Event と Person のレコードは正常に保存されていることがわかりますが、このプログラムの実行中に例外が発生したため、結合テーブルは空です。

4

1 に答える 1

0

events setのマッピング ファイルのエントリを次のように変更する必要がありますPerson

<set name="events" table="PERSON_EVENTS" cascade="save-update">
        <key column="PERSON_ID" />
        <many-to-many column="EVENT_ID" class="Event" unique="true"/>
</set>

要素のunique="true"属性はmany-to-many、多重度を からmany-to-manyに変更しone-to-manyます。

またcascade="save-update"、推移的な永続性を実現するために使用されます。これにより、 のインスタンスを作成してinEventのセットに追加すると、とともに永続化されます。インターフェイスを呼び出して明示的に永続化する必要はありません。この属性は、が永続的な によって参照されている場合、インスタンスを永続化する (つまり、データベースに保存する) ようにHibernate に指示します。eventsPersonPersonEventsave()Sessioncascadenew EventEventPerson

Personこれらの変更を行うと、次のように一連の を保存できeventsます。

Event event = new Event();
event.setTitle(...);
event.setDate(...);

Set<Event> events = new HashSet<Event>();
events.add(event);

Person p = new Person();
p.setAge(...);
...
p.setEvents(events);

session.save(p);
于 2013-10-21T08:09:12.210 に答える