Thursday, January 2, 2014

Component Mapping in Hibernate


A Component (Embedded Object) is an object that is persisted as a value type, not an entity (table). A Component mapping is a mapping for a class having a reference to another class as a member variable.

Consider the following Person class














Person class contains the following properties like firstName, lastName, age, houseNo, street etc. Instead of keeping the all attributes in one class(Person) we can divide the some properties(house, street, city) into separate class (Address) and map that attribute to Person class.



























In the above example, Address is a component in the Person class and it  can't have its own primary key, it uses the primary key of the enclosing Person entity.

Generally we can use, to get the form data from multiple pages and save the data into a single table.

Components can in turn declare their own properties, components or collections.

<component
       name="propertyName"                               
       class="className"                                 
       insert="true|false"                               
       update="true|false"                               
       access="field|property|ClassName"                  
       lazy="true|false"                                  
       optimistic-lock="true|false"                       
       unique="true|false"                                
       node="element-name|."
>
       <property ...../>
       <many-to-one .... />
       ........
</component>


name: the name of the property.
class (optional - defaults to the property type determined by reflection): the name of the component (child) class.
insert: do the mapped columns appear in SQL INSERTs?
update: do the mapped columns appear in SQL UPDATEs?
access (optional - defaults to property): the strategy Hibernate uses for accessing the property value.
lazy (optional - defaults to false): specifies that this component should be fetched lazily when the instance variable is first accessed. It requires build-time bytecode instrumentation.
optimistic-lock (optional - defaults to true): specifies that updates to this component either do or do not require acquisition of the optimistic lock. It determines if a version increment should occur when this property is dirty.
unique (optional - defaults to false): specifies that a unique constraint exists upon all mapped columns of the component.


Person.java
=================
package com.ranga.mapping;


import java.io.Serializable;


public class Person implements Serializable {
   
   private long id;
   private String firstName;
   private String lastName;
   private int age;
   private Address address;
   
   public long getId() {
       return id;
   }
   public void setId(long 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 int getAge() {
       return age;
   }
   public void setAge(int age) {
       this.age = age;
   }
   public Address getAddress() {
       return address;
   }
   public void setAddress(Address address) {
       this.address = address;
   }
   @Override
   public String toString() {
       return "Person [id=" + id + ", firstName=" + firstName + ", lastName="
               + lastName + ", age=" + age + ", address=" + address + "]";
   }
       
}


Address.java
===============
package com.ranga.mapping;


import java.io.Serializable;


public class Address implements Serializable {
   private String houseNo;
   private String street;
   private String city;
   public String getHouseNo() {
       return houseNo;
   }
   public void setHouseNo(String houseNo) {
       this.houseNo = houseNo;
   }
   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;
   }
   @Override
   public String toString() {
       return "Address [houseNo=" + houseNo + ", street=" + street + ", city="
               + city + "]";
   }    
   
}


Person.hbm.xml
===================


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
   "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


<hibernate-mapping package="com.ranga.mapping">


   <class name="Person" table="Persons">
       <id name="id">
           <generator class="increment"/>                        
       </id>
       <property name="firstName" />
       <property name="lastName" />
       <property name="age" />
       <component name="address" class="Address">
           <property name="houseNo"></property>
           <property name="street"></property>
           <property name="city"></property>                        
       </component>        
   </class>
</hibernate-mapping>


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">oracle.jdbc.driver.OracleDriver</property>
       <property name="connection.url">jdbc:oracle:thin:@localhost:1521:xe</property>
       <property name="connection.username">ranga</property>
       <property name="connection.password">ranga</property>


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


       <!-- SQL dialect -->
       <property name="dialect">org.hibernate.dialect.Oracle10gDialect</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.internal.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">update</property>


       <mapping resource="com/ranga/mapping/Person.hbm.xml" />
   </session-factory>
</hibernate-configuration>




HibernateUtil.java
===================
package com.ranga.util;


import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;


public class HibernateUtil {
   private static final SessionFactory sessionFactory;
   private static final ServiceRegistry serviceRegistry;
   static {
       try {
           Configuration configuration = new Configuration();
           configuration.configure();
           serviceRegistry = new ServiceRegistryBuilder().applySettings(
                   configuration.getProperties()).buildServiceRegistry();
           sessionFactory = configuration.buildSessionFactory(serviceRegistry);
       } catch (Throwable ex) {
           throw new ExceptionInInitializerError(ex);
       }
   }


   public static SessionFactory getSessionFactory() {
       return sessionFactory;
   }
   
   public static void closeSessionFactory() {
       if (sessionFactory != null)
           sessionFactory.close();        
    }
}



App.java
=================
package com.ranga;


import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;


import com.ranga.mapping.Address;
import com.ranga.mapping.Person;
import com.ranga.util.HibernateUtil;


public class App {
   public static void main(String[] args) {
       SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
       // Saving the Person Information
       Session session = sessionFactory.openSession();
       Transaction transaction = null;
       try {
           transaction = session.beginTransaction();


           Address address = new Address();
           address.setHouseNo("124");
           address.setStreet("BTM");
           address.setCity("Bangalore");


           Person p1 = new Person();
           p1.setFirstName("ranga");
           p1.setLastName("reddy");
           p1.setAge(25);
           p1.setAddress(address);


           long personId = (Long) session.save(p1);
           transaction.commit();


           // fetching the Person Information
           Person person = (Person) session.get(Person.class, personId);
           System.out.println(person);


       } catch (HibernateException e) {
           transaction.rollback();
           e.printStackTrace();
       } finally {
           session.close();
       }
   }
}

=====================================================================

1 comments: