Pages Navigation Menu

Coding is much easier than you think

Value object & Entity object in Hibernate mapping

So far we have learnt how to write a model object and we learnt to annotate a model object so that hibernate create a table for us, then we learnt how to save, retrieve, update and delete the entity object in the database.
 
Hibrenet-
 
Still now we have created the entity class based on the assumption that each member variable inside the entity class will have a single column in database.
 
In Above table the type of fields of the class STUDENT CLASS is as below.

              ID            is INTEGER type
              Name          is VARCHAR type
              DEPARTMENT    is VARCHAR type
              ADDRESS       is VARCHAR type
              COLLEGE       is VARCHAR type

Now what if one of these member variable is an object instead of a simple data type. For example
 
Hibrenet-intro
 
Here STUDENT CLASS have a field Address object, this means in the database there are no meaning for Address object, as this Address object in turn have four other fields like.

1. Street
2. City
3. State
4. Pin code

Now the question is how can we save this address object into the database.
 

Value object

 
One way of saving the Address Object is to treat the member variable of address objects as the member variable of Student object itself.
 
Hibrenet-introduction
 
Here without having a Student object the use of Address object doesn’t make any sense. So the purpose of address object is just provide value to the Student object; And this is what differentiate an Entity object from a Value object.
 

So what the heck is Value object?

 
Entity object is the one which have meaning on its own, where a value object has no meaning on its own, the value object belongs to an entity instance and its persistent state is embedded in the table row of the owning entity.
In the above example the Student object represents an Entity object and Address object represents a Value object.
 

Long story short here:

 
Entity Object: Has its own database identity (Student table)
Value Object: Doesn’t not have its own database identity
 
Now let’s create an class for Address (Value object)
 

package entity;

import javax.persistence.Column;
import javax.persistence.Embeddable;

@Embeddable
public class Address {
	@Column(name = "STREET_NAME")
	private String street;
	@Column(name = "CITY_NAME")
	private String city;
	@Column(name = "STATE_NAME")
	private String state;
	@Column(name = "PIN_CODE")
	private String pincode;
        
        // Create getters and setters
}

 
Now in order to make this class of value type, and in order to tell hibernate not to create a separate table for address class, I have used @Embeddable annotation in the Address class, Also we need to use @Embedded annotation in the member variable of Address object in Student entity class as shown below.
 

package entity;

import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "STUDENT")
public class Student {

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

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

	@Column(name = "DEPARTMENT")
	private String department;

	@Column(name = "COLLEGE")
	private String college;

	// For value type object
	@Embedded
	private Address address;

       // Getters and Setters
}

 

Hibernate Configuration file

 
File: hibernate.cfg.xml

<hibernate-configuration>
<session-factory>
	<!-- Database connection settings -->
	<property name="hibernate.connection.driver_class">
                 oracle.jdbc.driver.OracleDriver
        </property>
	<property name="hibernate.connection.username">system</property>
	<property name="hibernate.connection.password">admin</property>
	<property name="hibernate.connection.url">
                jdbc:oracle:thin:@127.0.0.1:1521:XE
        </property>

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

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

	<!-- Drop and re-create the database schema on startup -->
	<property name="hibernate.hbm2ddl.auto">create</property>
	<!-- Map Entity Class -->
    <mapping class="entity.Student"></mapping>

</session-factory>

</hibernate-configuration>

 

HibernateTest class

 
Create the Main class to run the example.

package util;

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

import entity.Address;
import entity.Student;

public class HibernateUtil {

	public static void main(String[] args) {

		Configuration cf = new Configuration().configure("hibernate.cfg.xml");

		StandardServiceRegistryBuilder srb = 
                         new StandardServiceRegistryBuilder();
		srb.applySettings(cf.getProperties());
		ServiceRegistry sr = srb.build();
		SessionFactory sf = cf.buildSessionFactory(sr);

		Session session = sf.openSession();
		Transaction tx = session.beginTransaction();

		Student student = new Student(); 

		student.setName("Lahir Nisha");
		student.setDepartment("ECE");
		student.setCollege("SKCET");

		Address address1 = new Address();
		address1.setStreet("Race cource");
		address1.setCity("Coimbatore");
		address1.setState("Tamilnadu");
		address1.setPincode("642001");
		student.setAddress(address1);
                session.save(student);  

		tx.commit(); 
		session.close();
		sf.close();
	}
}

 

Run it – Eclipse Console

 
Vlue object
 

Database Output

 
Vlue object saving
 

@AttributeOverride annotation:

 
So far we have seen that an Entity Type Object Student has a Value Object(or Embeddable Object ) ADDRESS with corresponding fields name street, city, pin-code and state save to the database table STUDENT with value object’s column name (CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME).
 
Suppose in the above scenario if a Student have two addresses like Local Address and Permanent Address then how to manage the column names of these two value objects in the database table STUDENT.
 
In order to overcome this problem, we have to override the Attribute name of the Value objects. Hibernate has provided @AttributeOverride annotation for this purpose.
 
Example:-

Student.java

 

package entity;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "STUDENT")
public class Student {

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

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

	@Column(name = "DEPARTMENT")
	private String department;

	@Column(name = "COLLEGE")
	private String college;

	@Column(name = "ADDRESS")
	@Embedded
	@AttributeOverrides({
	   @AttributeOverride(name = "street", column = @Column(name = "HOME_STREET_NAME")),
	   @AttributeOverride(name = "city", column = @Column(name = "HOME_CITY_NAME")),
	   @AttributeOverride(name = "state", column = @Column(name = "HOME_STATE_NAME")),
	   @AttributeOverride(name = "pincode", column = @Column(name = "HOME_PIN_CODE")) })
	private Address homeAddress;

	@Embedded
	private Address permanentAddress;
        // Create getters and setters 
}

 

HibernateTest class

 
Create the Main class to run the example.

package util;

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

import entity.Address;
import entity.Student;

public class HibernateUtil {

	public static void main(String[] args) {

		Configuration cf = new Configuration().configure("hibernate.cfg.xml");

		StandardServiceRegistryBuilder srb 
                             = new StandardServiceRegistryBuilder();
		srb.applySettings(cf.getProperties());
		ServiceRegistry sr = srb.build();
		SessionFactory sf = cf.buildSessionFactory(sr);

		Session session = sf.openSession();
		Transaction tx = session.beginTransaction();
		
		Address homeAddress = new Address(); 
		homeAddress.setStreet("Race cource");
		homeAddress.setCity("Coimbatore");
		homeAddress.setState("Tamilnadu");
		homeAddress.setPincode("642001");
		
		Address permanantAddress = new Address();
		permanantAddress.setStreet("Besant nagar");
		permanantAddress.setCity("Chennai");
		permanantAddress.setState("Tamilnadu");
		permanantAddress.setPincode("600001");
		
		Student student = new Student(); 

		student.setName("Lahir Nisha");
		student.setDepartment("ECE");
		student.setCollege("SKCET");
		student.setPermanentAddress(permanantAddress);
		student.setHomeAddress(homeAddress);

                session.save(student); 
        
		tx.commit(); 
		session.close();
		sf.close();
	}
}

 

Eclipse console after running this program


 
Hibernate: insert into STUDENT (COLLEGE, DEPARTMENT, HOME_CITY_NAME, HOME_PIN_CODE, HOME_STATE_NAME, HOME_STREET_NAME, NAME, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME, ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
 
In our next article we shall learn about Saving Collections in Hibernate

About Mohaideen Jamil


Am currently working as a Struts 2 Developer in a reputed IT Organisations. I can help you with teaching Core java and Struts 2. Follow me on Facebook or Google Plus. If you like my tutorials, consider making a donation to this charity, thanks.