Friday, July 27, 2012

10. Named Queries, Lazy loading සහ Cascade ගැන..


Named Queries

මෙම queries, define කර ඇත්තේ mapping xml file  එකේදීය. අවශ්‍ය විට මෙම නමින් call කළ හැකිය.Application code එක තුළ sql ලිවීම වළකී.

උදා:


<sql-query name = "empdetails">
   <return alias="emp" class="com.test.Employee"/>
      SELECT emp.EMP_ID AS {emp.empid},
                 emp.EMP_ADDRESS AS {emp.address},
                 emp.EMP_NAME AS {emp.name}
      FROM Employee EMP WHERE emp.NAME LIKE :name
</sql-query>

මෙම Named query එක call කරන්නේ කෙසේද ?



List people = session.getNamedQuery("empdetails")
    .setString("TomBrady", name)
    .setMaxResults(50)
    .list();

----------------------------------------------------------------------------------

Lazy loading

lazy=true මඟින් performance improve වෙයි.Collection එකක් associate වී ඇත්නම්, එහි elements load වන්නේ, ඒ සඳහා වෙනම call කළොත් පමණි.

Parent object එක load කරන විට child objects load කළයුතුද නැත්ද යන්න set කරන්නේ මෙමඟිනි.

Parent class එකේ mapping සිදුකරන විට මෙය ලබාදිය යුතුය.

lazy=true මඟින් අදහස් වන්නේ child objects load නොකළ යුතු බවයි.(default)

එය  load කිරීමට නම් වෙනම parent.getChild() call කළ යුතුය.

සමහර අවස්ථාවල parent object එක සමඟම child object එකත් load කිරීම අවශ්‍යය වෙයි.
 එවිට lazy=false දිය යුතුය.


---------------------------------------------------------------------

Cascade


1) cascade="none", (default) -:association., ignore කරන ලෙස දැන්වීමට

2) cascade="save-update" -: object එක save/update කරන විට, transaction commit කරන විට association , navigate කර persistent instances වලටත් අදාළ වෙනස්කම් කරන්න.


3) cascade="delete" -: object එක delete කරන විට association , navigate කර persistent instances, delete කරන්න.







9. Hibernate සහ Spring, integrate කරමු.



මෙහි ප්‍රධාන පියවර දෙකකි.
1. HibernateTemplate එක Spring හි declare කිරීම
2. එයට SessionFactory  එක සම්බන්ධ කිරීම


-----------------------------------------------



Spring වල ඇති HibernateTemplate, Hibernate session සඳහා වඩා abstract layer එකක් ලබාදෙයි.

HibernateTemplate හි ප්‍රධානම කාර්යය වන්නේ Hibernate sessions open කිරීම සහ close කිරීමේ වැඩ සරල කිරීම සහ Hibernate-specific exceptions, Spring ORM exceptions බවට පත් කිරීමයි.

[Hibernate 2 ට අදාළව නම් මෙය Checked Hibernate exception එක, Unchecked Hibernate Exception එකක් බවට පත් කිරීමයි.

HibernateTemplate එක Spring හි configure කරන ආකාරය පහත xml එකේ දැක්වෙයි.


<bean id="hibernateTemplate"

class="org.springframework.orm.hibernate3.HibernateTemplate">
 <property name="sessionFactory" ref="sessionFactory" />
</bean>




---------------------------------------------------------


Hibernate Session Object එකක් සඳහා reference එකක් ලබාගැනීමේ සම්මත ක්‍රමය වන්නේ Hibernate හි Session Factory Interface එකේ implementation එකක් හරහාය.

Hibernate sessions, open කිරීම, close කිරීම සහ manage කිරීම Session Factory හි වගකීමයි.

පළමු කාර්යය වන්නේ Hibernate Session Factory Bean එක Spring වල configure කිරීමයි. 


Classes, tables map කරන්නේ annotations මඟින් නම් මෙම Hibernate Session Factory instance එක ලබා දෙන්නේ AnnotationSessionFactory Bean එක මඟිනි.

Mappings සිදු කරන්නේ xml මඟින් නම් මෙය සිදු කරන්නේ LocalSessionFactoryBean මඟිනි.


<bean id="sessionFactory"

class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
 <property name="dataSource" ref="dataSource" />
 <property name="annotatedClasses">
  <list>
   <value>hibernate.Employee</value>
  </list>
 </property>
 <property name="hibernateProperties">
  <props>
   <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
   <prop key="show_sql">true</prop>
  </props>
 </property>
</bean>

-------------------------------------------------------------------



දැන් HibernateTemplate එක Declare කරලා අවසන්.
එලෙසම එය SessionFactory එකට සම්බන්ධ කර තියෙන්නේ.

දැන් අප සූදානම් Database එකට data persist කරන්නට සහ එයින් data retrieve කරන්නට.








8. SessionFacory,session සහ HibernateTemplate හි භාවිතය


SessionFacory



Application එක සඳහා session instances ලබා දෙන්නේ SessionFactory එක මඟිනි.

සාමාන්‍යයෙන් Application එකක් සඳහා පවතින්නේ එක SessionFactory එකකි.

Application එක Hibernate මඟින් databases කීපයක් access කරනවා නම්, එක් එක් database එක සඳහා වෙන වෙනම SessionFactory අවශ්‍යය වෙයි.

Many-To-Many Relation Mapping උදාහරණයේදී Session එක භාවිතයෙන් objects, save කරන ආකාරය සළකා බලමු.

packagge abc.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

public class SavingTest{

public static void main (String args[] ) {

SessionFactory sf =  HibernateUtil.getSessionFactory();
Session session = sf.openSession() ;
session.beginTransaction () ;

Meeting m1 = new Meeting ("HR Meeting") ;
Meeting m2 = new Meeting ("Finance Meeting");

Employee e1 = new Employee ("kamal","perera",20000);
Employee e2 = new Employee("nimal","silva",30000);

e1.getMeetings.add(m1) ;
e1.getMeetings.add(m2);
e2.getMeetings.add(m1);

session.save(e1);
session.save(e2);

session.getTransaction();
commit();
session.close();

}
}


-----------------------------------------

HibernateTemplate


HibernateTemplate යනු helper class එකකි.
එය hibernate data access code එක සරල කරයි.

එයින් session open කිරීම සහ close කිරීමද code එක execute වූ පසු transaction, commit හෝ rollback කිරීමද සිදුකරන නිසා ඒ සඳහා code ලිවිය යුතු නොවේ.

නමුත් Hibernate 4 version එකෙන් මෙය ඉවත් කර ඇත.









Thursday, July 26, 2012

7. Many-To-Many Relation Mapping


පහත දැක්වෙන්නේ Many-To-Many relationship එකක් map කරන ආකාරය.


Meeting සහ Employee classes දෙක අතර සම්බන්ධය Many-To-Many ලෙස ගනිමු.

එනම් එක Meeting එකක Employees ලා බොහෝ සිටිය හැක.
එක Employee කෙනෙක් බොහෝ Meeting ගණනකට සහභාගි විය හැක.


a)  package abc.hibernate;

import java.sql.Date;

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





@Entity
@Table(name="employee")
public class Employee{

@Id
@GeneratedValue
@Column(name="emp_id")
private Long empId;

@Column(name="first_name")
private String firstName;

@Column(name="last_name")
private String lastName;

@Column(name="birth_date")
private Date birth_date;

@Column(name="salary")
private double salary;

@ManyToMany(cascade={CascadeType.ALL })
@JoinTable(name="employee_meeting",
                       joinColumns={@JoinColumn(name="emp_id")},
                       inverseJoinColumns={@JoinColumn(name="meeting_id")})
private Set<Meeting> meetings = new HashSet<Meeting>(); 

public Employee(){
}

public Employee(String firstname, String lastname, Date birthdate, double salary){
this.firstName = firstname;
this.lastName = lastname ;
this.birthDate = birthdate ;
this.salary = salary ;
}

//Getter and Setter methods

}




---------------------------------------------------------------------------------------------




b)   package abc.hibernate;


import java.util.Date;
import java.util.HashSet;
import java.util.Set;



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


@Entity
@Table(name="meeting")
public class Meeting {


@Id
@Column(name="meeting_id")
@GeneratedValue
private Long meetingId ;


@Column(name="subject")
private String Subject;


@Column(name="meeting_date")
private Date meetingDate;


@ManyToMany(mappedBy="meetings")
private Set<Employee> employees = new HashSet<Employee>();


private Meeting(String subject){
this.subject= subject;
this.meeting_date = new Date();
}


//Getters and Setters


}







6.One-To-Many relation mapping


පහත දැක්වෙන්නේ One-To-Many relationship එකක් map කරන ආකාරය.


Department සහ Employee classes දෙක අතර සම්බන්ධය One-To-Many ලෙස ගනිමු.

එනම් එක Department එකක Employees ලා බොහෝ සිටිය හැක.
නමුත් එක Employee කෙනෙක් අයත් වන්නේ එක Department එකකට පමණි.

a)  package abc.hibernate;

import java.sql.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.ManyToOne;
import javax.persistence.JoinColumn;

@Entity
@Table(name="employee")
public class Employee{

@Id
@GeneratedValue
@Column(name="emp_id")
private Long empId;

@Column(name="first_name")
private String firstName;

@Column(name="last_name")
private String lastName;

@Column(name="birth_date")
private Date birth_date;

@Column(name="salary")
private double salary;

@ManyToOne
@JoinColumn(name="deptment_id")
private Department Department;


public Employee(){
}

public Employee(String firstname, String lastname, Date birthdate, double salary){
this.firstName = firstname;
this.lastName = lastname ;
this.birthDate = birthdate ;
this.salary = salary ;
}

//Getter and Setter methods

}






@JoinColumn යනු Entity දෙකක් සම්බන්ධ කිරීමේදී map වෙන column එකයි.
----------------------------------------------------------------------------




b)   package abc.hibernate;

import java.util.Set;

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


@Entity
@Table(name="department")
public class Department{


@Id
@GeneratedValue
@Column(name="department_id")
private Long departmentId;




@Column(name="depat_name")
private String departmentName;




@OneToMany(mappedBy="department")
private Set<Employee> employee ;


//getters and setters


}



























































5. One-To-One relation mapping


Hibernate mappings වලදී table අතර relations, map කිරීම ඉතාම වැදගත් කාර්යයක්.

පහත දැක්වෙන්නේ One-To-One relationship එකක් map කරන ආකාරය


Employee සහ EmployeeDetail නම් class දෙක අතර සම්බන්ධය One-To-One ලෙස ගනිමු.

එනම් එක Employee කෙනෙකුට ඇත්තේ එක EmployeeDetail එකකි.
එලෙසම එක EmployeeDetail  එකක් සම්බන්ධ වන්නේ එක Employee කෙනෙක් සමඟ පමණි.


a) package abc.hibernate;

import java.sql.Date;

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

@Entity
@Table(name="employee")
public class Employee{

@Id
@GeneratedValue
@Column(name="emp_id")
private Long empId;

@Column(name="first_name")
private String firstName;

@Column(name="last_name")
private String lastName;

@Column(name="birth_date")
private Date birth_date;

@Column(name="salary")
private double salary;

@OneToOne ( mappedBy="employee" cascade=CascadeType.ALL)
private EmployeeDetail employeeDetail;


public Employee(){
}

public Employee(String firstname, String lastname, Date birthdate, double salary){
this.firstName = firstname;
this.lastName = lastname ;
this.birthDate = birthdate ;
this.salary = salary ;
}

//Getter and Setter methods

}




b)  package abc.hibernate; 

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;


@Entity
@Table(name="employeedetail")
public class EmployeeDetail{


@Id
@Column (name="employee_id", unique=true, nullable=false)
@GeneratedValue(generator ="gen")
@GenericGenerator(name="gen", strategy="foreign", parameters=@Parameter(name="property",
                                                                                     value="employee"))
private Long employeeId;


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

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


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

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


@OneToOne
@PrimaryKeyJoinColumn
private Employee emploee ;

public EmployeeDetail(){
}


public EmployeeDetail (String street, String city, String state, String country ) {
this.street= street ;
this.city = city ;
this.state = state ;
this.country = country ;
}

//getters and setters

}




























Wednesday, July 25, 2012

4. Hibernate mappings, Annotations භාවිතයෙන්...



පහත දැක්වෙන Employee class එක simple POJO class එකක්.

මෙහිදී hibernate mapping සිදු කර තිබෙන්නේ annotations භාවිතයෙන්.



package abc.hibernate;

import java.sql.Date;

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

@Entity
@Table(name="employee")
public class Employee{

@Id
@GeneratedValue
private Long empId;

@Column(name="first_name")
private String firstName;

@Column(name="last_name")
private String lastName;

@Column(name="birth_date")
private Date birth_date;

@Column(name="salary")
private double salary;

public Employee(){
}

public Employee(String firstname, String lastname, Date birthdate, double salary){
this.firstName = firstname;
this.lastName = lastname ;
this.birthDate = birthdate ;
this.salary = salary ;
}

//Getter and Setter methods

}

ඉහත  annotations වල භාවිතය පහත පරිදිය.

@Entity -  මෙමඟින් class එක entity එකක් බව ( persistent POJO class එකක් බව ) ප්‍රකාශ වෙයි.

@Table(name="xxx") -  class එක  map වියයුතු table එකේ නම


@Id -  මෙමඟින් මේ entity එකේ identifier property එක ප්‍රකාශ කරයි.

@GeneratedValue - primary key එක auto generate විය යුතු බව

@Column(name="xxx") -  attribute එක  map වියයුතු column එකේ නම




one-to-one, one-to-many සහ many-to-many relationships ඇති tables, map කරන ආකාරය ඉදිරියට...









Tuesday, July 24, 2012

3. Hibernate, configuration කරන්නේ කොහොමද?


මේ සඳහා වෙනම configuration file එකක් ලිවීමට පුළුවන්.
(hibernate.cfg.xml)

xml file එකක් වෙනුවට properties file එකකිනුත් hibernate configurations ලබාදිය හැක.

නැත්නම් මේ configuration details , spring-config.xml වැනි configuration file එකකට ඇතුළත් කරන්නත් පුළුවන්.
(Hibernate සහ spring ,integrate කරන project එකකදී)

 hibernate.cfg.xml file එකක් පහත දැක්වෙයි.

<?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/firsthibernate
</property>

<property name=“connection.username”>root</property>
  
               <property name=“connection.password”>root</property> 

    
<!--sql dialect-->

<property name=“dialect”>org.hibernate.dialect.MySQLDialect</property>

<!-- Echo all executed SQL to stdout -->
                   
                  <property name=“show_sql”>true</property>

                <property name="hibernate.connection.pool_size">10</property>  

                   <!-- mapping සිදු කරන්නේ annotations මඟින් නම් -->     
       
<mapping class="employee.Employee" />

<!-- mapping සිදු කරන්නේ xml මඟින් නම් -->

<mapping resource="employee.Employee.hbm.xml" />



</session-factory>

</hibernate-configuration>

දැන් මේ configuration details විස්තර සහිතව සළකා බලමු.



 පළමු properties හතරෙන් දැක්වෙන්නේ MySQL database connection එක සඳහා අවශ්‍යය 

configurationsවෙයි.


driver_class යනු කුමක්ද? DBMS එකට අදාළ JDBC driver class එකයි. 
උදා: com.mysql.jdbc.Driver, org.postgresql.Driver,  
oracle.jdbc.driver.OracleDriver

url එක මඟින් database path එක දිය යුතුය.username, password යනු database එකට connect වීම
සඳහා දිය යුතු username password වෙයි.

dialect යනු hibernate මඟින් generate කළයුතු specific sql variant එකයි. Database එකට අදාළ sql ,
generateකිරීම සඳහා මෙය ලබාදිය යුතුය. උදා: org.hibernate.dialect.MySQLDialect, 
org.hibernate.dialect.PostgreSQLDialect, org.hibernate.dialect.OracleDialect ,
org.hibernate.dialect.SQLServerDialect

show_sql යන්න true කර ඇත්නම් console window එකට සියළු sql command ලබාදෙයි.


pool_size යනු hibernate database connection pool එකේ ඇති උපරිම waiting connections 
ගණනයි.

අවසන mapping files ඇති තැන ලබා දී ඇත.

මීලඟ ලිපියෙන් hibernate mapping files ලියන අයුරු.


Hibernate ලිපි පෙළ

1. Hibernate කියන්නේ මොකක්ද? 

2. Hibernate භාවිතා කිරීමේ වාසි මොනවාද?
3. Hibernate, configuration කරන්නේ කොහොමද?









2. Hibernate භාවිතා කිරීමේ වාසි මොනවාද?

Hibernate බඳු ORM tool එකක් භාවිතා කිරීමේ වාසි මොනවාද?


1) Productivity ඉහළ යාම


              SQL ලිවිය යුතු නොවීම, ලිවිය යුතු  Java code ප්‍රමාණය අඩුවීම, high level OO API එකක් වීම වැනි හේතු නිසා Productivity ඉහළ යාම සිදුවෙයි.


2) Performance ඉහළ යාම
           lazy loading, Eager loading , Sophisticated caching වැනි හේතු නිසා Performance ඉහළ යාම සිදුවෙයි.

3) Maintainability ඉහළ යාම
   ලිවිය යුතු  code ප්‍රමාණය අඩුවීම නිසා Maintainability ඉහළ යාම සිදුවෙයි.

4) Portability ඉහළ යාම
  Framework එක විසින් database specific SQL ලියා දෙන නිසා Portability ඉහළ යාම සිදුවෙයි.



Hibernate මඟින් පහසු කෙරෙන්නේ කුමක්ද?


1  Domain objects , save කිරීම සහ retrieve කිරීම පහසුවෙන් කළ හැක.
2.Database table names සහ column names වැනි දෙය වෙනස් කිරීම පහසුවෙන් කළ හැක.
3. Related items ලබා ගැනීමට ලිවිය යුතු complex joins සරල කරයි.


JDBC වලට වඩා Hibernate භාවිතයේ වාසි..

1) Hibernate Framework එකෙන්ම අවශ්‍යය sql, generate වී execute වන නිසා developers ලාගේ development time එක සහ debugging time එක ඉතිරි වෙයි.JDBC වලින් මේ සඳහා කළයුතු කාර්යය විශාලය.

2 Developer ට database එකේ data manage කිරීම වෙනුවට business logic එක ගැන concentrate කළ හැක.
3. Hibernate, database independant නිසා ඕනෑම dbms එකක් සමඟ hibernate යොදාගත හැක.





JDBC වලට වඩා Hibernate භාවිතයේ අවාසි



1.  Hibernate සඳහා ඉගෙන ගත යුතු දේ බොහෝ වීම
2. JDBC වලට වඩා Hibernate, slow වෙයි.Runtime එකේදී SQL statements බොහොමයක් generate කළයුතු නිසා
3. Batch processing සඳහා එතරම් සුදුසු නොවේ.

වාසි, අවාසි නිවැරදිව සළකා බලා අවශ්‍යතාවය අනුව Hibernate, web application එකකට යොදා ගැනීම ගැන තීරණය කළ යුතුය.


Hibernate configurations සහ  mapping ඉදිරි ලිපිවල..




Hibernate ලිපි පෙළ


1. Hibernate කියන්නේ මොකක්ද? 

2. Hibernate භාවිතා කිරීමේ වාසි මොනවාද?
3. Hibernate, configuration කරන්නේ කොහොමද?