hibernate

Hibernate tutorial: One to one and Many to many mapping annotation

This post about hibernate tutorial i will show how to implement many to many and one to one mapping in hibernate using JPA annotation. We will using source code from previous post Hibernate tutorial: one-to-many mapping annotation as code base for this article.

1. Project import

Click on this link to download source code and import to eclipse IDE. And we will update code from this source code.

2. Entity Relationship diagram(ERD)

Below is ERD of this tutorial. Each User will have only one a Profile and versa each profile belong to only one user. And each user has many roles and each role can belong to many users.

schema

3. Model

We create two new entities: Profile and Role and put follow code
Profile

@Entity(name = "profiles")
public class Profile implements Serializable{
  /**
   * 
   */
  private static final long serialVersionUID = -3643249555458092568L;
  private Long id;
  private User user;
  private String street1;
  private String street2;
  private String city;
  private String country;
  private String mobile;
  private String zipcode;

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  @OneToOne
  @JoinColumn(name="user_id",unique=true)
  public User getUser() {
    return user;
  }

  public void setUser(User user) {
    this.user = user;
  }

  public String getStreet1() {
    return street1;
  }

  public void setStreet1(String street1) {
    this.street1 = street1;
  }

  public String getStreet2() {
    return street2;
  }

  public void setStreet2(String street2) {
    this.street2 = street2;
  }

  public String getCity() {
    return city;
  }

  public void setCity(String city) {
    this.city = city;
  }

  public String getCountry() {
    return country;
  }

  public void setCountry(String country) {
    this.country = country;
  }

  public String getMobile() {
    return mobile;
  }

  public void setMobile(String mobile) {
    this.mobile = mobile;
  }

  public String getZipcode() {
    return zipcode;
  }

  public void setZipcode(String zipcode) {
    this.zipcode = zipcode;
  }

}

Role

@Entity(name = "roles")
public class Role implements Serializable {

  /**
   * 
   */
  private static final long serialVersionUID = 331927881086337827L;
  private Long id;
  private String name;
  private String description;
  private String status;
  private Set users;

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getDescription() {
    return description;
  }

  public void setDescription(String description) {
    this.description = description;
  }

  public String getStatus() {
    return status;
  }

  public void setStatus(String status) {
    this.status = status;
  }

  @ManyToMany(fetch = FetchType.LAZY)
  @JoinTable(name = "roles_users", joinColumns = @JoinColumn(name = "role_id"), inverseJoinColumns = @JoinColumn(name = "user_id"), uniqueConstraints = { @UniqueConstraint(columnNames = {
      "role_id", "user_id" }) })
  public Set getUsers() {
    if (users == null) {
      users = new HashSet();
    }
    return users;
  }

  public void setUsers(Set users) {
    this.users = users;
  }

}

Update User as below:

@Entity(name = "users")
public class User implements Serializable {
  /**
   * 
   */
  private static final long serialVersionUID = 7292222119906752946L;
  private Long id;
  private String username;
  private String password;
  private Date crtDate;
  private Profile profile;
  private Set histories;
  private Set roles;

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getUsername() {
    return username;
  }

  public void setUsername(String username) {
    this.username = username;
  }

  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  @Column(name = "create_date")
  @Temporal(TemporalType.TIMESTAMP)
  public Date getCrtDate() {
    return crtDate;
  }

  public void setCrtDate(Date crtDate) {
    this.crtDate = crtDate;
  }

  @OneToOne(optional = false, mappedBy = "user",cascade=CascadeType.ALL)
  public Profile getProfile() {
    return profile;
  }

  public void setProfile(Profile profile) {
    this.profile = profile;
  }

  @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
  public Set getHistories() {
    if (histories == null) {
      histories = new HashSet();
    }
    return histories;
  }

  public void setHistories(Set histories) {
    this.histories = histories;
  }

  @ManyToMany(mappedBy = "users", cascade = CascadeType.PERSIST)
  public Set getRoles() {
    if (roles == null) {
      roles = new HashSet();
    }
    return roles;
  }

  public void setRoles(Set roles) {
    this.roles = roles;
  }

}

4. Hibernate configuration

We need update hibernate configuration so hibernate can know about new entities

<hibernate-configuration>
 <session-factory>
  <property name="hibernate.hbm2ddl.auto">update</property>
  <property name="hibernate.connection.password">admin</property>
  <property name="hibernate.connection.username">root</property>
  <property name="connection.url">jdbc:mysql://localhost/tutorial?autoReconnect=true</property>
  <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
  <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
  <property name="hibernate.show_sql">true</property>
  <mapping class="com.devjav.tutorial.hibernate.entity.User"/>
  <mapping class="com.devjav.tutorial.hibernate.entity.LoginHistory"/>
  <mapping class="com.devjav.tutorial.hibernate.entity.Profile"/>
  <mapping class="com.devjav.tutorial.hibernate.entity.Role"/>
 </session-factory>
</hibernate-configuration>

5. Application Entry

We update main function onApp

public class App {

  /**
   * @param args
   */
  public static void main(String[] args) {
    Session session = null;
    Transaction txn = null;
    try {
      session = HibernateUtil.openSession();
      User user = new User();
      user.setCrtDate(new Date());
      user.setUsername("thinhpt");
      user.setPassword("123456");
      Profile profile= new Profile();
      profile.setCity("Hanoi");
      profile.setCountry("Vietnam");
      profile.setMobile("9934934343");
      profile.setStreet1("dsadsa");
      profile.setStreet2("dsadsadsad");
      profile.setUser(user);
      profile.setZipcode("10000");
      user.setProfile(profile);
      Role role = new Role();
      role.setName("Administrator");
      role.setDescription("Adminstrator of application");
      role.setStatus("Active");
      role.getUsers().add(user);
      user.getRoles().add(role);
      txn = session.beginTransaction();
      session.persist(user);
      txn.commit();
    } catch (Exception ex) {
      ex.printStackTrace();
      if (txn != null) {
        txn.rollback();
        txn = null;
      }
    } finally {
      if (session != null) {
        session.close();
        session = null;
      }
      HibernateUtil.release();
    }

  }

}

6. Run application

Run this application and it will insert a record users,profiles,roles,roles_users table

Hibernate: insert into profiles (city, country, mobile, street1, street2, user_id, zipcode) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into users (create_date, password, username) values (?, ?, ?)
Hibernate: insert into roles (description, name, status) values (?, ?, ?)
Hibernate: update profiles set city=?, country=?, mobile=?, street1=?, street2=?, user_id=?, zipcode=? where id=?
Hibernate: insert into roles_users (role_id, user_id) values (?, ?)

7. Source code

You can download source code on this link

Leave a Reply