简体   繁体   中英

Hibernate One To Many

I am doing for one to many mapping with no success. My schema is as follows

Event (one) ----> Message (many)

The Get/Set message function in Event File:

@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;
    }
}

The Get/Set message function in Message File:

@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;
    }
}

And Hibernate Configuration File:

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

After Executing following 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();
        }

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

Any suggestions?

Try the following code. Seems like you are getting a 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();
    }

You have to add it to every Entity that uses Property-Access means @ManyToOne(fetch = FetchType.LAZY) on top of a method-signature like you did. And do add the serial number.

@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;

}

You can have @Access(AccessType.PROPERTY) or @Access(AccessType.Field) the difference is, where you annotate the @ManyToOne (@OneToMany, @OneToOne). Property-access means you set those annotations on top of the method signature. Field-access means you set in on top of the field it self.

like:

@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
}

The imports:

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

As someone mentioned you may get a 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();
    }

If you want it saved cascading:

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

Based on SWiggels said: btw you save your event twice but you never save your message – SWiggels

I modified my code to:

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

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

Finally get the right result. Thanks to SWiggels !

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

Because you are not persisting the testMessage object.

Why are you persisting the event object twice? Shouldn't you be persisting the testMessage object.

        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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM