Wednesday, October 14, 2015

Hibernate Uni-directional One-to-One Mapping with Annotation

There are two Hibernate mapping directions.
  • Bi-directional mapping
 Here both student and address objects have reference to each other, thus, address object can retrieve student data.

  • Uni-directional mapping
              Here the relationship is kept only on one side. You can directly retrieve data only from one side.
              Lets consider one to one relationship

                   One student dwells in one Address.
                   One address can be occupied by only one student

    if student domain object has a reference to an address object, but address  domain object does not have a reference to the student object, only from a student object you can retrieve address data.


To create a uni-directional mapping using JPA annotation for above relation, we should identify which relation should contain the foreign key. Lets say Student relation contains the foreign key. Therefore, we need a reference to the address and address class will not have any reference

Address class looks like this

package com.sajith.domain;

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

/**
 * Address domain object
 */

@Entity
@Table(name = "ADDRESS")
public class Address {

 @Id
 @Column(name = "ADDRESS_NO")
 private int addressNo;

 @Column(name = "STREET")
 private String street;

 @Column(name = "CITY")
 private String city;

 public int getAddressNo() {
  return addressNo;
 }

 public void setAddressNo(int addressNo) {
  this.addressNo = addressNo;
 }

 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;
 }

}
 
 
In this class addressNo field represents primary key table column ADDRESS_NO. This column is the foreign key column in STUDENT table. To represent this relationship in Student class will contain the address as a field and annotations will be used to indicate that it is the mapping field and hold the foreign key.

Student class as follow
package com.sajith.domain;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

/**
 * Student Domain class
 * 
 */

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

 private int studentId;

 private String studentName;

 private Address studentAddress;

 @Id
 @Column(name = "ID")
 @GeneratedValue
 public int getStudentId() {
  return studentId;
 }

 public void setStudentId(int studentId) {
  this.studentId = studentId;
 }

 @Column(name = "NAME")
 public String getStudentName() {
  return studentName;
 }

 public void setStudentName(String studentName) {
  this.studentName = studentName;
 }

 @OneToOne(cascade = CascadeType.ALL)
 @JoinColumn(name = "ADDRESS_NO")
 public Address getStudentAddress() {
  return studentAddress;
 }

 public void setStudentAddress(Address studentAddress) {
  this.studentAddress = studentAddress;
 }

}

@OneToOne - States the relationship type
   CascadeType.ALL - States that when changes happen to Student, the corresponding Address should be   changed as well
E.g:  If student is deleted his address should be deleted as well.
@JoinColumn:  States the foreign key column

Get the Hibernate configuration file from my previous Hibernate post and adds the Address class
 <mapping class="com.sajith.domain.Address"/>

Hibernate Util class


package com.sajith.util;

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

public class HibernateUtil {

 private static final SessionFactory sessionFactory = buildSessionFactory();

 private static ServiceRegistry serviceRegistry;

 private static SessionFactory buildSessionFactory() {

  Configuration configuration = new Configuration();
  configuration.configure();
  serviceRegistry = new StandardServiceRegistryBuilder().applySettings(
    configuration.getProperties()).build();

  return configuration.buildSessionFactory(serviceRegistry);

 }

 public static SessionFactory getSessionFactory() {
  return sessionFactory;
 }

 public static void shutdown() {
  // Close caches and connection pools
  getSessionFactory().close();
 }

} 

Main App class
package com.sajith;

import org.hibernate.Session;

import com.sajith.domain.Address;
import com.sajith.domain.Student;
import com.sajith.util.HibernateUtil;

public class App {

 
 public static void main(String[] args) {
  
 
  Session session = HibernateUtil.getSessionFactory().openSession();

  session.beginTransaction();
   
  Student student1 = new Student();
  
  Address address  = new Address();
  
  address.setAddressNo(2);
  address.setCity("Colombo");
  address.setStreet("Horton Place");
  
  
  student1.setStudentId(3);
                student1.setStudentName("Sanya Fernando");
                student1.setStudentAddress(address);
 
 

  session.save(student1);
  session.getTransaction().commit();
  
  System.exit(0);
 }
 
}

As you can see we create a Student instance and assign an address.
Create the tables like following.

Address table



Student table



If you execute the App file, output will be








Monday, October 12, 2015

Hibernate mapping with Annotation


This is a simple example of mapping a java domain class with a relation using JPA annotation and Hibernate.

Hibernate can be mapped in 2 ways.
  • With an XML mapping file(.hbm file)
  • With Annotation
Description
   We use JPA as Annotation specification and Hibernate as the provider.

Steps

  • Create a java project using Maven in Eclipse and update the pom file

Refer: Hibernate environment setup with maven using Eclipse


  • Create the domain class and annotate using JPA annotation
@Entity - Denotes that instances of this class are persistent with a DB
@Table - Denotes that name of the corresponding table in DB is STUDENT if not used this annotation, table name would be the same as class name(Hence, here it would be Student)
@Id - This field will be the Primary Key column
@Column - Denotes that this will be a column in the table

Mapping can be done for member variables or/and their corresponding getter methods.

package com.sajith.domain;

import javax.annotation.Generated;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * Student Domain class
 *
 */

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

 
 private int studentId;
 
 private String studentName;
 
 private String studnetCity;

 @Id
 @Column(name="ID")
 public int getStudentId() {
  return studentId;
 }

 
 public void setStudentId(int studentId) {
  this.studentId = studentId;
 }

 @Column(name="CITY")
 public String getStudnetCity() {
  return studnetCity;
 }

 public void setStudnetCity(String studnetCity) {
  this.studnetCity = studnetCity;
 }

 @Column(name="NAME")
 public String getStudentName() {
  return studentName;
 }

 public void setStudentName(String studentName) {
  this.studentName = studentName;
 }

}


  • Create the Hibernate configuration file
  When you use annotation instead of XML mapping only change will be instead of <mapping resource>
<mapping class> attribute.

<?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>
        <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="hibernate.connection.password">sajith</property>
        <property name="hibernate.connection.url">jdbc:oracle:thin:@127.0.0.1:1521:xe</property>
        <property name="hibernate.connection.username">sajith</property>
        <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
        <property name="show_sql">true</property>
        <property name="hbmdl.auto">update</property>
        <mapping class="com.sajith.domain.Student"/>
    </session-factory>
</hibernate-configuration>


  • Create the Util class

package com.sajith.util;

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

public class HibernateUtil {

 private static final SessionFactory sessionFactory = buildSessionFactory();
 
 private static ServiceRegistry serviceRegistry;

 private static SessionFactory buildSessionFactory() {
  
   Configuration configuration = new Configuration();
   configuration.configure();
   serviceRegistry = new StandardServiceRegistryBuilder().applySettings(
          configuration.getProperties()).build();
  
  return configuration.buildSessionFactory(serviceRegistry);
       
  
 }

 public static SessionFactory getSessionFactory() {
  return sessionFactory;
 }

 public static void shutdown() {
  // Close caches and connection pools
  getSessionFactory().close();
 }
 
}

  • Create the main App class
 
package com.sajith;

import org.hibernate.Session; 
import com.sajith.domain.Student;
import com.sajith.util.HibernateUtil;

public class App {

 
 public static void main(String[] args) {
  
 
  Session session = HibernateUtil.getSessionFactory().openSession();

  session.beginTransaction();
   
  Student student1 = new Student();
  
  student1.setStudentId(1);
                student1.setStudentName("Sanya Fernando");
                student1.setStudnetCity("Kandy");
 
  session.save(student1);
  session.getTransaction().commit();
  
  
 }
 
}
 
  • Run the App file





Hibernate environment setup with maven using Eclipse

Hibernate is an ORM tool framework which can be used to abstract the JDBC and access various DBMSs independently from DBMS specific SQL. Hibernate provides a way to developer to write SQL using domain model instead of data model representing in DB.

Hibernate mapping types

1. XML mapping files
2. Annotation

The application of Hibernate


1. Pure Hibernate - Only Hibernate framework is used as the mapping framework.
2. With JPA  - Java standardized API for mapping. Here JPA works as the specification and Hibernate is the provider. This is the recommended development method; while JPA annotation is used as the ORM interface, Hibernate provides the implementation. The advantage is you can easily replace the ORM implementation for another ORM framework.

1. Simple Domain object to Oracle table mapping in Hibernate


Hibernate setup with maven in Eclipse

Required Tools & technologies:
  1. Maven 3.1.1
  2. JBOSS hibernate tools
  3. JDK 1.7
  4. Hibernate 4.3.6.final
  5. Oracle 11g
  6. maven-compiler-plugin 3.3
  7. Ojdbc 11.1.0.7
Steps

  • Create a simple maven project skipping archetype
  • Update .pom file with adding following entries
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sajith.hibernate</groupId>
     <artifactId>HibernateStart</artifactId>
     <version>0.0.1-SNAPSHOT</version>
    
     <repositories>
      <repository>
       <id>JBoss repository</id>
       <url>http://repository.jboss.org/nexus/content/groups/public/</url>
      </repository>
     </repositories>
            <dependencies>
      <dependency>
       <groupId>org.hibernate</groupId>
       <artifactId>hibernate-core</artifactId>
       <version>4.3.6.Final</version>
      </dependency>
      <dependency>
       <groupId>com.oracle</groupId>
       <artifactId>ojdbc6</artifactId>
       <version>11.1.0.7</version>
      </dependency>
      <dependency>
       <groupId>org.javassist</groupId>
       <artifactId>javassist</artifactId>
       <version>3.18.1-GA</version>
      </dependency>
     </dependencies>
     <build>
      <plugins>
       <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.3</version>
        <configuration>
         <source>1.7</source>
         <target>1.7</target>
        </configuration>
       </plugin>
      </plugins>
     </build>
    </project>
         Here we use a plug-in to change the default maven compiler and run time version from 1.5 to 1.7
         We add JBOSS repository to get the required Hibernate jars downloaded. And, finally add Oracle
         driver. Oracle drive, you have to download manually and install in your local maven repository.

   
  • Create the domain class

package com.sajith.domain;

/**
 * Student Domain class
 *
 */
public class Student {

 private int studentId;
 private String studentName;
 private String studnetCity;

 public int getStudentId() {
  return studentId;
 }

 public void setStudentId(int studentId) {
  this.studentId = studentId;
 }

 public String getStudnetCity() {
  return studnetCity;
 }

 public void setStudnetCity(String studnetCity) {
  this.studnetCity = studnetCity;
 }

 public String getStudentName() {
  return studentName;
 }

 public void setStudentName(String studentName) {
  this.studentName = studentName;
 }

}
  
  •  Create Hibernate mapping file - Student.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Oct 12, 2015 2:15:25 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.sajith.domain.Student" table="STUDENT">
        <id name="studentId" type="int">
            <column name="ID" />
            <generator class="assigned" />
        </id>
        <property name="studentName" type="java.lang.String">
            <column name="NAME" />
        </property>
        <property name="studnetCity" type="java.lang.String">
            <column name="CITY" />
        </property>
    </class>
</hibernate-mapping>

   
  • Create Hibernate configuration file - 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>
        <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="hibernate.connection.password">sajith</property>
        <property name="hibernate.connection.url">jdbc:oracle:thin:@127.0.0.1:1521:xe</property>
        <property name="hibernate.connection.username">sajith</property>
        <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
        <property name="show_sql">true</property>
        <property name="hbmdl.auto">update</property>
        <mapping resource="com/sajith/domain/Student.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

 
Here, xe is the SID
  •  Create Hibernate Util class
 
 
package com.sajith.util;

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

public class HibernateUtil {

 private static final SessionFactory sessionFactory = buildSessionFactory();
 
 private static ServiceRegistry serviceRegistry;

 private static SessionFactory buildSessionFactory() {
  
   Configuration configuration = new Configuration();
   configuration.configure();
   serviceRegistry = new StandardServiceRegistryBuilder().applySettings(
          configuration.getProperties()).build();
  
  return configuration.buildSessionFactory(serviceRegistry);
       
  
 }

 public static SessionFactory getSessionFactory() {
  return sessionFactory;
 }

 public static void shutdown() {
  // Close caches and connection pools
  getSessionFactory().close();
 }
 
}

  •       Create the main app class
 
package com.sajith;

import org.hibernate.Session; 
import com.sajith.domain.Student;
import com.sajith.util.HibernateUtil;

public class App {

 
 public static void main(String[] args) {
  
 
  Session session = HibernateUtil.getSessionFactory().openSession();

  session.beginTransaction();
   
  Student student1 = new Student();
  
  student1.setStudentId(1);
                student1.setStudentName("Sanya Fernando");
                student1.setStudnetCity("Kandy");
 
  session.save(student1);
  session.getTransaction().commit();
  
  
 }
 
}
   
Note that both configuration files should be in class path to run the application.

  • Run the app file and see the result in the DB. you can also see the log result in Eclipse console window
             Hibernate: insert into STUDENT (NAME, CITY, ID) values (?, ?, ?)






Wednesday, September 24, 2014

Design Patterns in OOD/OOP

Definition

It is a collection of reusable solutions identified by software professionals through lesson learned and best practices to a commonly reoccurring problem in software design.

In Object Oriented Design ,Software Design Patterns are derived from Object Oriented Concepts and Principles.

Invention

Commonly called that Gang of Four are founders of design patterns

Intention

Mainly focuses on designing and developing easy to maintenance, flexible, low coupling and high cohesion applications.

Types
  1. Object Oriented Design Patterns - How the Classes and Objects are organized to develop an easy maintenance system.
  2.  Architectural Design Patterns  - How the Components (Collection of Classes) are arranged in different tiers across an enterprise application to develop an easy maintenance and scalable system.

Object Oriented Design Patterns

    Categorized into 4 sub categories.
  1. Creational  Patterns - Focuses on new object creation.
  2. Structural Patterns - Focuses on simple way to realize relationships between entities.
  3. Behavioral Patterns - Focuses on common communication relationships between objects.
  4. Concurrency Patterns - Focuses on the multi-threaded programming paradigm.

Architectural Design Patterns

  Categorized into 3 sub categories.
  1. Presentation Tier Patterns - Focuses on arranging components in front-end.
  2. Business Tier Patterns - Focuses on arranging components and interaction with Presentation Tier.
  3. Integration Tier Patterns  - Focuses on arranging components in back-end and interaction with Business Tier.

Saturday, September 20, 2014

Decorator Design Pattern

Definition

Decorator Design Pattern is a Structural Design Pattern that adds additional behavior or responsibilities to an object at runtime.

Intention
  1. Adds additional functionality to an object at runtime.
  2. Provides flexible alternative to sub classing.
  3. Works as a filter by applying criteria.
Components

Component - Interface for objects that can have additional responsibilities at runtime.
Concrete Components - Objects that are wrapped by additional behavior.
Decorator - Type of additional behavior that will wrap around Concrete Components
Concrete Decorators  - Extends the functionality of the component by adding behavior or features.
Client - The user who needs the Concrete Components to be added new responsibilities. 










Component

 public interface Vehicle {

    public void drive();

}

Concrete Components


public class Car implements Vehicle {

    @Override
    public void drive() {
        System.out.println("Drive with fuel");
    }

}



Decorator


public abstract class FuelDecorator implements Vehicle {

    protected Vehicle vehicle;

    public FuelDecorator(Vehicle vehicle) {

        this.vehicle = vehicle;
    }

    @Override
    public abstract void drive();

}



Concrete Decorators 

 public class HybridType extends FuelDecorator {

    @Override
    public void drive() {
      
         vehicle.drive();
         System.out.println("and Battery");
    }

    public HybridType(Vehicle vehicle) {
        super(vehicle);
      
    }

}

Client

public class Client {

    public static void main(String[] args) {

        Vehicle vehicle = new Car();

        vehicle.drive(); // Output: Drive with fuel

        Vehicle hybridCar = new HybridType(vehicle);
        hybridCar.drive(); // Output: Drive with fuel
                                    // and Battery

    }

}