Friday 26 December 2014

Hibernate : many to one mapping

In previous post we have seen one-to-many mapping. In previous example, we have seen one employee object associated with multiple address objects. Many-to-one is exactly opposite to one-to-many like many address objects are associated with one employee object.

package myFirstHibernate;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

@Entity
public class Address {
 @Id @GeneratedValue
 private int id;
 private String street;
 private String city;
 private String state;
 private String PIN;
 private String country;
 
 @ManyToOne(cascade=CascadeType.ALL)
 private Employee emp;
 
 public Employee getEmp() {
  return emp;
 }

 public void setEmp(Employee emp) {
  this.emp = emp;
 }

 public int getId() {
  return id;
 }
 
 public void setId(int id) {
  this.id = id;
 }
 
 public String getStreet() {
  return street;
 }
 
 public void setStreet(String street) {
  this.street = street;
 }
 
 public String getCity() {
  return city;
 }
 
 public void setCity(String city) {
  this.city = city;
 }
 
 public String getState() {
  return state;
 }
 
 public void setState(String state) {
  this.state = state;
 }
 
 public String getPIN() {
  return PIN;
 }
 
 public void setPIN(String pIN) {
  PIN = pIN;
 }
 
 public String getCountry() {
  return country;
 }
 
 public void setCountry(String country) {
  this.country = country;
 }
 
}

package myFirstHibernate;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.JoinColumn;

@Entity
public class Employee {
 @Id @GeneratedValue
 private int id;
 private String firstName;
 private String lastName;
 
 @OneToMany(cascade=CascadeType.ALL)
 @JoinTable(
   name = "emp_address_mapping",
            joinColumns = @JoinColumn(name = "emp_id"),
            inverseJoinColumns = @JoinColumn(name = "address_id")
   )
 List<Address> addresses = new ArrayList<Address> ();

 public int getId() {
  return id;
 }

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

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public List<Address> getAddresses() {
  return addresses;
 }

 public void setAddresses(List<Address> addresses) {
  this.addresses = addresses;
 }
 
}
 

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>

  <session-factory>
  
   <!--  Database Connection settings -->
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="connection.url">jdbc:mysql://localhost/sample</property>
    <property name="connection.username">root</property>
    <property name="connection.password">tiger</property>
    
    <!-- Enable the logging of all the generated SQL statements to the console -->
    <property name="show_sql">true</property>
    
    <!-- Format the generated SQL statement to make it more readable, -->
    <property name="format_sql">false</property>
    
    <!-- Hibernate will put comments inside all generated SQL statements to hint what’s the generated SQL trying to do -->
    <property name="use_sql_comments">false</property>
    
    <!-- This property makes Hibernate generate the appropriate SQL for the chosen database. -->
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    
    <!-- Drop and re-create the database schema on startup -->
    <property name="hbm2ddl.auto">create</property>
    
    <!-- mappings for annotated classes -->
    <mapping class="myFirstHibernate.Employee" />
    <mapping class="myFirstHibernate.Address" />
    
  </session-factory>
  
</hibernate-configuration>

package myFirstHibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;

public class TestEmployee {
 
 /* Step 1: Create session factory */
 private static SessionFactory getSessionFactory() {
  Configuration configuration = new Configuration().configure();
  StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().
  applySettings(configuration.getProperties());
  SessionFactory factory = configuration.buildSessionFactory(builder.build());
        return factory;
    }
 
 public static void main(String args[]){
  Employee emp1 = new Employee();
  
  emp1.setFirstName("Hari Krishna");
  emp1.setLastName("Gurram");
  
  Address addr1 = new Address();
  addr1.setCity("Bangalore");
  addr1.setCountry("India");
  addr1.setPIN("560037");
  addr1.setState("Karnataka");
  addr1.setStreet("Chowdeswari street");
  addr1.setEmp(emp1);
   
  Address addr2 = new Address();
  addr2.setCity("Ongole");
  addr2.setCountry("India");
  addr2.setPIN("523169");
  addr2.setState("Andhra Pradesh");
  addr2.setStreet("Punuru");
  addr2.setEmp(emp1);
  
  emp1.getAddresses().add(addr1);
  emp1.getAddresses().add(addr2);

  
  /* To persist data */
  SessionFactory sessionFactory = getSessionFactory();
  Session session = sessionFactory.openSession();
  session.beginTransaction();
  session.save(emp1);
  session.getTransaction().commit();
  session.close(); 
  
 }
}

Run TestEmployee class, you will get output like below.
Hibernate: drop table if exists Address
Hibernate: drop table if exists Employee
Hibernate: drop table if exists emp_address_mapping
Hibernate: create table Address (id integer not null auto_increment, PIN varchar(255), city varchar(255), country varchar(255), state varchar(255), street varchar(255), emp_id integer, primary key (id))
Hibernate: create table Employee (id integer not null auto_increment, firstName varchar(255), lastName varchar(255), primary key (id))
Hibernate: create table emp_address_mapping (emp_id integer not null, address_id integer not null)
Hibernate: alter table emp_address_mapping add constraint UK_h4s1v5ws5cxqr3eqd5sggdm9v  unique (address_id)
Hibernate: alter table Address add constraint FK_482g3bhbkhv2cgytyefllyg2l foreign key (emp_id) references Employee (id)
Hibernate: alter table emp_address_mapping add constraint FK_h4s1v5ws5cxqr3eqd5sggdm9v foreign key (address_id) references Address (id)
Hibernate: alter table emp_address_mapping add constraint FK_56nsddme9y6h8uu4kcb127sas foreign key (emp_id) references Employee (id)
Dec 21, 2014 2:16:40 PM org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: HHH000230: Schema export complete
Hibernate: insert into Employee (firstName, lastName) values (?, ?)
Hibernate: insert into Address (PIN, city, country, emp_id, state, street) values (?, ?, ?, ?, ?, ?)
Hibernate: insert into Address (PIN, city, country, emp_id, state, street) values (?, ?, ?, ?, ?, ?)
Hibernate: insert into emp_address_mapping (emp_id, address_id) values (?, ?)
Hibernate: insert into emp_address_mapping (emp_id, address_id) values (?, ?)

MySQL tables looks like below.
mysql> select * from address;
+----+--------+-----------+---------+----------------+--------------------+--------+
| id | PIN    | city      | country | state          | street             | emp_id |
+----+--------+-----------+---------+----------------+--------------------+--------+
|  1 | 560037 | Bangalore | India   | Karnataka      | Chowdeswari street |      1 |
|  2 | 523169 | Ongole    | India   | Andhra Pradesh | Punuru             |      1 |
+----+--------+-----------+---------+----------------+--------------------+--------+
2 rows in set (0.00 sec)

mysql> select * from employee;
+----+--------------+----------+
| id | firstName    | lastName |
+----+--------------+----------+
|  1 | Hari Krishna | Gurram   |
+----+--------------+----------+
1 row in set (0.00 sec)

mysql> select * from emp_address_mapping;
+--------+------------+
| emp_id | address_id |
+--------+------------+
|      1 |          1 |
|      1 |          2 |
+--------+------------+
2 rows in set (0.00 sec)

mysql> describe employee;
+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| id        | int(11)      | NO   | PRI | NULL    | auto_increment |
| firstName | varchar(255) | YES  |     | NULL    |                |
| lastName  | varchar(255) | YES  |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

mysql> describe address;
+---------+--------------+------+-----+---------+----------------+
| Field   | Type         | Null | Key | Default | Extra          |
+---------+--------------+------+-----+---------+----------------+
| id      | int(11)      | NO   | PRI | NULL    | auto_increment |
| PIN     | varchar(255) | YES  |     | NULL    |                |
| city    | varchar(255) | YES  |     | NULL    |                |
| country | varchar(255) | YES  |     | NULL    |                |
| state   | varchar(255) | YES  |     | NULL    |                |
| street  | varchar(255) | YES  |     | NULL    |                |
| emp_id  | int(11)      | YES  | MUL | NULL    |                |
+---------+--------------+------+-----+---------+----------------+
7 rows in set (0.01 sec)

mysql> describe emp_address_mapping;
+------------+---------+------+-----+---------+-------+
| Field      | Type    | Null | Key | Default | Extra |
+------------+---------+------+-----+---------+-------+
| emp_id     | int(11) | NO   | MUL | NULL    |       |
| address_id | int(11) | NO   | PRI | NULL    |       |
+------------+---------+------+-----+---------+-------+
2 rows in set (0.01 sec)

As you closely observe, we really don’t need table “emp_address_mapping”. Change classes Address, Employee like below, and re run TestEmployee class.

package myFirstHibernate;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

@Entity
public class Address {
 @Id @GeneratedValue
 private int id;
 private String street;
 private String city;
 private String state;
 private String PIN;
 private String country;
 
 @ManyToOne(cascade=CascadeType.ALL)
 @JoinColumn(name="emp_id")
 private Employee emp;
 
 public Employee getEmp() {
  return emp;
 }

 public void setEmp(Employee emp) {
  this.emp = emp;
 }

 public int getId() {
  return id;
 }
 
 public void setId(int id) {
  this.id = id;
 }
 
 public String getStreet() {
  return street;
 }
 
 public void setStreet(String street) {
  this.street = street;
 }
 
 public String getCity() {
  return city;
 }
 
 public void setCity(String city) {
  this.city = city;
 }
 
 public String getState() {
  return state;
 }
 
 public void setState(String state) {
  this.state = state;
 }
 
 public String getPIN() {
  return PIN;
 }
 
 public void setPIN(String pIN) {
  PIN = pIN;
 }
 
 public String getCountry() {
  return country;
 }
 
 public void setCountry(String country) {
  this.country = country;
 }
 
}

package myFirstHibernate;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;

@Entity
public class Employee {
 @Id @GeneratedValue
 private int id;
 private String firstName;
 private String lastName;
 
 @OneToMany(cascade=CascadeType.ALL, mappedBy="emp")
 List<Address> addresses = new ArrayList<Address> ();

 public int getId() {
  return id;
 }

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

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public List<Address> getAddresses() {
  return addresses;
 }

 public void setAddresses(List<Address> addresses) {
  this.addresses = addresses;
 }
 
}

Re run TestEmployee class, you will get output like below.
Hibernate: drop table if exists Address
Hibernate: drop table if exists Employee
Hibernate: create table Address (id integer not null auto_increment, PIN varchar(255), city varchar(255), country varchar(255), state varchar(255), street varchar(255), emp_id integer, primary key (id))
Hibernate: create table Employee (id integer not null auto_increment, firstName varchar(255), lastName varchar(255), primary key (id))
Hibernate: alter table Address add constraint FK_482g3bhbkhv2cgytyefllyg2l foreign key (emp_id) references Employee (id)
Dec 21, 2014 2:33:20 PM org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: HHH000230: Schema export complete
Hibernate: insert into Employee (firstName, lastName) values (?, ?)
Hibernate: insert into Address (PIN, city, country, emp_id, state, street) values (?, ?, ?, ?, ?, ?)
Hibernate: insert into Address (PIN, city, country, emp_id, state, street) values (?, ?, ?, ?, ?, ?)

As you observe output, it creates only two tables Employee, Address. There is no mapping table.



Prevoius                                                 Next                                                 Home

No comments:

Post a Comment