hibernate basics

Upload: sabari-nathan

Post on 14-Jan-2016

15 views

Category:

Documents


0 download

DESCRIPTION

hipernate

TRANSCRIPT

  • Hibernate

    What is Hibernate ?

    Hibernate is an object-relational mapping (ORM) library for the Java language.

    Providing a framework for mapping an object-oriented domain model to a traditional relational database

    Hibernate's primary feature is mapping from Java classes to database tables (and from Java data types to SQL data types)

    Mapping Java classes to database tables is accomplished through the configuration of an XML file or by using Java Annotations

    Hibernate can use the XML file or the annotations to maintain the database schema.

    Hibernate is an object-relational mapping tool, a persistence framework and is used to persist Java objects in a relational database

    Hibernate is an ORM, so you can use either struts+hibernate or spring+hibernate to build a web application.

    In the hibernate u need not bother about how to create table in SQL and u need not to remember connection, prepared statement like that data is stored in persistence way in data base. It makes developer life easy

    It also provides data query and retrieval facilities

    Hibernate Architecture :

    Hibernate:

    1) Itself opens connection to database,

    2) Converts HQL (Hibernate Query Language) statements to database specific statement,

    3) Receives result set,

    4) Then performs mapping of these database specific data to Java objects which are directly used by Java application.

    Hibernate uses the database specification from Hibernate Properties file.

    Automatic mapping is performed on the basis of the properties defined in hbm XML file defined for particular Java object

  • Hibernate

    Hibernate communication with RDBMS :

    Load the Hibernate configuration file (.cfg) and create configuration object. It will automatically load all hbm mapping files.

    Create session factory from configuration object

    Get one session from this session factory.

    Create HQL query.

    Execute query to get list containing Java objects.

    Example,

    Retrieve list of employees from Employee table using Hibernate.

    /* Load the hibernate configuration file */

    Configuration cfg = new Configuration();

    cfg.configure(CONFIG_FILE_LOCATION);

    /* Create the session factory */

    SessionFactory sessionFactory = cfg.buildSessionFactory();

    /* Retrieve the session */

    Session session = sessionFactory.openSession();

    /* create query */

    Query query = session.createQuery("from EmployeeBean);

    /* execute query and get result in form of Java objects */

    List finalList = query.list();

    EmployeeBean.hbm.xml

  • Hibernate

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

    Why is Hibernate better than JDBC ?

    1) Relational Persistence for JAVA

    Working with both Object-Oriented software and Relational Database is complicated task with JDBC because there is mismatch between how data is represented in objects versus relational database.

    So with JDBC, developer has to write code to map an object model's data representation to a relational data model and its corresponding database schema.

    Hibernate is flexible and powerful ORM solution to map Java classes to database tables. Hibernate itself takes care of this mapping using XML files so developer does not need to write code for this.

    2) Transparent Persistence

    The automatic mapping of Java objects with database tables and vice versa is called Transparent Persistence.

    Hibernate provides transparent persistence and developer does not need to write code explicitly to map database tables tuples to application objects during interaction with RDBMS.

  • Hibernate

    With JDBC this conversion is to be taken care of by the developer manually with lines of code.

    3) Support for Query Language

    JDBC supports only native Structured Query Language (SQL). Developer has to find out the efficient way to access database, ie to select effective query from a number of queries to performsame task.

    Hibernate provides a powerful query language Hibernate Query Language (independent from type of database) that is expressed in a familiar SQL like syntax and includes full support for polymorphic queries.

    Hibernate also supports native SQL statements. It also selects an effective way to perform a database manipulation task for an application.

    4) Database Dependent Code

    Application using JDBC to handle persistent data (database tables) having database specific code in large amount.

    The code written to map table data to application objects and vice versa is actually to map table fields to object properties.

    As table changed or database changed then its essential to change object structure as well as to change code written to map table-to-object/object-to-table.

    Hibernate provides this mapping itself. The actual mapping between tables and application objects is done in XML files.

    If there is change in Database or in any table then the only need to change XML file properties.

    5) Maintenance Cost

    With JDBC, it is developers responsibility to handle JDBC result set and convert it to Java objects through code to use this persistent data in application.

    So with JDBC, mapping between Java objects and database tables is done manually.

    Hibernate reduces lines of code by maintaining object-table mapping itself and returns result to application in form of Java objects.

    It relieves programmer from manual handling of persistent data, hence reducing the development time and maintenance cost.

    6) Open-Source, Zero-Cost Product License

    Hibernate is an open source and free to use for both development and production deployments.

    Disadvantages of Hibernate :

    Anybody wanting to maintain application using Hibernate will need to know Hibernate.

  • Hibernate

    For complex data, mapping from Object-to-tables and vise versa reduces performance and increases time of conversion.

    Hibernate does not allow some type of queries which are supported by JDBC. For example It does not allow to insert multiple objects (persistent data) to same table using single query.

    Developer has to write separate query to insert each object.

    Hibernate vs JDBC :

    Hibernate JDBC

    Hibernate is data base independent, same code will work for all data bases like ORACLE,MySQL ,SQLServer etc.

    In case of JDBC query must be data base specific

    As Hibernate is set of Objects , you don't need to learn SQL language. You can treat TABLE as a Object .

    In case of JDBC you need to learn SQL.

    Don't need Query tuning in case of Hibernate. If you use Criteria Queries in Hibernate then hibernate automatically tuned your query and return best result with performance.

    In case of JDBC you need to tune your queries.

    You will get benefit of Cache. Hibernate support two level of cache. First level and 2nd level. So you can store your data into Cache for better performance.

    In case of JDBC you need to implement your JAVA cache .

    Hibernate supports Query cache and It will provide the statistics about your query and database status.

    JDBC doest Not provide any statistics.

    Development fast in case of Hibernate because you don't need to write queries.No need to create any connection pool in case of Hibernate. You can use c3p0.

    In case of JDBC you need to write your own connection pool.

    In the XML file you can see all the relations between tables in case of

  • Hibernate

    Hibernate. Easy readability.You can load your objects on start up using lazy=false in case of Hibernate.

    JDBC Don't have such support.

    Hibernate Supports automatic versioning of rows

    JDBC Does Not Support it.

    Advantages of hibernates:

    1.Hibernate supports Inheritance, Associations, Collections

    2.In hibernate if we save the derived class object, then its base class object will also be stored into the database, it means hibernate supporting inheritance

    3. Hibernate supports relationships like One-To-Many, One-To-One, Many-To-Many, Many-To-One

    4. This will also supports collections like List, Set, Map (Only new collections)

    5. In JDBC all exceptions are checked exceptions, so we must write code in try, catch and throws, but in hibernate we only have Unchecked exceptions, so no need to write try, catch, or no need to write throws. Actually in hibernate we have the translator which converts checked to Unchecked

    6. Hibernate has capability to generate primary keys automatically while we are storing the records into database

    7. Hibernate has its own query language, i.e hibernate query language which is database independent So if we change the database, then also our application will works as HQL is database independent

    8. HQL contains database independent commands While we are inserting any record, if we dont have any particular table in the database, JDBC will rises an error like View not exist, and throws exception, but in case of hibernate, if it not found any table in the database this will create the table for us.

    9. Hibernate supports caching mechanism by this, the number of round trips between an application and the database will be reduced, by using this caching technique an application performance will be increased automatically.

    10. Hibernate supports annotations, apart from XML

    11. Hibernate provided Dialect classes, so we no need to write SQL queries in hibernate, instead we use the methods provided by that API.

    12. Getting pagination in hibernate is quite simple.

  • Hibernate

    13. Hibernate takes care of mapping Java classes to database tables using XML files and without writing any line of code.

    14. Provides simple APIs for storing and retrieving Java objects directly to and from the database.

    15. If there is change in Database or in any table then the only need to change XML file properties.

    16. Provides Simple querying of data.

    What is Hibernate ?

    Hibernate is an Object-Relational Mapping(ORM) solution for JAVA and it raised as an open source persistent framework created by Gavin King in 2001.

    It is a powerful, high performance Object-Relational Persistence and Query service for any Java Application.

    Hibernate maps Java classes to database tables and from Java data types to SQL data types.

    Hibernate sits between traditional Java objects and database server to handle all the work in persisting those objects based on the appropriate O/R mechanisms and patterns.

    Supported Databases:Hibernate supports almost all the major RDBMS. Following is list of few of the database engines supported by Hibernate.

    HSQL Database Engine DB2/NT MySQL PostgreSQL FrontBase Oracle Microsoft SQL Server Database Sybase SQL Server Informix Dynamic Server

  • Hibernate

    Supported Technologies:Hibernate supports a variety of other technologies, including the following:

    XDoclet Spring J2EE Eclipse plug-ins Maven

    Hibernate Application Architecture :

    High Level View Detailed View

    Hibernate uses various existing Java APIs, like JDBC, Java Transaction API(JTA), and Java Naming and Directory Interface (JNDI).

    Configuration Object:

    The Configuration object is the first Hibernate object you create in any Hibernate application and usually created only once during application initialization.

    It represents a configuration or properties file required by the Hibernate.

    The Configuration object provides two keys components:1) Database Connection This is handled through one or more configuration files supported by Hibernate. These files are hibernate.properties and hibernate.cfg.xml

    2) Class Mapping Setup This component creates the connection between the

  • Hibernate

    Java classes and database tables.

    SessionFactory Object:

    Configuration object is used to create a SessionFactory object which in turn configures Hibernate for the application using the supplied configuration file and allows for a Session object to be instantiated.

    The SessionFactory is a thread safe object and used by all the threads of an application.

    The SessionFactory is heavyweight object so usually it is created during application start up and kept for later use.

    You would need one SessionFactory object per database using a separate configuration file.

    So if you are using multiple databases then you would have to create multiple SessionFactory objects.

    Session Object:

    A Session is used to get a physical connection with a database. The Session object is lightweight and designed to be instantiated

    each time an interaction is needed with the database. Persistent objects are saved and retrieved through a Session

    object. The session objects should not be kept open for a long time because they are

    not usually thread safe and they should be created and destroyed them as needed.

    Transaction Object:

    A Transaction represents a unit of work with the database and most of the RDBMS supports transaction functionality.

    Transactions in Hibernate are handled by an underlying transaction manager and transaction (from JDBC or JTA).

    This is an optional object and Hibernate applications may choose not to use this interface, instead managing transactions in their own application code.

    Query Object:

    Query objects use SQL or Hibernate Query Language (HQL) string to retrieve data from the database and create objects.

    A Query instance is used to bind query parameters, limit the number of results returned by the query, and finally to execute the query.

  • Hibernate

    Criteria Object:

    Criteria object are used to create and execute object oriented criteria queries to retrieve objects.

    Hibernate Properties:To configure for a databases in a standalone situation

    Properties Description

    hibernate.dialect This property makes Hibernate generate the appropriate SQL for the chosen database.

    hibernate.connection.driver_class The JDBC driver class.

    hibernate.connection.url The JDBC URL to the database instance.

    hibernate.connection.username The database username.

    hibernate.connection.password The database password.

    hibernate.connection.pool_size Limits the number of connections waiting in the Hibernate database connection pool.

    hibernate.connection.autocommit Allows autocommit mode to be used for the JDBC connection.

    The database along with an application server and JNDI then you would have to configure the following properties

    Properties Description

    hibernate.connection.datasource The JNDI name defined in the application server context you are using for the application

    hibernate.jndi.class The InitialContext class for JNDI.

    hibernate.jndi. Passes any JNDI property you like to the JNDI InitialContext

    hibernate.jndi.url Provides the URL for JNDI

    hibernate.connection.username The database username.

    hibernate.connection.password The database password.

    Example hibernate.cfg.xml,

  • Hibernate

    org.hibernate.dialect.MySQLDialect com.mysql.jdbc.Driver

    jdbc:mysql://localhost/test root root123

    The above configuration file includes tags which are related to hibernate-mapping file

    Hibernate Sessions :

    A Session is used to get a physical connection with a database. The Session object is lightweight and designed to be instantiated

    each time an interaction is needed with the database. Persistent objects are saved and retrieved through a Session object. The session objects should not be kept open for a long time because

    they are not usually thread safe and they should be created and destroyed them as needed.

    The main function of the Session is to offer create, read and delete operations for instances of mapped entity classes.

    Instances/Objects(Persistence Class Object) may exist in one of the following three states Transient Persistent Detached

    Transient State :

    When it is just created and has no primary key, the state is called transient.

    If Object is transient, instance has just been instantiated with

  • Hibernate

    new Operator and it's not associated with Hibernate Session. Transient object will be garbage collected if application doesn't

    have any reference any more. Use the Hibernate session to make an Object persistent.

    Example,Car car = new Car();car.setName(BMW);

    Persistent State :

    When the session is opened and the object is just saved in or retrieved from the database. This state is called persistent.

    During this state Hibernate manages the object and saves your changes, if you commit them.

    Below you can see an example. A car is saved and the name is changed afterwards. As the car is in persistent state, the new name will be saved.

    Session session = HibernateSessionFactory.currentSession();tx = session.beginTransaction();session.save(car);car.setName(Peugeot);tx.commit();

    A persistence instance has a representation in database and an identifier value. It might have been just saved or loaded. It will be associated with a hibernate session.

    Object States Life Cycle :

    Detached State :

    When the session was closed, the state changes to detached. The object is detached from its session.

    A detached instance is persistence but its session is closed. It will be modified in the current state if the reference of the object is valid.

    A detached instance can be reattached to a new session ie it persistent again.

    A Session instance is serializable if its persistent classes are serializable. A typical transaction should use the following idiom:

  • Hibernate

    Session session = factory.openSession();Transaction tx = null;try { tx = session.beginTransaction(); // do some work ... tx.commit();}catch (Exception e) { if (tx!=null) tx.rollback(); e.printStackTrace(); }finally { session.close();}

    If the Session throws an exception, the transaction must be rolled back and the session must be discarded.Hibernate Persistent Class :

    Java classes whose objects or instances will be stored in database tables are called persistent classes in Hibernate.

    Hibernate works best if these classes follow some simple rules, also known as the Plain Old Java Object (POJO) programming model.

    POJO Hibernate Rules :

    All Java classes that will be persisted need a default constructor.

    All classes should contain an ID in order to allow easy identification of your objects within Hibernate and the database. This property maps to the primary key column of a database table.

    All attributes that will be persisted should be declared private and have getXXX and setXXX methods defined in the JavaBean style.

    All classes that do not extend or implement some specialized classes and interfaces required by the EJB framework.

    Sample POJO,

    public class Employee { private int id; private String firstName; private String lastName; private int salary;

    public Employee() {} public Employee(String fname, String lname, int salary) { this.firstName = fname; this.lastName = lname; this.salary = salary; }

    Default constructor, Id& private declaration,

  • Hibernate

    public int getId() { return id; } public void setId( int id ) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName( String first_name ) { this.firstName = first_name; } public String getLastName() { return lastName; } public void setLastName( String last_name ) { this.lastName = last_name; } public int getSalary() { return salary; } public void setSalary( int salary ) { this.salary = salary; }}

    Hibernate Mapping Files : An Object/relational mappings are usually defined in an XML

    document. This mapping file instructs Hibernate how to map the defined class

    or classes to the database tables. A number of tools exist to generate the mapping document.

    XDoclet, Middlegen AndroMDA.

    Example,

    public class Employee { private int id; private String firstName; private String lastName; private int salary;

    public Employee() {} public Employee(String fname, String lname, int salary) { this.firstName = fname; this.lastName = lname; this.salary = salary; } public int getId() { return id;

  • Hibernate

    } public void setId( int id ) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName( String first_name ) { this.firstName = first_name; } public String getLastName() { return lastName; } public void setLastName( String last_name ) { this.lastName = last_name; } public int getSalary() { return salary; } public void setSalary( int salary ) { this.salary = salary; }}

    There would be one table corresponding to each object you are willing to provide persistence. Consider above objects need to be stored and retrieved into the following RDBMS table:

    create table EMPLOYEE ( id INT NOT NULL auto_increment, first_name VARCHAR(20) default NULL, last_name VARCHAR(20) default NULL, salary INT default NULL, PRIMARY KEY (id));

    Based on the two above entities we can define following mapping file which instructs Hibernate how to map the defined class or classes to the database tables.

    This class contains the employee detail.

    Java class nameDB table name

    Table primary key

    Table column

    Java datatypeConverts to

    SQL datatype

    Rootelement

    AutomaticPrimary

    Keygenerator

  • Hibernate

    You should save the mapping document in a file with the format .hbm.xml.

    The mapping document is an XML document having as the root element which contains all the elements.

    The elements are used to define specific mappings from a Java classes to the database tables. The Java class name is specified using the name attribute of the class element and the database table name is specified using the table attribute.

    The element is optional element and can be used to create the class description.

    The element maps the unique ID attribute in class to the primary key of the database table. The name attribute of the id element refers to the property in the class and the column attribute refers to the column in the database table. The type attribute holds the hibernate mapping type, this mapping types will convert from Java to SQL data type.

    The element within the id element is used to automatically generate the primary key values. Set the class attribute of the generator element is set to native to let hibernate pick up either identity, sequence or hilo algorithm to create primary key depending upon the capabilities of the underlying database.

    The element is used to map a Java class property to a column in the database table. The name attribute of the element refers to the property in the class and the column attribute refers to the column in the database table. The type attribute holds the hibernate mapping type, this mapping types will convert from Java to SQL data type.

    When you prepare a Hibernate mapping document, we have seen that you map Java data types into RDBMS data types. The types declared and used in the mapping files are not Java data types; they are not SQL database types either. These types are called Hibernate mapping types, which can translate from Java to SQL data types and vice versa.

    The important methods of Session Interfaces are,Session org.hibernate.Session

    Pojoproperty

    Hibernate type

  • Hibernate

    save() persist() saveOrUpdate() merge() delete() get() load() update() lock() replicate()

    Transient instances may be made persistent by calling save(), persist() or saveOrUpdate()

    Persistent instances may be made transient by calling delete()

    Any instance returned by a get() or load() method is persistent

    Detached instances may be made persistent by calling update(), saveOrUpdate(), lock() or replicate()

    The state of a transient or detached instance may also be made persistent as a new persistent instance by calling merge().

    Sample Hibernate CRUD Application :import java.util.List; import java.util.Date;import java.util.Iterator; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.Transaction;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;

    public class ManageEmployee { private static SessionFactory factory; public static void main(String[] args) { try{ factory = new Configuration().configure().buildSessionFactory(); }catch (Throwable ex) { System.err.println("Failed to create sessionFactory object." + ex); throw new ExceptionInInitializerError(ex); } ManageEmployee ME = new ManageEmployee();

    /* Add few employee records in database */ Integer empID1 = ME.addEmployee("Zara", "Ali", 1000); Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);

  • Hibernate

    Integer empID3 = ME.addEmployee("John", "Paul", 10000);

    /* List down all the employees */ ME.listEmployees();

    /* Update employee's records */ ME.updateEmployee(empID1, 5000);

    /* Delete an employee from the database */ ME.deleteEmployee(empID2);

    /* List down new list of the employees */ ME.listEmployees(); } /* Method to CREATE an employee in the database */ public Integer addEmployee(String fname, String lname, int salary){ Session session = factory.openSession(); Transaction tx = null; Integer employeeID = null; try{ tx = session.beginTransaction(); Employee employee = new Employee(fname, lname, salary); employeeID = (Integer) session.save(employee); tx.commit(); }catch (HibernateException e) { if (tx!=null) tx.rollback(); e.printStackTrace(); }finally { session.close(); } return employeeID; } /* Method to READ all the employees */ public void listEmployees( ){ Session session = factory.openSession(); Transaction tx = null; try{ tx = session.beginTransaction(); List employees = session.createQuery("FROM Employee").list(); for (Iterator iterator = employees.iterator(); iterator.hasNext();){ Employee employee = (Employee) iterator.next(); System.out.print("First Name: " + employee.getFirstName()); System.out.print(" Last Name: " + employee.getLastName()); System.out.println(" Salary: " + employee.getSalary()); } tx.commit(); }catch (HibernateException e) { if (tx!=null) tx.rollback(); e.printStackTrace(); }finally { session.close(); } }

  • Hibernate

    /* Method to UPDATE salary for an employee */ public void updateEmployee(Integer EmployeeID, int salary ){ Session session = factory.openSession(); Transaction tx = null; try{ tx = session.beginTransaction(); Employee employee = (Employee)session.get(Employee.class, EmployeeID); employee.setSalary( salary ); session.update(employee); tx.commit(); }catch (HibernateException e) { if (tx!=null) tx.rollback(); e.printStackTrace(); }finally { session.close(); } } /* Method to DELETE an employee from the records */ public void deleteEmployee(Integer EmployeeID){ Session session = factory.openSession(); Transaction tx = null; try{ tx = session.beginTransaction(); Employee employee = (Employee)session.get(Employee.class, EmployeeID); session.delete(employee); tx.commit(); }catch (HibernateException e) { if (tx!=null) tx.rollback(); e.printStackTrace(); }finally { session.close(); } }}Important Hibernate Mappings :

    Collections Mappings: If an entity or class has collection of values for a particular

    variable, then we can map those values using any one of the collection interfaces available in java.

    Hibernate can persist instances of java.util.Map, java.util.Set, java.util.SortedMap, java.util.SortedSet, java.util.List, and any array of persistent entities or values.

    Collection type Mapping and Description

    java.util. Set This is mapped with a element and initialized with java.util.HashSet

  • Hibernate

    java.util. SortedSet This is mapped with a element and initialized with java.util.TreeSet. The sort attribute can be set to either a comparator or natural ordering.

    java.util. List This is mapped with a element and initialized with java.util.ArrayList

    java.util. Collection This is mapped with a or element and initialized with java.util.ArrayList

    java.util. Map This is mapped with a element and initialized with java.util.HashMap

    java.util. SortedMap This is mapped with a element and initialized with java.util.TreeMap. The sort attribute can be set to either a comparator or natural ordering.

    Association Mappings: The mapping of associations between entity classes and the

    relationships between tables is the soul of ORM. An association mapping can be unidirectional as well as bidirectional.

    Mapping type DescriptionMany-to-One Mapping many-to-one relationship using HibernateOne-to-One Mapping one-to-one relationship using HibernateOne-to-Many Mapping one-to-many relationship using HibernateMany-to-Many Mapping many-to-many relationship using Hibernate

    Component Mappings:

    It is very much possible that an Entity class can have a reference to another class as a member variable.

    If the referred class does not have it's own life cycle and completely depends on the life cycle of the owning entity class, then the referred class is called as the Component class.

    The mapping of Collection of Components is also possible in a similar way just as the mapping of regular Collections with minor configuration differences.

    Mapping type DescriptionComponent Mappings Mapping for a class having a reference to another class as a member variable.

  • Hibernate

    Hibernate Using Set in Mapping Files : (java.util.Set)

    A Set is a java collection that does not contain any duplicate element.

    A Set is mapped with a element in the mapping table and initialized with java.util.HashSet.

    It does not require index element not index based contains only unique values

    You can use Set collection in your class when there is no duplicate element required in the collection.

    Example,create table EMPLOYEE ( id INT NOT NULL auto_increment, first_name VARCHAR(20) default NULL, last_name VARCHAR(20) default NULL, salary INT default NULL, PRIMARY KEY (id));

    create table CERTIFICATE ( id INT NOT NULL auto_increment, certificate_name VARCHAR(30) default NULL, employee_id INT default NULL, PRIMARY KEY (id));

    There will be one-to-many relationship between EMPLOYEE and CERTIFICATE objectsimport java.util.*;

    public class Employee { private int id; private String firstName; private String lastName; private int salary; private Set certificates;

    public Employee() {} public Employee(String fname, String lname, int salary) { this.firstName = fname; this.lastName = lname; this.salary = salary; } getter ... setter ...}

    public class Certificate { private int id; private String name;

  • Hibernate

    public Certificate() {} public Certificate(String name) { this.name = name; }

    getter ...setter ...

    public boolean equals(Object obj) { if (obj == null) return false; if (!this.getClass().equals(obj.getClass())) return false;

    Certificate obj2 = (Certificate)obj; if((this.id == obj2.getId()) && (this.name.equals(obj2.getName()))) { return true; } return false; } public int hashCode() { int tmp = 0; tmp = ( id + name ).hashCode(); return tmp; }}

    Mapping .hbm File :

    This class contains the employee detail.

    Set mapping definitions

    element tag is usedIf stores string values in

    Collection instead ofEntity reference

    Inside

  • Hibernate

    This class contains the certificate records.

    The element is new here and has been introduced to set the relationship between Certificate and Employee classes.

    We used the cascade attribute in the element to tell Hibernate to persist the Certificate objects at the same time as the Employee objects.

    The name attribute is set to the defined Set variable in the parent class, in our case it is certificates.

    For each set variable, we need to define a separate set element in the mapping file.

    The element is the column in the CERTIFICATE table that holds the foreign key to the parent object ie. table EMPLOYEE.

    The element indicates that one Employee object relates to many Certificate objects.

    You can use either , or elements based on your requirement.

    Using SortedSet (java.util.SortedSet) :

    A SortedSet is a java collection that does not contain any duplicate element and elements are ordered using their natural ordering or by a comparator provided.

    A SortedSet is mapped with a element in the mapping table and initialized with java.util.TreeSet.

    The sort attribute can be set to either a comparator or natural ordering.

  • Hibernate

    If we use natural ordering then its iterator will traverse the set in ascending element order.

    Example,Same Table Employee and Certificate which has been used the above scenario.import java.util.*;

    public class Employee { private int id; private String firstName; private String lastName; private int salary; private SortedSet certificates;

    public Employee() {} public Employee(String fname, String lname, int salary) { this.firstName = fname; this.lastName = lname; this.salary = salary; } getters ... setters ...}

    The following class should also implement Comparable interface and compareTo method which will be used to sort the elements in case you set sort="natural" in your mapping file (see below mapping file).

    public class Certificate implements Comparable { private int id; private String name;

    public Certificate() {} public Certificate(String name) { this.name = name; }

    getters ...setters ...

    public int compareTo(Certificate that){ final int BEFORE = -1; final int AFTER = 1;

    if (that == null) { return BEFORE; }

    Comparable thisCertificate = this.getName(); Comparable thatCertificate = that.getName();

    if(thisCertificate == null) { return AFTER;

  • Hibernate

    } else if(thatCertificate == null) { return BEFORE; } else { return thisCertificate.compareTo(thatCertificate); } }}

    This class contains the employee detail.

    This class contains the certificate records.

    The sort attribute can be set to natural to have natural sorting or it can be set to a custom class implementing java.util.Comparator. We have used a class MyClass which implements java.util.Comparator to reverse the sorting order implemented in Certificate class.If we use sort="natural" setting then we do not need to create a separate class because Certificate class already has implemented Comparable interface and hibernate will use compareTo() method defined in Certificate class to compare certificate names.

    Sorting processSort = natural or

    Sort = userdefined class

    Foreign keyrelationships

  • Hibernate

    But we are using a custom comparator class MyClass in our mapping file so we would have to create this class based on our sorting algorithm. Let us do descending sorting in this class using this class.import java.util.Comparator;

    public class MyClass implements Comparator{ public int compare(Certificate o1, Certificate o2) { final int BEFORE = -1; final int AFTER = 1;

    /* To reverse the sorting order, multiple by -1 */ if (o2 == null) { return BEFORE * -1; }

    Comparable thisCertificate = o1.getName(); Comparable thatCertificate = o2.getName();

    if(thisCertificate == null) { return AFTER * 1; } else if(thatCertificate == null) { return BEFORE * -1; } else { return thisCertificate.compareTo(thatCertificate) * -1; } }}

    Using List :

    A List is a java collection that stores elements in sequence and allow duplicate elements and multiple null elements.

    The user can access elements by their integer index, and search for elements in the list.

    Its an index based and contains index column

    A List is mapped with a element in the mapping table and initialized with java.util.ArrayList.

    import java.util.*;

    public class Employee { private int id; private String firstName; private String lastName; private int salary; private List certificates;

    public Employee() {} public Employee(String fname, String lname, int salary) { this.firstName = fname; this.lastName = lname;

  • Hibernate

    this.salary = salary; } getters and setters ...}

    This class contains the employee detail.

    This class contains the certificate records.

    The element is used to keep the position of the element and map with the index column in the collection table.

    The index of the persistent list starts at zero. You could change this, for example, with in your mapping.

    Using Collection (java.util.Collection) :

    A Bag is a java collection that stores elements without caring about the sequencing but allow duplicate elements in the list.

    Index of the element

    One-to-many tag is used Inside to store

    Entity reference in list

    element tag is usedIf stores string values in

    Collection instead ofEntity reference

    Inside

  • Hibernate

    A bag is a random grouping of the objects in the list. Its not index based and does not contain any index column

    A Collection is mapped with a element in the mapping table and initialized with java.util.ArrayList.

    Example,import java.util.*;

    public class Employee { private int id; private String firstName; private String lastName; private int salary; private Collection certificates;

    public Employee() {} public Employee(String fname, String lname, int salary) { this.firstName = fname; this.lastName = lname; this.salary = salary; } getters and setters ...}

    This class contains the employee detail.

    This class contains the certificate records.

    One-to-many tag is usedInside

    element tag is usedIf stores string values in

    Collection instead ofEntity reference

  • Hibernate

    The element is used to set the relationship between Certificate and Employee classes

    Using Map (java.util.Map) :

    A Map is a java collection that stores elements in key-value pairs and does not allow duplicate elements in the list.

    Its an index based collection

    The Map interface provides three collection views, which allow a map's contents to be viewed as a collection of values, or set of Keys set of key-value mappings.

    A Map is mapped with a element in the mapping table and an unordered map can be initialized with java.util.HashMap.

    Example,import java.util.*;

    public class Employee { private int id; private String firstName; private String lastName; private int salary; private Map certificates;

    public Employee() {} public Employee(String fname, String lname, int salary) { this.firstName = fname; this.lastName = lname; this.salary = salary; } getters and setters ...}

  • Hibernate

    This class contains the employee detail.

    This class contains the certificate records.

    The element is used to represents the key parts of the key/value map pair. The key will be stored in the column certificate_type using a type of string.

    Using SortedMap (java.util.SortedMap):

    A SortedMap is a similar java collection as Map that stores elements in key-value pairs and provides a total ordering on its keys.

    Duplicate elements are not allowed in the map. The map is ordered according to the natural ordering of its keys, or by a Comparator typically provided at sorted map creation time.

    A SortedMap is mapped with a element in the mapping table and an ordered map can be initialized with java.util.TreeMap.

    import java.util.*;

    public class Employee { private int id; private String firstName; private String lastName; private int salary; private SortedMap certificates;

    Key part in Map

    One-to-many tag is Used Inside

    element tag is usedIf stores string values in

    Collection instead ofEntity reference hereIs is value

    part

  • Hibernate

    public Employee() {} public Employee(String fname, String lname, int salary) { this.firstName = fname; this.lastName = lname; this.salary = salary; } setters and getters ...}

    This class contains the employee detail.

    This class contains the certificate records.

    One-to-many Examples with Collection Mappings

    Same sort conceptsUsed in above

    SortedSet Scenario

    One-to-many tag is usedInside

  • Hibernate

    Table CreationCREATE TABLE `department` ( `department_id` BIGINT(20) NOT NULL AUTO_INCREMENT, `dept_name` VARCHAR(50) NOT NULL DEFAULT '0', PRIMARY KEY (`department_id`))COLLATE='latin1_swedish_ci'ENGINE=InnoDBROW_FORMAT=DEFAULTAUTO_INCREMENT=115

    CREATE TABLE `employee` ( `employee_id` BIGINT(10) NOT NULL AUTO_INCREMENT, `firstname` VARCHAR(50) NULL DEFAULT NULL, `lastname` VARCHAR(50) NULL DEFAULT NULL, `birth_date` DATE NULL DEFAULT NULL, `cell_phone` VARCHAR(15) NULL DEFAULT NULL, `department_id` BIGINT(20) NULL DEFAULT NULL, PRIMARY KEY (`employee_id`), INDEX `FK_DEPT` (`department_id`), CONSTRAINT `FK_DEPT` FOREIGN KEY (`department_id`) REFERENCES `department` (`department_id`))COLLATE='latin1_swedish_ci'ENGINE=InnoDBROW_FORMAT=DEFAULT

    Model Class Persistent Class

    Department :public class Department { private Long departmentId; private String departmentName;

  • Hibernate

    private Set employees; // Getter and Setter methods}Employee :public class Employee { private Long employeeId; private String firstname; private String lastname; private Date birthDate; private String cellphone; private Department department; public Employee() { } public Employee(String firstname, String lastname, Date birthdate, String phone) { this.firstname = firstname; this.lastname = lastname; this.birthDate = birthdate; this.cellphone = phone; } // Getter and Setter methods}Hibernate Utillimport org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;

  • Hibernate

    public class HibernateUtil { private static final SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { try { // Create the SessionFactory from hibernate.cfg.xml return new Configuration().configure().buildSessionFactory(); } catch (Throwable ex) { System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; }}Employee hbm file

  • Hibernate

    Department hbm file

    Execute exampleimport org.hibernate.Session;import org.hibernate.SessionFactory; public class Main {

  • Hibernate

    public static void main(String[] args) { SessionFactory sf = HibernateUtil.getSessionFactory(); Session session = sf.openSession(); session.beginTransaction(); Department department = new Department(); department.setDepartmentName("Sales"); session.save(department); Employee emp1 = new Employee("Nina", "Mayers", "1212"); Employee emp2 = new Employee("Tony", "Almeida", "4343"); emp1.setDepartment(department); emp2.setDepartment(department); session.save(emp1); session.save(emp2); session.getTransaction().commit(); session.close(); }}OutputHibernate: insert into DEPARTMENT (DEPT_NAME) values (?)Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone, department_id) values (?, ?, ?, ?, ?)Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone, department_id) values (?, ?, ?, ?, ?)

    One-to-Many exampleA is an unordered collection, which can contain duplicated elements. That means if you persist a bag with some order of elements, you cannot expect the same order retains when the collection is retrieved. There is not a bag concept in Java collections framework, so we just use a java.util.List correspond to a .

    To implement Bag in our one-to-many mapping example, we will do following changes:

    Department

  • Hibernate

    import java.util.ArrayList;import java.util.List; public class Department { private Long departmentId; private String departmentName; private List employees; // Getter and Setter methods }Department hbm file

  • Hibernate

    outputHibernate: insert into DEPARTMENT (DEPT_NAME) values (?)Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone, department_id) values (?, ?, ?, ?, ?)Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone, department_id) values (?, ?, ?, ?, ?)

    One-to-Many exampleA is an indexed collection where the index will also be persisted. That means we can retain the order of the list when it is retrieved. It differs from for it persists the element Index while a does not. The corresponding type of a in Java is java.util.List.

    To implement List in our one-to-many mapping example, we will do following changes:

    8.1 Add Index Column in Employee TableDROP TABLE if exists `employee`;

    CREATE TABLE `employee` (

    `employee_id` BIGINT(10) NOT NULL AUTO_INCREMENT,

    `firstname` VARCHAR(50) NULL DEFAULT NULL,

    `lastname` VARCHAR(50) NULL DEFAULT NULL,

    `birth_date` DATE NULL DEFAULT NULL,

    `cell_phone` VARCHAR(15) NULL DEFAULT NULL,

    `department_id` BIGINT(20) NULL DEFAULT NULL,

    `idx` INT(11) NOT NULL DEFAULT '0', PRIMARY KEY (`employee_id`),

    INDEX `FK_DEPT` (`department_id`),

    CONSTRAINT `FK_DEPT` FOREIGN KEY (`department_id`) REFERENCES `department` (`department_id`)

    )

    COLLATE='latin1_swedish_ci'

    ENGINE=InnoDB

    ROW_FORMAT=DEFAULT

    Departmentimport java.util.List;

    public class Department {

    private Long departmentId;

  • Hibernate

    private String departmentName;

    private List employees;

    // Getter and Setter methods

    }Department hbm file

    outputHibernate: insert into DEPARTMENT (DEPT_NAME) values (?)Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone) values (?, ?, ?, ?)Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone) values (?, ?, ?, ?)Hibernate: update EMPLOYEE set department_id=?, idx=? where EMPLOYEE_ID=?Hibernate: update EMPLOYEE set department_id=?, idx=? where EMPLOYEE_ID=?

  • Hibernate

    One-to-Many exampleAn has the same usage as a except that it corresponds to an Array type in Java and not a java.util.List. It is rarely used unless we are mapping for legacy applications. In most cases, we should use instead. That is because the size of an array cannot be increased or decreased dynamically, where as a list can.

    To implement Array in our one-to-many mapping example, we will do following changes:

    public class Department {

    private Long departmentId;

    private String departmentName;

    private Employee[] employees;

    // Getter and Setter methods

    }

    We simply change the List of Employees to Array of Employee [].

  • Hibernate

    OutputHibernate: insert into DEPARTMENT (DEPT_NAME) values (?)Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone) values (?, ?, ?, ?)Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone) values (?, ?, ?, ?)Hibernate: update EMPLOYEE set department_id=?, idx=? where EMPLOYEE_ID=?Hibernate: update EMPLOYEE set department_id=?, idx=? where EMPLOYEE_ID=?

    Association :

    Many-to-One :

    This class contains the employee detail.

    Seperate tagIs used here

  • Hibernate

    This class contains the address detail.

    The element is used to set the relationship between EMPLOYEE and ADDRESS entities. Multiple EMPLOYEE'S can contain the same ADDRESS here

    One-to-One :

    A one-to-one association is similar to many-to-one association with a difference that the column will be set as unique. For example an address object can be associated with a single employee object.

    The element will be used to define the rule to establish a one-to-one relationship between EMPLOYEE and ADDRESS entities but column attribute will be set to unique constraint.

    This class contains the employee detail.

    Many-to-OneRelationships

    One-to-oneRelationship

    But usedMany-to-one

    element

    Seperate tagIs used here

  • Hibernate

    This class contains the address detail.

    The element is used to set the relationship between EMPLOYEE and ADDRESS entities. The column attribute which is set to unique so that only one Employee object can be associated with an address object.

    We can use in both persistent class for mapping one-to-one relationship. This is another way to implement.

    This class contains the employee detail.

    This class contains the address detail.

    Set uniqueConstraint to make

    The one-to-one mapping

    One-to-oneRelationship

  • Hibernate

    One-to-Many :

    A One-to-Many mapping can be implemented using a Set java collection

    This class contains the employee detail.

    This class contains the certificate records.

    Many-to-Many :

    A Many-to-Many mapping can be implemented using a Set java collection

    One-to-many tag is usedInside

    One-to-oneRelationship

  • Hibernate

    This class contains the employee detail.

    This class contains the certificate records.

    Hibernate One To One Mapping Tutorial (XML Mapping)Example,/* EMPLOYEE table */CREATE TABLE `employee` ( `employee_id` BIGINT(10) NOT NULL AUTO_INCREMENT, `firstname` VARCHAR(50) NULL DEFAULT NULL, `lastname` VARCHAR(50) NULL DEFAULT NULL, `birth_date` DATE NOT NULL, `cell_phone` VARCHAR(15) NOT NULL, PRIMARY KEY (`employee_id`))COLLATE='latin1_swedish_ci'ENGINE=InnoDBROW_FORMAT=DEFAULTAUTO_INCREMENT=216 /* EMPLOYEEDETAIL table */CREATE TABLE `employeedetail` ( `employee_id` BIGINT(20) NOT NULL AUTO_INCREMENT, `street` VARCHAR(50) NULL DEFAULT NULL, `city` VARCHAR(50) NULL DEFAULT NULL, `state` VARCHAR(50) NULL DEFAULT NULL,

    Table is usedTo displayAll records

    Many-to-many tagIs used inside

  • Hibernate

    `country` VARCHAR(50) NULL DEFAULT NULL, PRIMARY KEY (`employee_id`), CONSTRAINT `FKEMPL` FOREIGN KEY (`employee_id`) REFERENCES `employee` (`employee_id`))COLLATE='latin1_swedish_ci'ENGINE=InnoDBROW_FORMAT=DEFAULTAUTO_INCREMENT=216

    public class Employee { private Long employeeId; private String firstname; private String lastname; private Date birthDate; private String cellphone; private EmployeeDetail employeeDetail; public Employee() { } public Employee(String firstname, String lastname, Date birthdate, String phone) { this.firstname = firstname; this.lastname = lastname; this.birthDate = birthdate; this.cellphone = phone; } // Getter and Setter methods }

    public class EmployeeDetail { private Long employeeId; private String street; private String city; private String state; private String country; private Employee employee; public EmployeeDetail() { } public EmployeeDetail(String street, String city, String state, String country) { this.street = street; this.city = city; this.state = state; this.country = country; }

  • Hibernate

    // Getter and Setter methods }

    Note that in above model classes, employeeId is common. This is the primary key of Employee table that exhibits One-to-one relationship with EmployeeDetail table.

    employee

    Note that in above hibernate mapping we are implementing One-to-one relationship. For both the model classes we are using a single primary key EmployeeId. In EmployeeDetail hbm file we have defined a foreign identifier generator so that primary it uses primary key of Employee table.

  • Hibernate

    com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/tutorial root 1 org.hibernate.dialect.MySQLDialect thread org.hibernate.cache.NoCacheProvider true validate

    import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration; public class HibernateUtil { private static final SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { try { // Create the SessionFactory from hibernate.cfg.xml return new Configuration() .configure() .buildSessionFactory(); } catch (Throwable ex) { System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; }}

    public class Main { public static void main(String[] args) { SessionFactory sf = HibernateUtil.getSessionFactory(); Session session = sf.openSession(); session.beginTransaction();

  • Hibernate

    EmployeeDetail employeeDetail = new EmployeeDetail("10th Street", "LA", "San Francisco", "U.S."); Employee employee = new Employee("Nina", "Mayers", new Date(121212), "114-857-965"); employee.setEmployeeDetail(employeeDetail); employeeDetail.setEmployee(employee); session.save(employee); List employees = session.createQuery("from Employee").list(); for (Employee employee1 : employees) { System.out.println(employee1.getFirstname() + " , " + employee1.getLastname() + ", " + employee1.getEmployeeDetail().getState()); } session.getTransaction().commit(); session.close(); }}

    Output

    Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone) values (?, ?, ?, ?)Hibernate: insert into EMPLOYEEDETAIL (STREET, CITY, STATE, COUNTRY, EMPLOYEE_ID) values (?, ?, ?, ?, ?)Hibernate: select employee0_.EMPLOYEE_ID as EMPLOYEE1_1_, employee0_.firstname as firstname1_, employee0_.lastname as lastname1_, employee0_.birth_date as birth4_1_, employee0_.cell_phone as cell5_1_ from EMPLOYEE employee0_Hibernate: select employeede0_.EMPLOYEE_ID as EMPLOYEE1_0_0_, employeede0_.STREET as STREET0_0_, employeede0_.CITY as CITY0_0_, employeede0_.STATE as STATE0_0_, employeede0_.COUNTRY as COUNTRY0_0_ from EMPLOYEEDETAIL employeede0_ where employeede0_.EMPLOYEE_ID=?Nina , Mayers, San Francisco

    Hibernate One To One Annotation Mapping Tutorialimport java.sql.Date; import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.OneToOne;import javax.persistence.Table;

  • Hibernate

    @Entity@Table(name="EMPLOYEE")public class Employee { @Id @GeneratedValue @Column(name="employee_id") private Long employeeId; @Column(name="firstname") private String firstname; @Column(name="lastname") private String lastname; @Column(name="birth_date") private Date birthDate; @Column(name="cell_phone") private String cellphone; @OneToOne(mappedBy="employee", cascade=CascadeType.ALL) private EmployeeDetail employeeDetail; public Employee() { } public Employee(String firstname, String lastname, Date birthdate, String phone) { this.firstname = firstname; this.lastname = lastname; this.birthDate = birthdate; this.cellphone = phone; } // Getter and Setter methods}

    import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.OneToOne;import javax.persistence.PrimaryKeyJoinColumn;import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator;import org.hibernate.annotations.Parameter; @Entity@Table(name="EMPLOYEEDETAIL")public class EmployeeDetail { @Id

  • Hibernate

    @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 employee; public EmployeeDetail() { } public EmployeeDetail(String street, String city, String state, String country) { this.street = street; this.city = city; this.state = state; this.country = country; } // Getter and Setter methods}

    Note that in EmployeeDetail class we have used @GenericGenerator to specify primary key. This will ensure that the primary key from Employee table is used instead of generating a new one.

    Hibernate-configuration file

    Instead of using the following tag rest of all same as above

    Hibernate Utill

    Instead of Configuration here using the AnnotationConfiguration class to create configuration objectreturn new AnnotationConfiguration().configure().buildSessionFactory();

    Many-to-one Mapping using Annotation :

  • Hibernate

    @Entity@Table(name="EMPLOYEE")public class Employee { @Id @GeneratedValue @Column(name="employee_id") private Long employeeId; @Column(name="firstname") private String firstname; @Column(name="lastname") private String lastname; @Column(name="birth_date") private Date birthDate; @Column(name="cell_phone") private String cellphone; @ManyToOne @JoinColumn(name="department_id") private Department department; public Employee() { } public Employee(String firstname, String lastname, String phone) { this.firstname = firstname; this.lastname = lastname; this.birthDate = new Date(System.currentTimeMillis()); this.cellphone = phone; } // Getter and Setter methods}

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

  • Hibernate

    @GeneratedValue @Column(name="DEPARTMENT_ID") private Long departmentId; @Column(name="DEPT_NAME") private String departmentName; @OneToMany(mappedBy="department") Accept only unique values private Set employees; // Getter and Setter methods}

    mappedBy refers to the property name of the association on the owner side. In our case, this is passport. As you can see, you dont have to (must not) declare the join column since it has already been declared on the owners side.

    Implemented Classpublic class Main { @SuppressWarnings("unchecked") public static void main(String[] args) { SessionFactory sf = HibernateUtil.getSessionFactory(); Session session = sf.openSession(); session.beginTransaction(); Department department = new Department(); department.setDepartmentName("Sales"); session.save(department); Employee emp1 = new Employee("Nina", "Mayers", "111"); Employee emp2 = new Employee("Tony", "Almeida", "222"); emp1.setDepartment(department); emp2.setDepartment(department); session.save(emp1); session.save(emp2); session.getTransaction().commit(); session.close(); }}

    OutputHibernate: insert into DEPARTMENT (DEPT_NAME) values (?)Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone, department_id) values (?, ?, ?, ?, ?)Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone, department_id) values (?, ?, ?, ?, ?)

  • Hibernate

    One- To Many Bi-directional Indexed mappingCREATE TABLE `employee` ( `employee_id` BIGINT(10) NOT NULL AUTO_INCREMENT, `firstname` VARCHAR(50) NULL DEFAULT NULL, `lastname` VARCHAR(50) NULL DEFAULT NULL, `birth_date` DATE NULL DEFAULT NULL, `cell_phone` VARCHAR(15) NULL DEFAULT NULL, `department_id` BIGINT(20) NULL DEFAULT NULL, `idx` INT(11) NULL DEFAULT NULL, PRIMARY KEY (`employee_id`), INDEX `FK_DEPT` (`department_id`), CONSTRAINT `FK_DEPT` FOREIGN KEY (`department_id`) REFERENCES `department` (`department_id`))

    @Entity@Table(name="DEPARTMENT")public class Department { @Id @GeneratedValue @Column(name="DEPARTMENT_ID") private Long departmentId; @Column(name="DEPT_NAME") private String departmentName; @OneToMany(cascade={CascadeType.ALL}) @JoinColumn(name="department_id") @IndexColumn(name="idx") private List employees; // Getter and Setter methods}

    Note that in Department entity class, we removed mappedBy clause from @OneToMany. This mark Department as the relationship owner and make it responsible to update foreign keys and index values.

    Also we specified index column using @IndexColumn annotation to specify which column in Employee table we would like to store index in.

    @Entity@Table(name="EMPLOYEE")public class Employee { @Id @GeneratedValue @Column(name="employee_id") private Long employeeId; @Column(name="firstname")

  • Hibernate

    private String firstname; @Column(name="lastname") private String lastname; @Column(name="birth_date") private Date birthDate; @Column(name="cell_phone") private String cellphone; @ManyToOne @JoinColumn(name="department_id", Foreign Key insertable=false, updatable=false, nullable=false) private Department department; public Employee() { } public Employee(String firstname, String lastname, String phone) { this.firstname = firstname; this.lastname = lastname; this.birthDate = new Date(System.currentTimeMillis()); this.cellphone = phone; } // Getter and Setter methods}

    public class Main { @SuppressWarnings("unchecked") public static void main(String[] args) { SessionFactory sf = HibernateUtil.getSessionFactory(); Session session = sf.openSession(); session.beginTransaction(); Department department = new Department(); department.setDepartmentName("Sales"); Employee emp1 = new Employee("Nina", "Mayers", "111"); Employee emp2 = new Employee("Tony", "Almeida", "222"); department.setEmployees(new ArrayList()); department.getEmployees().add(emp1); department.getEmployees().add(emp2); session.save(department); session.getTransaction().commit(); session.close(); }}

  • Hibernate

    OutputHibernate: insert into DEPARTMENT (DEPT_NAME) values (?)Hibernate: insert into EMPLOYEE (birth_date, cell_phone, firstname, lastname) values (?, ?, ?, ?)Hibernate: insert into EMPLOYEE (birth_date, cell_phone, firstname, lastname) values (?, ?, ?, ?)Hibernate: update EMPLOYEE set department_id=?, idx=? where employee_id=?Hibernate: update EMPLOYEE set department_id=?, idx=? where employee_id=?

    Many-to-many

    CREATE TABLE `employee` ( `employee_id` BIGINT(10) NOT NULL AUTO_INCREMENT, `firstname` VARCHAR(50) NULL DEFAULT NULL, `lastname` VARCHAR(50) NULL DEFAULT NULL, PRIMARY KEY (`employee_id`)) CREATE TABLE `meeting` ( `meeting_id` BIGINT(20) NOT NULL AUTO_INCREMENT, `subject` VARCHAR(50) NOT NULL, `meeting_date` DATE NOT NULL, PRIMARY KEY (`meeting_id`)) CREATE TABLE `employee_meeting` ( `employee_id` BIGINT(20) NOT NULL, `meeting_id` BIGINT(20) NOT NULL, PRIMARY KEY (`employee_id`, `meeting_id`), INDEX `FK_MEETING` (`meeting_id`),

  • Hibernate

    CONSTRAINT `FK_EMPLOYEE` FOREIGN KEY (`employee_id`) REFERENCES `employee` (`employee_id`), CONSTRAINT `FK_MEETING` FOREIGN KEY (`meeting_id`) REFERENCES `meeting` (`meeting_id`))

    public class Employee { private Long employeeId; private String firstname; private String lastname; private Set meetings = new HashSet(); public Employee() { } public Employee(String firstname, String lastname) { this.firstname = firstname; this.lastname = lastname; } // Getter and Setter methods}

    public class Meeting { private Long meetingId; private String subject; private Date meetingDate; private Set employees = new HashSet(); public Meeting(String subject) { this.subject = subject; this.meetingDate = new Date(); } // Getter and Setter methods}

  • Hibernate

    One thing is worth noting here is that we have mentioned keyword inverse=true in Meeting class which makes Employee as relationship owner. Thus Employee model takes care of updating referential keys in dependent models

    public class Main { public static void main(String[] args) { SessionFactory sf = HibernateUtil.getSessionFactory(); Session session = sf.openSession(); session.beginTransaction(); Meeting meeting1 = new Meeting("Quaterly Sales meeting"); Meeting meeting2 = new Meeting("Weekly Status meeting"); Employee employee1 = new Employee("Sergey", "Brin"); Employee employee2 = new Employee("Larry", "Page"); employee1.getMeetings().add(meeting1); employee1.getMeetings().add(meeting2); employee2.getMeetings().add(meeting1); session.save(employee1); session.save(employee2); session.getTransaction().commit(); session.close(); }}

  • Hibernate

    OutputHibernate: insert into EMPLOYEE (firstname, lastname) values (?, ?)Hibernate: insert into MEETING (SUBJECT, MEETING_DATE) values (?, ?)Hibernate: insert into MEETING (SUBJECT, MEETING_DATE) values (?, ?)Hibernate: insert into EMPLOYEE (firstname, lastname) values (?, ?)Hibernate: insert into EMPLOYEE_MEETING (EMPLOYEE_ID, MEETING_ID) values (?, ?)Hibernate: insert into EMPLOYEE_MEETING (EMPLOYEE_ID, MEETING_ID) values (?, ?)Hibernate: insert into EMPLOYEE_MEETING (EMPLOYEE_ID, MEETING_ID) values (?, ?)

    Many-to-many Annotation@Entity@Table(name="EMPLOYEE")public class Employee { @Id @Column(name="EMPLOYEE_ID") @GeneratedValue private Long employeeId; @Column(name="FIRSTNAME") private String firstname; @Column(name="LASTNAME") private String lastname; @ManyToMany(cascade = {CascadeType.ALL}) @JoinTable(name="EMPLOYEE_MEETING", joinColumns={@JoinColumn(name="EMPLOYEE_ID")}, inverseJoinColumns={@JoinColumn(name="MEETING_ID")}) private Set meetings = new HashSet(); public Employee() { } public Employee(String firstname, String lastname) { this.firstname = firstname; this.lastname = lastname; } // Getter and Setter methods}

  • Hibernate

    @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 employees = new HashSet(); public Meeting(String subject) { this.subject = subject; this.meetingDate = new Date(); } // Getter and Setter methods}

    @ManyToMany Is used to create many-to-many relationship between Employee and Meeting entities.

    Employee is defined as relationship owner as @JoinColumn is define in Employee class and mappedBy is specified in Meeting class@JoinTable Is used to define the join table (link table) for many-to-many relationship

    @JoinColumn Is used to define the join column (linking column) in both main tables.

    Component Mappings :

    A Component mapping is a mapping for a class having a reference to another class as a member variable.

    We have seen such mapping while having two tables and using element in the mapping file.

    Now we will use element in the mapping file and a single table would be used to keep the attributes contained inside the class variable.

    import java.util.*;

    public class Employee implements java.io.Serializable { private int id; private String firstName; private String lastName; private int salary;

  • Hibernate

    private Address address;

    public Employee() {} public Employee(String fname, String lname, int salary, Address address ) { this.firstName = fname; this.lastName = lname; this.salary = salary; this.address = address; } getters and setters ...}

    import java.util.*;

    public class Address{ private int id; private String street; private String city; private String state; private String zipcode;

    public Address() {} public Address(String street, String city, String state, String zipcode) { this.street = street; this.city = city; this.state = state; this.zipcode = zipcode; } getters and setters ... }

    This class contains the employee detail.

    Mention Address classAttributes Inside

    tag

  • Hibernate

    The element sets the existence of different attributes of Address class inside Employee classes.

    public class App {

    public static void main(String[] args) { System.out.println("Hibernate component mapping"); Session session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); Address address = new Address(); address.setStreet("Street"); address.setCity("City"); address.setState("State");

    address.setZipCode("ZipcOde"); Customer cust = new Customer(); cust.setCustName("mkyong"); cust.setAge(30); cust.setAddress(address); cust.setCreatedDate(new Date()); cust.setCreatedBy("system"); session.save(cust); session.getTransaction().commit(); System.out.println("Done"); }}

    INSERT

    INTO

    mkyongdb.customer

    (STREET, CITY, STATE, ZIPCODE, FIRSTNAME, LASTNAME, SALARY)

  • Hibernate

    VALUES

    (?, ?, ?, ?, ?, ?, ?)

    Hibernate Annotations :

    Hibernate Annotations is the powerful way to provide the meta-data for the Object and Relational Table mapping. import javax.persistence.*;

    @Entity@Table(name = "EMPLOYEE")public class Employee { @Id @GeneratedValue @Column(name = "id") private int id;

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

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

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

    public Employee() {} getters and setters ...}

    @Entity :

    The EJB 3 standard annotations are contained in the javax.persistence package, so we import this package as the first step.

    Second we used the @Entity annotation to the Employee class which marks this class as an entity bean, so it must have a no-argument constructor that is visible with at least protected scope.

    @Table :

    The @Table annotation allows you to specify the details of the table that will be used to persist the entity in the database.

    The @Table annotation provides four attributes, allowing you to override the name of the table, its catalogue, and its schema, and enforce unique constraints on columns in the table. For now we are using just table name which is EMPLOYEE.

  • Hibernate

    @Id and @GeneratedValue :

    Each entity bean will have a primary key, which you annotate on the class with the @Id annotation.

    The primary key can be a single field or a combination of multiple fields depending on your table structure.

    By default, the @Id annotation will automatically determine the most appropriate primary key generation strategy to be used.

    But you can override this by applying the @GeneratedValue annotation which takes two parameters strategy and generator.

    @Column :

    The @Column annotation is used to specify the details of the column to which a field or property will be mapped. You can use column annotation with the following most commonly used attributes:

    name attribute permits the name of the column to be explicitly specified.

    Length attribute permits the size of the column used to map a value particularly for a String value.

    Nullable attribute permits the column to be marked NOT NULL when the schema is generated.

    Unique attribute permits the column to be marked as containing only unique values.

    Hibernate Query Language (HQL):

    Hibernate Query Language (HQL) is an object-oriented query language, similar to SQL, but instead of operating on tables and columns, HQL works with persistent objects and their properties.

    It doesn't depend on the table of the database, instead of table name we use class name.

    HQL queries are translated by Hibernate into conventional SQL queries which in turns perform action on database.

    Although you can use SQL statements directly with Hibernate using Native SQL but I would recommend to use HQL whenever possible to avoid database portability hassles, and to take advantage of Hibernate's SQL generation and caching strategies.

    Keywords like SELECT , FROM and WHERE etc. are not case sensitive but properties like table and column names are case sensitive in HQL.

  • Hibernate

    The main difference between is HQL uses class name instead of table name, and property names instead of column name.

    Advantages :

    Database independent supports polymorphic queries

    FROM Clause :

    You will use FROM clause if you want to load a complete persistent objects into memory. Following is the simple syntax of using FROM clause:

    String hql = "FROM Employee";Query query = session.createQuery(hql);List results = query.list();

    If you need to fully qualify a class name in HQL, just specify the package and class name as follows:

    String hql = "FROM com.hibernatebook.criteria.Employee";Query query = session.createQuery(hql);List results = query.list();

    String hql = "FROM com.hibernatebook.criteria.Employee Where id=:id";Query query = session.createQuery(hql);query.setParameter(id, 123);List results = query.list();

    AS Clause :

    The AS clause can be used to assign aliases to the classes in your HQL queries, specially when you have long queries. For instance, our previous simple example would be the following:

    String hql = "FROM Employee AS E";Query query = session.createQuery(hql);List results = query.list();

    The AS keyword is optional and you can also specify the alias directly after the class name, as follows:

    String hql = "FROM Employee E";Query query = session.createQuery(hql);List results = query.list();

    SELECT Clause :

    The SELECT clause provides more control over the result set than the

    Fully qualified class name

    Without AS keyword

  • Hibernate

    from clause.

    If you want to obtain few properties of objects instead of the complete object, use the SELECT clause.

    Following is the simple syntax of using SELECT clause to get just first_name field of the Employee object:

    String hql = "SELECT E.firstName FROM Employee E";Query query = session.createQuery(hql);List results = query.list();

    It is notable here that Employee.firstName is a property of Employee object rather than a field of the EMPLOYEE table.

    WHERE Clause :

    If you want to narrow the specific objects that are returned from storage, you use the WHERE clause. Following is the simple syntax of using WHERE clause:String hql = "FROM Employee E WHERE E.id = 10";Query query = session.createQuery(hql);List results = query.list();

    Using Parameters

    String hql = "FROM Employee E WHERE E.id = :empid";Query query = session.createQuery(hql);query.setParameter(empid, 10);List results = query.list();

    ORDER BY Clause :

    To sort your HQL query's results, you will need to use the ORDER BY clause. You can order the results by any property on the objects in the result set either ascending (ASC) or descending (DESC). Following is the simple syntax of using ORDER BY clause:

    String hql = "FROM Employee E WHERE E.id > 10 ORDER BY E.salary DESC";Query query = session.createQuery(hql);List results = query.list();

    If you wanted to sort by more than one property, you would just add the additional properties to the end of the order by clause, separated by commas as follows:

  • Hibernate

    String hql = "FROM Employee E WHERE E.id > 10 " + "ORDER BY E.firstName DESC, E.salary DESC ";Query query = session.createQuery(hql);List results = query.list();

    GROUP BY Clause :

    This clause lets Hibernate pull information from the database and group it based on a value of an attribute and, typically, use the result to include an aggregate value.

    Following is the simple syntax of using GROUP BY clause:String hql = "SELECT SUM(E.salary), E.firtName FROM Employee E " + "GROUP BY E.firstName";Query query = session.createQuery(hql);List results = query.list();

    Using Named Parameters :

    Hibernate supports named parameters in its HQL queries. This makes writing HQL queries that accept input from the user easy and

    you do not have to defend against SQL injection attacks. Following is the simple syntax of using named parameters:

    String hql = "FROM Employee E WHERE E.id = :employee_id";Query query = session.createQuery(hql);query.setParameter("employee_id",10);List results = query.list();

    UPDATE Clause :

    Bulk updates are new to HQL with Hibernate 3, and deletes work differently in Hibernate 3 than they did in Hibernate 2.

    The Query interface now contains a method called executeUpdate() for executing HQL UPDATE or DELETE statements.

    The UPDATE clause can be used to update one or more properties of an one or more objects.

    Following is the simple syntax of using UPDATE clause:

    String hql = "UPDATE Employee set salary = :salary " + "WHERE id = :employee_id";Query query = session.createQuery(hql);query.setParameter("salary", 1000);

    Get user input &Set to named param

  • Hibernate

    query.setParameter("employee_id", 10);int result = query.executeUpdate();System.out.println("Rows affected: " + result);

    DELETE Clause :

    The DELETE clause can be used to delete one or more objects. Following is the simple syntax of using DELETE clause:

    String hql = "DELETE FROM Employee " + "WHERE id = :employee_id";Query query = session.createQuery(hql);query.setParameter("employee_id", 10);int result = query.executeUpdate();System.out.println("Rows affected: " + result);

    INSERT Clause :

    HQL supports INSERT INTO clause only where records can be inserted from one object to another object. Following is the simple syntax of using INSERT INTO clause:

    String hql = "INSERT INTO Employee(firstName, lastName, salary)" + "SELECT firstName, lastName, salary FROM old_employee";Query query = session.createQuery(hql);int result = query.executeUpdate();System.out.println("Rows affected: " + result);

    Aggregate Methods :HQL supports a range of aggregate methods, similar to SQL. They work the same way in HQL as in SQL and following is the list of the available functions:S.N. Functions Description1 avg(property name) The average of a property's value

    2 count(property name or *) The number of times a property occurs in the results

    3 max(property name) The maximum value of the property values

    4 min(property name) The minimum value of the property values5 sum(property name) The sum total of the property values

    The distinct keyword only counts the unique values in the row set. The following

  • Hibernate

    query will return only unique count:

    String hql = "SELECT count(distinct E.firstName) FROM Employee E";Query query = session.createQuery(hql);List results = query.list();

    Pagination using Query :There are two methods of the Query interface for pagination.S.N. Method & Description

    1Query setFirstResult(int startPosition)This method takes an integer that represents the first row in your result set, starting with row 0.

    2Query setMaxResults(int maxResult)This method tells Hibernate to retrieve a fixed number maxResults of objects.

    Using above two methods together, we can construct a paging component in our web or Swing application. Following is the example which you can extend to fetch 10 rows at a time:String hql = "FROM Employee";Query query = session.createQuery(hql);query.setFirstResult(5);query.setMaxResults(10); List results = query.list(); // will return records from 5 to 10th number

    Hibernate Criteria Queries :

    Hibernate provides alternate ways of manipulating objects and in turn data available in RDBMS tables.

    One of the methods is Criteria API which allows you to build up a criteria query object programmatically where you can apply filtration rules and logical conditions.

    The Hibernate Session interface provides createCriteria() method which can be used to create a Criteria object that returns instances of the persistence object's class when your application executes a criteria query.

    Criteria query is one which will simply return every object that corresponds to the Employee class.Criteria cr = session.createCriteria(Employee.class);List results = cr.list();

  • Hibernate

    Restrictions with Criteria:

    You can use add() method available for Criteria object to add restriction for a criteria query.

    Following is the example to add a restriction to return the records with salary is equal to 2000:

    Criteria cr = session.createCriteria(Employee.class);cr.add(Restrictions.eq("salary", 2000));List results = cr.list();

    Following are the few more examples covering different scenarios and can be used as per requirement:

    Criteria cr = session.createCriteria(Employee.class);

    // To get records having salary more than 2000cr.add(Restrictions.gt("salary", 2000));

    // To get records having salary less than 2000cr.add(Restrictions.lt("salary", 2000));

    // To get records having fistName starting with zaracr.add(Restrictions.like("firstName", "zara%"));

    // Case in-sensitive form of the above restriction.cr.add(Restrictions.ilike("firstName", "zara%"));

    // To get records having salary in between 1000 and 2000cr.add(Restrictions.between("salary", 1000, 2000));

    // To check if the given property is nullcr.add(Restrictions.isNull("salary"));

    // To check if the given property is not nullcr.add(Restrictions.isNotNull("salary"));

    // To check if the given property is emptycr.add(Restrictions.isEmpty("salary"));

    // To check if the given property is not emptycr.add(Restrictions.isNotEmpty("salary"));

    You can create AND or OR conditions using LogicalExpression restrictions as follows:

  • Hibernate

    org.hibernate.criterion.LogicalExpression LogicalExpression

    org.hibernate.criterion.Restrictions Restrictions

    Criteria cr = session.createCriteria(Employee.class);

    Criterion salary = Restrictions.gt("salary", 2000);Criterion name = Restrictions.ilike("firstNname","zara%");

    // To get records matching with OR conditionsLogicalExpression orExp = Restrictions.or(salary, name);cr.add( orExp );

    // To get records matching with AND conditionsLogicalExpression andExp = Restrictions.and(salary, name);cr.add( andExp );

    List results = cr.list();

    Pagination using Criteria:There are two methods of the Criteria interface for pagination.S.N. Method & Description

    1public Criteria setFirstResult(int firstResult)This method takes an integer that represents the first row in your result set, starting with row 0.

    2public Criteria setMaxResults(int maxResults)This method tells Hibernate to retrieve a fixed number maxResults of objects.

    Using above two methods together, we can construct a paging c