Embeddable in hibernate
Person table
|
|||||
Id
|
Bigint
|
||||
Name
|
Varchar
|
||||
Address
|
|
||||
jobType
|
Varchar
|
Observe the above table structure , we can easily persist
id,name,jobtype into person table.
But what about address attribute ?
Address is not having any basic datatype that java supports
and db supports.
Address is another class but it is composed inside person class.
So the way to save this address attribute inside person
table – we need to tell hibernate that
Please go to the address class and find all basic attributes
and put each of them in the person table.
So our solution looks something like this
Person table
|
|
Id
|
Bigint
|
Name
|
Varchar
|
Streetname
|
Varchar
|
City
|
Varchar
|
State
|
Varchar
|
pincode
|
Varchar
|
jobType
|
varchar
|
How to achive this in java using hibernate ?
Very simple – make the class address as embeddable .
And keep its reference in person class.
That’s it wow great.
Now when you persist person, your address class’s each attribute will go as a separate column inside
person table.
Observe carefully the below example.
Person class
package com.kb.model;
import
javax.persistence.Entity;
import
javax.persistence.GeneratedValue;
import
javax.persistence.Id;
import
javax.persistence.Table;
@Entity
@Table(name="PERSON_DETAILS")
public class Person {
@Id
@GeneratedValue
private long id;
private String name;
private Address address;
private String jobType;
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
getJobType() {
return jobType;
}
public void
setJobType(String jobType) {
this.jobType = jobType;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
Address class
package com.kb.model;
import javax.persistence.Column;
import javax.persistence.Embeddable;
@Embeddable
public class Address {
@Column(name="STREET_NAME")
private
String streetName;
@Column(name="CITY")
private
String city;
@Column(name="STATE")
private
String state;
@Column(name="PINCODE")
private
String pinCode;
public
String getStreetName() {
return
streetName;
}
public
void setStreetName(String streetName) {
this.streetName
= streetName;
}
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 getPinCode() {
return
pinCode;
}
public
void setPinCode(String pinCode) {
this.pinCode
= pinCode;
}
}
Client program
package com.kb.dao;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.kb.model.Address;
import com.kb.model.Person;
public class EmbeddedClient1 {
public
static void main(String[] args) {
Person person = new Person();
Address address = new Address();
address.setStreetName("maruti nagar");
address.setCity("bangalore");
address.setState("karnataka");
address.setPinCode("567891");
person.setName("kbc");
person.setJobType("Software");
person.setAddress(address);
//build session factory and get session
SessionFactory sessionFactory = new
Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
try {
session.beginTransaction();
session.save(person);
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
}
finally{
session.close();
}
}
}
output in mysql
Now what if we have collection of address inside person
class(like home address,office address,permanent address,temporary address)
Now assume we put all
the columns in person table then for same user all these addresses has to be in
person table. During that time, it becomes more redundancy as we need to show
each row with same user details for each different address which is not really
good.
The problem will become like this
Person table
|
||||||
Id
|
Name
|
Jobtype
|
Streetname
|
City
|
State
|
pincode
|
1
|
User1
|
Software
|
Infantry road
|
Bangalore
|
Karnataka
|
123456
|
1
|
User1
|
Software
|
Mg road
|
Bangalore
|
Karnataka
|
654321
|
For the same user 2 addresses and because of that user
information is redundant for each address information.
So if we have 100 such repetitive dependent object then 100
times user has to be duplicated in db.
So solution is separate the user and address as 2 tables and
put userid in address table to know that this
address belongs to this
particular user.
How can we achieve this in java using hibernate
Solution is very simple, just on top of collection element
declaration in person table , put this annotation
@ElementCollection.
See below code for complete example.
Person class
package com.kb.model;
import
java.util.ArrayList;
import java.util.List;
import
javax.persistence.ElementCollection;
import
javax.persistence.Entity;
import
javax.persistence.GeneratedValue;
import
javax.persistence.Id;
import
javax.persistence.Table;
@Entity
@Table(name="PERSON_DETAILS")
public class Person {
@Id
@GeneratedValue
private long id;
private String name;
@ElementCollection
private
List<Address> address = new ArrayList<Address>();
private String jobType;
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
getJobType() {
return jobType;
}
public void
setJobType(String jobType) {
this.jobType = jobType;
}
public
List<Address> getAddress() {
return address;
}
public void
setAddress(List<Address> address) {
this.address = address;
}
}
Address class
package com.kb.model;
import javax.persistence.Column;
import javax.persistence.Embeddable;
@Embeddable
public class Address {
@Column(name="STREET_NAME")
private
String streetName;
@Column(name="CITY")
private
String city;
@Column(name="STATE")
private
String state;
@Column(name="PINCODE")
private
String pinCode;
public
String getStreetName() {
return
streetName;
}
public
void setStreetName(String streetName) {
this.streetName
= streetName;
}
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 getPinCode() {
return
pinCode;
}
public
void setPinCode(String pinCode) {
this.pinCode
= pinCode;
}
}
Client program
package com.kb.dao;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.kb.model.Address;
import com.kb.model.Person;
public class EmbeddedClient1 {
public
static void main(String[] args) {
Person person = new Person();
Address address = new Address();
address.setStreetName("maruti nagar");
address.setCity("bangalore");
address.setState("karnataka");
address.setPinCode("567891");
person.setName("kbc");
person.setJobType("Software");
Address address1 = new Address();
address1.setStreetName("maruti nagar1");
address1.setCity("bangalore1");
address1.setState("karnataka1");
address1.setPinCode("567891new");
person.getAddress().add(address);
person.getAddress().add(address1);
//build session factory and get session
SessionFactory sessionFactory = new
Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
try {
session.beginTransaction();
session.save(person);
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
}
finally{
session.close();
}
}
}
output in mysql