Thursday, 2 August 2012

One to many mapping using bidirectional relationship– ManytoOne as owner

First let is look the hibernate documentation on this as follows

One to many association is annotated by @OneToMany(mappedBy=...).    Here is the documentation link

@Entity
public class Troop {
@OneToMany(mappedBy="troop")
public Set<Soldier> getSoldiers() {
...
}

@Entity
public class Soldier {
@ManyToOne
@JoinColumn(name="troop_fk")
public Troop getTroop() {
...
}


Troop has a bidirectional one to many relationship with Soldier through the troop property. You don't have to (must not) define any physical mapping in the mappedBy side.


In bi-directional mapping, the parent table can be retrieved by the child table and the child table can be retrieved by the parent table. Means retrieval can be done in both direction or bi-directional. That's why we call it bi-directional mapping.


Some examples


There are two table WRITER and STORY. One writer can write multiple stories. So the relation is one-to-many . Using bi-directional relation, From WRITER object you can get bag of Stories and from story object you can get writer object.


Now let us goto our example.


In this example, we will see many to one as owning side i.e on the detail side.  As per this example,
department is not the owner, where as employee is the owner.


Step : 1
In mysql , create the table as shown
image


Step : 2


Let us set the environment. Follow this post to set up Hibernate with java in eclipse IDE.


Step : 3


Let us create Beans as follows


package domain;


import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.OneToMany;
@Entity
@Table(name = "department")
public class Department {

@Id
@GeneratedValue
@Column(name = "ID")
private int ID;

@Column(name = "DepartName")
private String departName;


/**
mappedBy – means “I am not the owner side”, I am mapped by Employee from the other side of the relationship.
It will also not create the database column which makes sense, I would expect a foreign key on the Employee table instead.
Here we have used department as mapped by, so there must be property on the Employee Class.

Department has a bidirectional one to many relationship with Employee through the department property.
You don't have to (must not) define any physical mapping in the mappedBy side.

orphanRemoval=true is used because, even though we specified cascadetype all, but if only child records are deleted,
then when you save the master, the child will not delete. for this, we have used orphanRemoval=true.

**/

@OneToMany(fetch=FetchType.EAGER, cascade = CascadeType.ALL, mappedBy="department", orphanRemoval=true)
List<Employees> employees;

public int getID() {
return ID;
}

public void setID(int iD) {
ID = iD;
}

public String getDepartName() {
return departName;
}

public void setDepartName(String departName) {
this.departName = departName;
}

public List<Employees> getEmployees() {
return employees;
}

public void setEmployees(List<Employees> employees) {
this.employees = employees;
}



}

Employees



 

package domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.ManyToOne;
import javax.persistence.JoinColumn;


@Entity
@Table(name = "employees")
public class Employees {

@Id
@GeneratedValue
private int ID;
@Column(name = "firstName")
private String firstName;

@Column(name = "lastName")
private String lastName;

@ManyToOne
@JoinColumn(name="DepartmentID")
private Department department;

public int getID() {
return ID;
}

public void setID(int iD) {
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 Department getDepartment() {
return department;
}

public void setDepartment(Department department) {
this.department = department;
}

}


hibernate.cfg.xml


<?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/sampledb</property>
<property name="connection.username">root</property>
<property name="connection.password">123</property>

<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>

<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>

<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>



<!-- Mapping Classes -->
<mapping class="domain.Department" />
<mapping class="domain.Employees" />

</session-factory>
</hibernate-configuration>

Test Class

package test;

import java.util.ArrayList;
import java.util.List;
import org.hibernate.Session;
import domain.*;
import HibernateUtilities.*;

public class Test {

public static void main(String[] args) {

addNewMasterAndDetail();
//updateOnlyMaster();
//deleteMaster();
//updateonlyDetail();
//deleteOnlyDetail();

}

public static void addNewMasterAndDetail()
{
// Now let us create Department
Department d1 = new Department();
d1.setDepartName("Accounts");

// Now let us some employees
List<Employees> empList = new ArrayList<Employees>();
Employees e1 = new Employees();

e1.setFirstName("John");
e1.setFirstName("Mike");
e1.setDepartment(d1);
empList.add(e1);

e1 = new Employees();
e1.setFirstName("Smith");
e1.setFirstName("Robert");
e1.setDepartment(d1);
empList.add(e1);

d1.setEmployees(empList);

Session session = HibernateUtil.beginTransaction();
session.save(d1);
HibernateUtil.CommitTransaction();

}

public static void updateOnlyMaster()
{
//Now Let us update the master alone i.e Department
Session session = HibernateUtil.beginTransaction();
Department d2 = (Department) session.createQuery("from Department where id = 1").uniqueResult();
d2.setDepartName("Accounts Modified");
session.save(d2);
HibernateUtil.CommitTransaction();
}

public static void deleteMaster()
{
//Now Let us update the master alone i.e Department
Session session = HibernateUtil.beginTransaction();
Department d2 = (Department) session.createQuery("from Department where id = 1").uniqueResult();
session.delete(d2);
HibernateUtil.CommitTransaction();
}

public static void updateonlyDetail()
{
//Now Let us update the master alone i.e Department
Session session = HibernateUtil.beginTransaction();
Department d2 = (Department) session.createQuery("from Department where id = 2").uniqueResult();
d2.getEmployees().get(0).setFirstName("changed first name");
session.save(d2);
HibernateUtil.CommitTransaction();
}

public static void deleteOnlyDetail()
{
//Now Let us update the master alone i.e Department
Session session = HibernateUtil.beginTransaction();
Department d2 = (Department) session.createQuery("from Department where id = 2").uniqueResult();
d2.getEmployees().clear();
session.saveOrUpdate(d2);
HibernateUtil.CommitTransaction();
}
}


Now you can run test.java as java application.


Project Structure.


image


 


 




 


 



 

 

 



 



 



 

 

No comments:

Post a Comment