dineshonjava

Value Types and Embedding Objects in Hibernate

We’ll learn the difference between Entity type objects and Value type objects. We’ll use the @Embeddable annotations to embed a value type object into our Entity class.
"An object of value type has no database identity; it belongs to an entity instance and its persistent state is embedded in the table row of the owning entity. Value types don't have identifiers or identifier properties"

Now In short we look the following points...
  • Object of Entity Type : has its own database identity
  • Object of Value Type : belongs to an entity, and its persistent state is embedded in the table row of the owning entity. Value types don't have identifiers or identifier properties.
 We look following example of Object of Entity Type: 
@Entity
@Table(name="USER_TABLE")
public class UserDetails{
     @Id @GeneratedValue(strategy=GenerationType.AUTO)
     @Column(name="USER_ID", type="INTEGER")
      private long userId;
      @Column(name="USER_NAME", type="String")
       private String userName;
      @Column(name=USER_ADDRESS, type="String")
       private String address;
      @Column(name="USER_PHONE", type="INTEGER")
       private long phone;
      @Column(name="DOB", type="TIMESTAMP")
       private Date dob;
}

Value Types and Embedding Objects in Hibernate

In Above table we saw that type of the all fields of the class USER CLASS have database entity type object. 
              ID                is INTEGER type
              Name          is VARCHAR type
              ADDRESS is VARCHAR type
              Phone         is BIG INTEGER type
              DOB           is TIMESTAMP type
All are the Entity Type Objects.

Now We look following example of Object of Value Type:

@Entity
@Table(name="USER_TABLE")
public class UserDetails{
     @Id @GeneratedValue(strategy=GenerationType.AUTO)
     @Column(name="USER_ID", type="INTEGER")
      private long userId;
      @Column(name="USER_NAME", type="String")
       private String userName;
      @Column(name=USER_ADDRESS, type="??????") //What should be type for database
       private Address address;
      @Column(name="USER_PHONE", type="INTEGER")
       private long phone;
      @Column(name="DOB", type="TIMESTAMP")
       private Date dob;
}

Now lets see table structure for that...
Value Types and Embedding Objects

here USER CLASS have a field Address type of the Value type object means in the database there are no meaning of Address type object.
Address type object have the four other fields like.
1. Street
2. City
3. State
4. Pin code

VALUE TYPE OBJECT APPROACH:>

Here there are one approach to save the value the Address Object save to the USER TABLE is the save the individually fields of this object to the separate columns of the USER TABLE. As following 
Value Types in Hibernate
This scenario is working in the hibernate only one condition is Address Object should be a Value Object (means there is no meaning to itself its provide the meaning to the entity object).
In this approach there are some problems are
1. Table complexity
2. Data Redundancy
3. User may have multiple Address like home address and office address etc.

Look the above example in the code...
Address.java
package com.sdnext.hibernate.tutorial.dto;

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

@Embeddable //for value object it is not is entity object. Value object means does not have real meaning for self individually.
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;
   
    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 getPincode() {
        return pincode;
    }
    public void setPincode(String pincode) {
        this.pincode = pincode;
    }
    public String toString()
    {
        return " {Street: "+street+" City: "+city+" State: "+state+" Pincode: "+pincode+" }";
    }
}

@Embeddable: 
Target:
Classes
Defines a class whose instances are stored as an intrinsic part of an owning entity and share the identity of the entity. Each of the persistent properties or fields of the embedded object is mapped to the database table for the entity. 

UserDetails.java
package com.sdnext.hibernate.tutorial.dto;

import java.util.Date;

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

@Entity
@Table (name="USER_TABLE")

public class UserDetails
{
    @Id @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="USER_ID")

    private int    userId;
   
    @Column(name="USER_NAME")
    private String userName;
   
    @Embedded //For value type object
    private Address address;
   
    @Column(name="USER_PHONE")
    private String phone;
   
    @Column(name="DOB")
    private Date dob;
   
    public void setUserId(int userId) {
        this.userId = userId;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public Date getDob() {
        return dob;
    }
    public void setDob(Date dob) {
        this.dob = dob;
    }
    public int getUserId() {
        return userId;
    }
    public String toString()
    {
        return "[User Name: "+userName+"User Id: "+userId+" User Address "+address+" Use phone " +phone+" ]";
    }
}

hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/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:3306/hibernateDB</property>
         <property name="connection.username">root</property>
         <property name="connection.password">root</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>
       
        <!-- Drop and re-create the database schema on startup -->
         <property name="hbm2ddl.auto">create</property>
      
         <mapping class="com.sdnext.hibernate.tutorial.dto.UserDetails"/>
        
     </session-factory>
 </hibernate-configuration>


HibernateTestDemo.java
package com.sdnext.hibernate.tutorial;

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

import com.sdnext.hibernate.tutorial.dto.Address;
import com.sdnext.hibernate.tutorial.dto.UserDetails;

public class HibernateTestDemo {
    /**
     * @param args
     */
    public static void main(String[] args)
    {
        UserDetails user1 = new UserDetails(); //create first user
        UserDetails user2 = new UserDetails(); //create second user
             
        user1.setUserName("Dinesh Rajput");
        user2.setUserName("Anamika Rajput");
       
        Address address1 = new Address(); //create first value type object for  entity type object user1
        address1.setStreet("K Block House No. 403");
        address1.setCity("Mangol Puri");
        address1.setState("New Delhi");
        address1.setPincode("110083");
        user1.setAddress(address1);
       
        Address address2 = new Address();//create second value type object for  entity type object user2
        address2.setStreet("Film City");
        address2.setCity("Noida");
        address2.setState("UP");
        address2.setPincode("201301");
        user2.setAddress(address2);
       
        user1.setDob(new Date());
        user1.setPhone("+91-9953423462");
       
        user2.setDob(new Date());
        user2.setPhone("+91-9973423462");
       
        SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory(); //create a session factory object
        Session session = sessionFactory.openSession(); // create session object from session factory
        session.beginTransaction(); //begin transaction for this session
       
        session.save(user1); //save the first user
        session.save(user2); //save the second user
       
        session.getTransaction().commit(); //commit the transaction the session
        session.close(); //close the session
    }
}


OUTPUT:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into USER_TABLE (CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME, DOB, USER_PHONE, USER_NAME) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into USER_TABLE (CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME, DOB, USER_PHONE, USER_NAME) values (?, ?, ?, ?, ?, ?, ?)

Embedding Objects in Hibernate

Value Types and Embedding Objects Example

Attributes Override:
Here we have seen that an Entity Type Object USER has a Value Type Object(or Embeddable Object ) ADDRESS with corresponding fields name street, city, pin-code and state save to the database table USER_TABLE with value type object's column name (CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME).

But here some problems, suppose this user object have two types of addresses as like Local Address and Permanent Address then how to manage the column names of these value type objects in the database table USER_TABLE.

To overcome this problem we  have to override the Attributes of the Value type objects.
Lets see how to get in the code...

UserDetails.java
package com.sdnext.hibernate.tutorial.dto;

import java.util.Date;

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.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;

@Entity
@Table (name="USER_TABLE")
public class UserDetails
{
    @Id
    @Column(name="USER_ID")
    @GeneratedValue(strategy=GenerationType.AUTO)

    private int    userId;
   
    @Column(name="USER_NAME")

    private String userName;
   
    @Column(name="DOB")
   
private Date joinDate;
   
    @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;
   
    @Column(name="Phone")
      private String phone;
   
    public int getUserId() {
        return userId;
    }
    public Address getHomeAddress() {
        return homeAddress;
    }
    public void setHomeAddress(Address homeAddress) {
        this.homeAddress = homeAddress;
    }
    public void setUserId(int userId) {
        this.userId = userId;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public Date getDob() {
        return dob;
    }
    public void setDob(Date dob) {
        this.dob= dob;
    }
    public Address getPermanentAddress() {
        return permanentAaddress;
    }
    public void setPermanentAddress(Address permanentAddress) {
        this.permanentAddress = permanentAddress;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone= phone;
    }
   
    public String toString()
    {
        return "[User Name: "+userName+"\n Permanent Address: "+permanentAddress+"\n Home Address: "+homeAddress+"\n Date of Birth: "+dob+"\n Phone: "+phone+"]";
    }
}

Now run the following code of the class file..
HibernateTestDemo.java

package com.sdnext.hibernate.tutorial;

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

import com.sdnext.hibernate.tutorial.dto.Address;
import com.sdnext.hibernate.tutorial.dto.UserDetails;


public class HibernateTestDemo {

    /**
     * @param args
     */
    public static void main(String[] args)
    {
        UserDetails user = new UserDetails(); //create an user is entity type object
        //user.setUserId(1);
        user.setUserName("Dinesh Rajput");
       
        Address address = new Address(); //create an value type object of address class for home address
        address.setStreet("Block House No");
        address.setCity("MangolaPuri");
        address.setState("New Delhi");
        address.setPincode("110089");
        user.setHomeAddress(address); //set the home address
       
        Address address1 = new Address();//create another value type object for the permanent address
        address1.setStreet("Film City");
        address1.setCity("Noida");
        address1.setState("UP");
        address1.setPincode("201301");
        user.setPermanentAddress(address1);//set the permanent address
       
        user.setDob(new Date());
        user.setPhone("9999222211");
       
        SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory(); //create a session factory object
        Session session = sessionFactory.openSession(); //create a session object
        session.beginTransaction(); //transaction object start
        session.save(user); //  save the entity type object user to the database
        session.getTransaction().commit(); //commit the transaction object
        session.close(); //close the session
        }
}

After running the above code we will get the following table structure...

Value Types and Embedding Objects Outputs



Now in the Next Chapter we will see how to work on Work with Collection in Hibernate.

                                        <<Previous Chapter 12<<    >>Next Chapter14