0

我是 Hibernate 的新手,我正在尝试在我的 POJO 类 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>

POJO for Person 及其映射:

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>

其中element的unique="true"属性将多重性从 更改为。many-to-manymany-to-manyone-to-many

cascade="save-update"用于实现传递持久化;有了这个,当您创建一个实例Event并将其添加到 in 的集合中eventsPerson,它将与Person. 您不必Event通过调用接口save()来显式地进行持久化。Sessioncascade属性告诉 Hibernate 使任何new Event实例持久化(即,将其保存在数据库中)如果Event被持久性引用Person

完成这些更改后,您可以保存一个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 回答