休眠一对多

Hibernate One To Many

我正在做一对多映射,但没有成功。我的架构如下

事件(一)---->留言(多)

事件文件中的Get/Set消息函数:

@Entity
@Table(name = "event", schema = "public")
@SuppressWarnings("serial")
public class Event implements java.io.Serializable {
    ...
    ....    
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "event")
    public Set<Message> getMessages() {
    return this.messages;
    }

    public void setMessages(Set<Message> messages) {
    this.messages = messages;
    }
}

消息文件中的Get/Set消息函数:

@Entity
@Table(name = "message", schema = "public")
@SuppressWarnings("serial")
public class Message implements java.io.Serializable {
    ...
    ....
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "event_id", nullable = false)
    public Event getEvent() {
            return this.event;
    }

    public void setEvent(Event event) {
            this.event = event;
    }
}

和 Hibernate 配置文件:

...
<mapping class="org.itri.ccma.paas.hibernate.Event" />
<mapping class="org.itri.ccma.paas.hibernate.Message" />

执行后 BoEvent.java

...
Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();

            Event event = new Event();
            session.save(event);

            Set<Message> Messagess = new HashSet<Message>();

            Message testMessage = new Message();
            testMessage.setEvent(event);

            event.getMessages().add(testMessage);
            session.save(event);
            tx.commit();

        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();


        } finally {
            session.close();
        }

我的消息table中没有记录,但事件table是可以的。 我想我的代码中遗漏了一些东西

有什么建议吗?

试试下面的代码。好像你得到了 NullPointerException.

    Session session = HibernateUtil.getSessionFactory().openSession();
    Transaction tx = null;
    try {
        tx = session.beginTransaction();

        Event event = new Event();
        session.save(event);

        Set<Message> messages = new HashSet<Message>();

        Message testMessage = new Message();
        testMessage.setEvent(event);

        messages.add(testMessage); // This
        event.setMessages(messages); // This
        session.save(event);
        tx.commit();

    } catch (Exception e) {
        e.printStackTrace();
        tx.rollback();


    } finally {
        session.close();
    }

您必须将它添加到每个使用 属性 的实体中-访问意味着 @ManyToOne(fetch = FetchType.LAZY) 在方法签名之上,就像您所做的那样。并添加序列号。

@Entity
@Table(name = 'message')
@Access(AccessType.PROPERTY)
public class Message extends BusinessEntity {

private static final long serialVersionUID = 1L;

}

@Entity
@Table(name = 'event')
@Access(AccessType.PROPERTY)
public class Event extends BusinessEntity {

private static final long serialVersionUID = 1L;

}

你可以有 @Access(AccessType.PROPERTY)@Access(AccessType.Field) 不同的是,你在哪里注释 @ManyToOne(@OneToMany, @OneToOne)。 属性-access 意味着您将这些注释设置在方法签名之上。 Field-access 意味着您在它自己的字段之上进行设置。

赞:

@Entity
@Table(name = 'event')
@Access(AccessType.PROPERTY)
public class Event extends BusinessEntity {

private static final long serialVersionUID = 1L;

private Message message;

@ManyToOne
public Message getMessage(){ return message;}
//setter
}

@Entity
@Table(name = 'event')
@Access(AccessType.Field)
public class Event extends BusinessEntity {

private static final long serialVersionUID = 1L;

@ManyToOne
private Message message;

public Message getMessage(){ return message;}
//setter
}

进口:

 import javax.persistence.Access;
 import javax.persistence.AccessType;
 import javax.persistence.Entity;
 import javax.persistence.Table;

正如有人提到的,您可能会获得 NPE:

 Session session = HibernateUtil.getSessionFactory().openSession();
    Transaction tx = null;
    try {
        tx = session.beginTransaction();

        Event event = new Event();
        session.save(event);

        Message testMessage = new Message();
        testMessage.setEvent(event);
        event.setMessages(new HashSet<Message>());  //the list was not initialized.
        event.getMessages().add(testMessage);
        session.save(event);
        tx.commit();

    } catch (Exception e) {
        e.printStackTrace();
        tx.rollback();


    } finally {
        session.close();
    }

如果你想保存级联:

  @ManyToOne
  @Cascade( { org.hibernate.annotations.CascadeType.ALL } )
  public Message getMessage(){ return message;}

基于 SWiggels 说: 顺便说一句,你保存了两次你的活动,但你从未保存过你的消息 – SWiggels

我将代码修改为:

...
...
   Message testMessage = new Message();
   testMessage.setEvent(event);
   event.getMessages().add(testMessage);

   session.save(testMessage); // Here I modified
   tx.commit();

终于得到正确的结果。感谢 SWiggels !

There is no record in my Message table but event table is OK. I think I am missing something in my code

因为您没有持久化 testMessage 对象。

为什么要持久化事件对象两次?你不应该坚持 testMessage 对象。

        Event event = new Event();
        session.save(event);

        Set<Message> Messagess = new HashSet<Message>();

        Message testMessage = new Message();
        testMessage.setEvent(event);

        event.getMessages().add(testMessage);
        session.save(testMessage);  //save testMessage rather than event
        tx.commit();