Google

Oct 8, 2013

Hibernate Query Language (HQL) example



Step 1: The ER diagram showing the relationships among the tables. The column names and types are omitted to keep it simple.



Step 2: The basic table details.


The UserApp table uses "UserName" and "AppCd" as the primary key. It links to the User table using the "UserName". "UserName" is the primary key in the User table.



The UserApp table links to the App table using the "AppCd".


"AppCd" is the primary key in the App table.

-->
Step 3: Now the sample  HQL.


    public List getAppGroupActions(String userName)
    {
        
        String hql = "Select new com.myapp.model.security.UserAppId(user.userName, app.appCd)"
                + " from UserApp as usrapp, App app, User user "
                + " where  user.userName = usrapp.id.userName"
                + " and usrapp.id.appCd  = app.appCd "
                + " and usrapp.status='A' 
                + " and app.status='A' AND app.disabled = 'N' "
                + " and user.status = 'A' and user.disabled = 'N' "
                + " and usrapp.id.userName = :userName ";
        
        Query query = em
                .createQuery(hql);
        query.setParameter("userName", userName);
        
        @SuppressWarnings("unchecked")
        List resultList = query.getResultList();
        
        return resultList;
 }

Things to observe are:

  • A list new object of type new com.myapp.model.security.UserAppId is returned. You need to have this class defined with the right constructor to take userName and appCd
  • The UserApp,  App,  and User are hibernate entities and NOT table names.
  • usrapp.id.userName, user.status, etc are entity properties and NOT table column names.
You can refer here as to how the entities are defined and mapped.

So, this is an Object Oriented query language. 

Labels: ,

Oct 3, 2013

Hibernate Mapping and Many to One example - part 2

This is a continuation of Hibernate Mapping and Many to One example - part 1.

Step 5: Define the previously mapped classes UserApp and UserAppId in persistence.xml file along with the other classes that will be mapped below.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
 xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
 <persistence-unit name="myapp">

  
  <class>com.jpmorgan.myapp.model.security.CmnUser</class>
  
  <class>com.jpmorgan.myapp.model.security.UserApp</class>
  <class>com.jpmorgan.myapp.model.security.UserAppId</class>
  
  <class>com.jpmorgan.myapp.model.security.User</class>
  <class>com.jpmorgan.myapp.model.security.App</class>
  
 
  <exclude-unlisted-classes>true</exclude-unlisted-classes>

  <properties>
   <property name="hibernate.dialect"
    value="org.hibernate.dialect.SybaseASE15Dialect" />
   <property name="hibernate.show_sql" value="true" />
   <property name="hibernate.cache.use_second_level_cache"
    value="false" />
  </properties>

 </persistence-unit>
</persistence>






Step 6: Mapping of User table.

package com.myapp.dm.model.security;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Version;

import org.hibernate.annotations.Generated;
import org.hibernate.annotations.GenerationTime;


@SuppressWarnings("serial")
@Entity
@Table(name = "User", schema = "dbo", catalog = "my_app")
public class User implements java.io.Serializable
{
    
    private String userName;
    private char disabled;
    private String comment;
    private char status;
    private Date createdOn;
    private String createdBy;
    private Date modifiedOn;
    private String modifiedBy;
    private byte[] timestamp;
    
    public User()
    {
    }
    
    public User(String userName,char disabled, char status, Date createdOn, String createdBy,
            Date modifiedOn, String modifiedBy)
    {
        this.userName = userName;
        this.disabled = disabled;
        this.status = status;
        this.createdOn = createdOn;
        this.createdBy = createdBy;
        this.modifiedOn = modifiedOn;
        this.modifiedBy = modifiedBy;
    }
    
       
    @Id
    @Column(name = "UserName", unique = true, nullable = false, length = 40)
    public String getUserName()
    {
        return this.userName;
    }
    
    public void setUserName(String userName)
    {
        this.userName = userName;
    }
    
    @Column(name = "UserType", nullable = false, length = 40)
    public String getUserType()
    {
        return this.userType;
    }
    
    public void setUserType(String userType)
    {
        this.userType = userType;
    }
    
    @Column(name = "Disabled", nullable = false, length = 1)
    public char getDisabled()
    {
        return this.disabled;
    }
    
    public void setDisabled(char disabled)
    {
        this.disabled = disabled;
    }
    
 
    @Column(name = "Comment")
    public String getComment()
    {
        return this.comment;
    }
    
    public void setComment(String comment)
    {
        this.comment = comment;
    }
    
    @Column(name = "Status", nullable = false, length = 1)
    public char getStatus()
    {
        return this.status;
    }
    
    public void setStatus(char status)
    {
        this.status = status;
    }
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "CreatedOn", nullable = false, length = 23)
    public Date getCreatedOn()
    {
        return this.createdOn;
    }
    
    public void setCreatedOn(Date createdOn)
    {
        this.createdOn = createdOn;
    }
    
    @Column(name = "CreatedBy", nullable = false, length = 40)
    public String getCreatedBy()
    {
        return this.createdBy;
    }
    
    public void setCreatedBy(String createdBy)
    {
        this.createdBy = createdBy;
    }
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "ModifiedOn", nullable = false, length = 23)
    public Date getModifiedOn()
    {
        return this.modifiedOn;
    }
    
    public void setModifiedOn(Date modifiedOn)
    {
        this.modifiedOn = modifiedOn;
    }
    
    @Column(name = "ModifiedBy", nullable = false, length = 40)
    public String getModifiedBy()
    {
        return this.modifiedBy;
    }
    
    public void setModifiedBy(String modifiedBy)
    {
        this.modifiedBy = modifiedBy;
    }
    
    @Version
    @Column(name = "Timestamp", insertable = false, updatable = false, unique = true, nullable = false)
    @Generated(GenerationTime.ALWAYS)
    public byte[] getTimestamp()
    {
        return this.timestamp;
    }
    
    public void setTimestamp(byte[] timestamp)
    {
        this.timestamp = timestamp;
    } 
}


Step 7: Mapping of App table.
package com.myapp.model.security;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Version;

import org.hibernate.annotations.Generated;
import org.hibernate.annotations.GenerationTime;

@SuppressWarnings("serial")
@Entity
@Table(name = "App", schema = "dbo", catalog = "sne_kath")
public class App implements java.io.Serializable
{
    
    private String appCd;
    private String description;
    private char status;
    private char disabled;
    private Date createdOn;
    private String createdBy;
    private Date modifiedOn;
    private String modifiedBy;
    private byte[] timestamp;
    private String requiresDeskTop;
    
    public App()
    {
    }
    
    public App(String appCd, String description, char status, Date createdOn, String createdBy, Date modifiedOn,
            String modifiedBy)
    {
        this.appCd = appCd;
        this.description = description;
        this.status = status;
        this.createdOn = createdOn;
        this.createdBy = createdBy;
        this.modifiedOn = modifiedOn;
        this.modifiedBy = modifiedBy;
    }
    
    @Column(name = "appcd", nullable = false)
    @Id
    public String getAppCd()
    {
        return appCd;
    }
    
    public void setAppCd(String appCd)
    {
        this.appCd = appCd;
    }
    
    @Column(name = "description", nullable = false)
    public String getDescription()
    {
        return description;
    }
    
    public void setDescription(String description)
    {
        this.description = description;
    }
    
    public char getDisabled()
    {
        return disabled;
    }
    
    public void setDisabled(char disabled)
    {
        this.disabled = disabled;
    }
    
    @Column(name = "RequiresDesktop", nullable = true)
    public String getRequiresDeskTop()
    {
        return requiresDeskTop;
    }
    
    public void setRequiresDeskTop(String requiresDeskTop)
    {
        this.requiresDeskTop = requiresDeskTop;
    }
    
    @Version
    @Column(name = "Timestamp", insertable = false, updatable = false, unique = true, nullable = false)
    @Generated(GenerationTime.ALWAYS)
    public byte[] getTimestamp()
    {
        return this.timestamp;
    }
    
    public void setTimestamp(byte[] timestamp)
    {
        this.timestamp = timestamp;
    }
    
    @Column(name = "Status", nullable = false, length = 1)
    public char getStatus()
    {
        return this.status;
    }
    
    public void setStatus(char status)
    {
        this.status = status;
    }
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "CreatedOn", nullable = false, length = 23)
    public Date getCreatedOn()
    {
        return this.createdOn;
    }
    
    public void setCreatedOn(Date createdOn)
    {
        this.createdOn = createdOn;
    }
    
    @Column(name = "CreatedBy", nullable = false, length = 40)
    public String getCreatedBy()
    {
        return this.createdBy;
    }
    
    public void setCreatedBy(String createdBy)
    {
        this.createdBy = createdBy;
    }
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "ModifiedOn", nullable = false, length = 23)
    public Date getModifiedOn()
    {
        return this.modifiedOn;
    }
    
    public void setModifiedOn(Date modifiedOn)
    {
        this.modifiedOn = modifiedOn;
    }
    
    @Column(name = "ModifiedBy", nullable = false, length = 40)
    public String getModifiedBy()
    {
        return this.modifiedBy;
    }
    
    public void setModifiedBy(String modifiedBy)
    {
        this.modifiedBy = modifiedBy;
    } 
}


Step 8: Finally, the hibernate and JPA dependency jars in Maven's pom.xml file.

Labels: ,

Oct 2, 2013

Hibernate Mapping and Many to One example - part 1

Here is a multipart step by step tutorial style basic mapping. The diagram below depicts the basic database table structure.

Step 1: The ER diagram showing the relationships among the tables. The column names and types are omitted to keep it simple.



Step 2: The basic table details.


The UserApp table uses "UserName" and "AppCd" as the primary key. It links to the User table using the "UserName". "UserName" is the primary key in the User table.



The UserApp table links to the App table using the "AppCd".


"AppCd" is the primary key in the App table.


Step 3: Now the hibernate mapping part. Mapping UserApp table to UserApp object.

package com.myapp.model.security;

import java.util.Date;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Version;

import org.hibernate.annotations.Generated;
import org.hibernate.annotations.GenerationTime;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;


@SuppressWarnings("serial")
@Entity
@Table(name = "UserApp", schema = "dbo", catalog = "my_app")
public class UserApp implements java.io.Serializable
{
    
    private UserAppId id; // primary key
    private byte[] timestamp;
    private String groupNm;
    private char status;
    private Date createdOn;
    private String createdBy;
    private Date modifiedOn;
    private String modifiedBy;
    
 //linking tables and entities
    private CmnApp cmnApp;
    private CmnUser cmnUser;
    
 //default empty constructor
    public UserApp(){}
    
    public UserApp(UserAppId id, String groupNm, char status, Date createdOn, String createdBy, Date modifiedOn,
            String modifiedBy)
    {
        this.id = id;
        this.groupNm = groupNm;
        this.status = status;
        this.createdOn = createdOn;
        this.createdBy = createdBy;
        this.modifiedOn = modifiedOn;
        this.modifiedBy = modifiedBy;
    }
    
    public UserApp(UserAppId id, String groupNm, String previousGroupNm, char status, Date createdOn,
            String createdBy, Date modifiedOn, String modifiedBy)
    {
        this.id = id;
        this.groupNm = groupNm;
        this.previousGroupNm = previousGroupNm;
        this.status = status;
        this.createdOn = createdOn;
        this.createdBy = createdBy;
        this.modifiedOn = modifiedOn;
        this.modifiedBy = modifiedBy;
    }
    
    @EmbeddedId
    @AttributeOverrides(
    {
        @AttributeOverride(name = "userName", column = @Column(name = "UserName", nullable = false, length = 40)),
        @AttributeOverride(name = "appCd", column = @Column(name = "AppCd", nullable = false, length = 10))
    })
    public UserAppId getId()
    {
        return this.id;
    }
    
    public void setId(UserAppId id)
    {
        this.id = id;
    }
    
    @Version
    @Column(name = "Timestamp", insertable = false, updatable = false, unique = true, nullable = false)
    @Generated(GenerationTime.ALWAYS)
    public byte[] getTimestamp()
    {
        return this.timestamp;
    }
    
    public void setTimestamp(byte[] timestamp)
    {
        this.timestamp = timestamp;
    }
    
    @Column(name = "GroupNm", nullable = false, length = 40)
    public String getGroupNm()
    {
        return this.groupNm;
    }
    
    public void setGroupNm(String groupNm)
    {
        this.groupNm = groupNm;
    }
    
    @Column(name = "Status", nullable = false, length = 1)
    public char getStatus()
    {
        return this.status;
    }
    
    public void setStatus(char status)
    {
        this.status = status;
    }
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "CreatedOn", nullable = false, length = 23)
    public Date getCreatedOn()
    {
        return this.createdOn;
    }
    
    public void setCreatedOn(Date createdOn)
    {
        this.createdOn = createdOn;
    }
    
    @Column(name = "CreatedBy", nullable = false, length = 40)
    public String getCreatedBy()
    {
        return this.createdBy;
    }
    
    public void setCreatedBy(String createdBy)
    {
        this.createdBy = createdBy;
    }
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "ModifiedOn", nullable = false, length = 23)
    public Date getModifiedOn()
    {
        return this.modifiedOn;
    }
    
    public void setModifiedOn(Date modifiedOn)
    {
        this.modifiedOn = modifiedOn;
    }
    
    @Column(name = "ModifiedBy", nullable = false, length = 40)
    public String getModifiedBy()
    {
        return this.modifiedBy;
    }
    
    public void setModifiedBy(String modifiedBy)
    {
        this.modifiedBy = modifiedBy;
    }
    
 
 //mapping links
 
    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "AppCd", insertable = false, updatable = false)
    public CmnApp getCmnApp()
    {
        return cmnApp;
    }
    
    public void setCmnApp(CmnApp cmnApp)
    {
        this.cmnApp = cmnApp;
    }
    
    @ManyToOne(cascade = CascadeType.ALL, optional = true)
    @NotFound(action = NotFoundAction.IGNORE)
    @JoinColumn(name = "UserName", insertable = false, updatable = false)
    public CmnUser getCmnUser()
    {
        return cmnUser;
    }
    
    public void setCmnUser(CmnUser cmnUser)
    {
        this.cmnUser = cmnUser;
    } 
}



Step 4: Define the primary key class UserAppId that maps the key columns.

package com.myapp.model.security;

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


@SuppressWarnings("serial")
@Embeddable
public class UserAppId implements java.io.Serializable
{
    
    private String userName;
    private String appCd;
    
    public UserAppId()
    {
    }
    
    public UserAppId(String userName, String appCd)
    {
        this.userName = userName;
        this.appCd = appCd;
    }
    
    @Column(name = "UserName", nullable = false, length = 40)
    public String getUserName()
    {
        return this.userName;
    }
    
    public void setUserName(String userName)
    {
        this.userName = userName;
    }
    
    @Column(name = "AppCd", nullable = false, length = 10)
    public String getAppCd()
    {
        return this.appCd;
    }
    
    public void setAppCd(String appCd)
    {
        this.appCd = appCd;
    }
    
    public boolean equals(Object other)
    {
        if ((this == other))
            return true;
        if ((other == null))
            return false;
        if (!(other instanceof UserAppId))
            return false;
        UserAppId castOther = (UserAppId) other;
        
        return ((this.getUserName() == castOther.getUserName()) || (this.getUserName() != null
                && castOther.getUserName() != null && this.getUserName().equals(castOther.getUserName())))
                && ((this.getAppCd() == castOther.getAppCd()) || (this.getAppCd() != null
                        && castOther.getAppCd() != null && this.getAppCd().equals(castOther.getAppCd())));
    }
    
    public int hashCode()
    {
        int result = 17;
        
        result = 37 * result + (getUserName() == null ? 0 : this.getUserName().hashCode());
        result = 37 * result + (getAppCd() == null ? 0 : this.getAppCd().hashCode());
        return result;
    }  
}


The Hibernate Mapping and Many to One example - part 2 will cover the mapping of the other two tables.

Labels: ,

Jun 21, 2013

JPA interview questions and answers and high level overview - part 2

This is a continuation of JPA and Hibernate interview Questions and answers part 1.

Q. What is an EntityManager?
A. The entity manager javax.persistence.EntityManager provides the operations from and to the database, e.g. find objects, persists them, remove objects from the database, etc. Entities which are managed by an EntityManager will automatically propagate these changes to the database (if this happens within a commit statement). These objects are known as persistent object.  If the Entity Manager is closed (via close()) then the managed entities are in a detached state. These are known as the detached objects. If you want synchronize them again with the database, the a Entity Manager provides the merge() method. Once merged, the object(s) becomes perstent objects again.

The EntityManager is the API of the persistence context, and an EntityManager can be injected directly in to a DAO without requiring a JPA Template. The Spring Container is capable of acting as a JPA container and of injecting the EntityManager by honoring the @PersistenceContext (both as field-level and a method-level annotation).

Here is a sample PersonDaoImpl using the Person entity

 
package com.mycompany.myapp.impl;

//...

import com.mycompany.myapp.model.Person

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.stereotype.Repository;

@Repository("personDao")
public class PersonDaoImpl implements PersonDao
{
    @PersistenceContext
    private EntityManager em;
    
    @Override    
    public List<Person> fetchPersonByFirstname(String fName)
    {
        Query query = em.createQuery( "from Person p where p.firstname = :personName", Person.class );
        query.setParameter("firstName", fName);
          
        List<Person> persons = new ArrayList<Person>();
        List<Person> results = query.getResultList();
        
        return persons;
    }
    
    public Person find(Integer id)
    {
        return em.find(Person.class, id);
    }  
}


Q. What us an Entity?
A. A class which should be persisted in a database it must be annotated with javax.persistence.Entity. Such a class is called Entity. An instances of the class will be a row in the person table. So, the columns in the person table will be mapped to the Person java object annotated as @Entity. Here is the sample Person class.




 
package com.mycompany.myapp.model;

//....

@SuppressWarnings("serial")
@Entity
@Table(name = "person", schema = "dbo", catalog = "my_db_schema")
@Where(clause = "inactiveFlag = 'N'")
@TypeDefs(
{
    @TypeDef(name = "IdColumn", typeClass = IdColumnType.class)})
public class UnitTrustPrice implements java.io.Serializable
{

    private int id;
    private String firstName;
 private String surname;
 private byte[] timestamp;
 private char inactiveFlag;

    public Person()
    {
    }
 
 //.. other constructors
 
 @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "person_id", nullable = false, precision = 9, scale = 0)
    @Type(type = "int")
    public int getId()
    {
        return this.id;
    }
    
    public void setId(int id)
    {
        this.id = id;
    }
 
 @Version
    @Column(name = "timestamp", insertable = false, updatable = false, unique = true, nullable = false)
    @Generated(GenerationTime.ALWAYS)
    public byte[] getTimestamp()
    {
        return this.timestamp;
    }
    
    public void setTimestamp(byte[] timestamp)
    {
        this.timestamp = timestamp;
    }
 
 @Column(name = "InactiveFlag", nullable = false, length = 1)
    public char getInactiveFlag()
    {
        return this.inactiveFlag;
    }
    
    public void setInactiveFlag(char inactiveFlag)
    {
        this.inactiveFlag = inactiveFlag;
    }
    
 
 @Column(name = "first_name", nullable = false, length = 30)
    public String getFirstName()
    {
        return this.firstName;
    }
 
    public void setFirstName(String fName)
    {
        this.firstName = fName;
    }
 
 @Column(name = "surname", nullable = false, length = 30)
    public String getSurname()
    {
        return this.surname;
    }
 
    public void setSurname(String sName)
    {
        this.surname = sName;
    }
 
 //..........
} 




Q. What are the dependency jars required for a JPA application?
A Include the relevant jar files via your Maven pom.xml file.

 
<!-- JPA and hibernate -->
<dependency>
 <groupId>org.hibernate</groupId>
 <artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
 <groupId>org.hibernate</groupId>
 <artifactId>hibernate-entitymanager</artifactId>
</dependency>
<dependency>
 <groupId>org.hibernate.javax.persistence</groupId>
 <artifactId>hibernate-jpa-2.0-api</artifactId>
</dependency>

<!-- validator -->
<dependency>
 <groupId>javax.validation</groupId>
 <artifactId>validation-api</artifactId>
</dependency>

<dependency>
 <groupId>org.hibernate</groupId>
 <artifactId>hibernate-validator</artifactId>
</dependency>




Labels: , ,

Jun 19, 2013

JPA interview questions and answers and high level overview - part 1

Q. What is a JPA? What are its key components?
A. The process of mapping Java objects to database tables and vice versa is called "Object-relational mapping" (ORM). The Java Persistence API provides Java developers with an object/relational mapping  (ORM) facility for managing relational data in Java applications. JPA is a specification and several implementations are available like EJB, JDO, Hibernate, and Toplink. Via JPA the developer can map, store, update and retrieve data from relational databases to Java objects and vice versa. 


Q. What is the difference between hibernate.cfg.xml and persistence.xml?
A. If you are using Hibernate's proprietary API, you'll need the hibernate.cfg.xml. If you are using JPA i.e. Hibernate EntityManager, you'll need the persistence.xml. You will not need both as you will be using either Hibernate proprietary API or JPA. However, if you had used Hibernate Proprietary API using hibernate.cfg.xml with hbm.xml mapping files, and now wanted to start using JPA, you can reuse the existing configuration files by referencing the hibernate.cfg.xml in the persistence.xml in the hibernate.ejb.cfgfile property and reuse the existing hbm.xml files. In a long run, migrate hbm.xml files to JPA annotations.


Q. What is an EntityManagerFactory and a Persistence unit?
A. The EntityManager is created by the EntitiyManagerFactory which is configured by the persistence unit. The persistence unit is described via the file "persistence.xml" in the directory META-INF in the source folder. It defines a set of entities which are logically connected and the connection properties as shown below via an example.

 
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
 xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">

 <persistence-unit name="myapp-server" transaction-type="RESOURCE_LOCAL">

  <provider>org.hibernate.ejb.HibernatePersistence</provider>
  
        <!-- import other mapping files if any -->
        <mapping-file>META-INF/myApp2.xml</mapping-file>

  <class>com.mycompany.myapp.Person</class>
  
  <exclude-unlisted-classes>true</exclude-unlisted-classes>

  <properties>
   <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:derby:/home/myapp/databases/simpleDb;create=true" />
            <property name="javax.persistence.jdbc.user" value="test" />
            <property name="javax.persistence.jdbc.password" value="test" />
    
   <!-- force Hibernate to use a singleton of Ehcache CacheManager -->
   <property name="hibernate.cache.region.factory_class"
    value="org.hibernate.cache.ehcache.EhCacheRegionFactory" />
   <property name="hibernate.cache.use_second_level_cache" value="true" />
         <property name="hibernate.cache.use_query_cache" value="true" />
   <property name="net.sf.ehcache.configurationResourceName" value="ehcache.xml" />
  </properties>

 </persistence-unit>
</persistence>


Usually, JPA defines a persistence unit through the META-INF/persistence.xml file. Starting with Spring 3.1, this XML file is no longer necessary – the LocalContainerEntityManagerFactoryBean now supports a ‘packagesToScan’ property where the packages to scan for @Entity classes can be specified. The snippet below shows how you can bootstrap with or without persistence.xml.

 
package com.mycompany.app.config;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.orm.hibernate4.HibernateExceptionTranslator;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;


@Configuration
@PropertySource(value =
{"classpath:/common/jpa.properties"
})
@EnableTransactionManagement
public class JpaConfig
{
    @Value("${my_app_common_jpa_showSql:false}")
    private Boolean showSql;
    
    @Value("${my_app_common_jpa_hibernateDialect}")
    private String hibernateDialect;
    
    @Value("${my_app_common_jpa_generateStatistics:false}")
    private Boolean generateStatistics;
    
    @Value("${my_app_common_jpa_generateDdl:false}")
    private Boolean generateDdl;
    
    @Value("${my_app_common_jpa_databasePlatform}")
    private String databasePlatform;
    
    @Resource(name = "myAppDataSource")
    private DataSource dataSource;
    
    private static Logger LOGGER = LoggerFactory.getLogger(JpaConfig.class);
    
    @Bean
    public Map<String, Object> jpaProperties()
    {
        LOGGER.debug("jpaProperties hibernateDialect=" + hibernateDialect);
        
        Map<String, Object> props = new HashMap<String, Object>();
        props.put("hibernate.dialect", hibernateDialect);
        props.put("hibernate.generate_statistics", generateStatistics);
        
        return props;
    }
    
    @Bean
    public JpaVendorAdapter jpaVendorAdapter()
    {
        LOGGER.debug("jpaProperties databasePlatform=" + databasePlatform);
        
        HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
        hibernateJpaVendorAdapter.setShowSql(showSql);
        hibernateJpaVendorAdapter.setGenerateDdl(generateDdl);
        hibernateJpaVendorAdapter.setDatabasePlatform(databasePlatform);
        
        return hibernateJpaVendorAdapter;
    }
    
    @Bean
    public PlatformTransactionManager transactionManager()
    {
        return new JpaTransactionManager(entityManagerFactory());
    }
    
    @Bean
    public EntityManagerFactory entityManagerFactory()
    {
        LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
        
        lef.setDataSource(dataSource);
        lef.setJpaPropertyMap(this.jpaProperties());
        lef.setJpaVendorAdapter(this.jpaVendorAdapter());
        lef.setPersistenceXmlLocation("META-INF/persistence.xml");
        //alternative without persistence.xml from Spring 3.1
        //lef.setPackagesToScan("com.mycompany.myapp");
        lef.afterPropertiesSet();
        
        return lef.getObject();
    }
    
    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation()
    {
        return new PersistenceExceptionTranslationPostProcessor();
    }
    
    @Bean
    public HibernateExceptionTranslator hibernateExceptionTranslator()
    {
        return new HibernateExceptionTranslator();
    }
}

The jpa.properties can be defined as shown below.

 
# properties for JPA
my_app_common_jpa_showSql=false
my_app_common_jpa_generateDdl=false

my_app_common_jpa_databasePlatform=SYBASE
my_app_common_jpa_hibernateDialect=org.hibernate.dialect.SybaseASE15Dialect
my_app_common_jpa_generateStatistics=true
my_app_common_aesJndiName=java:comp/env/jdbc/my_db

The configuration shown above is Java based config, and  if you want to use a Spring xml file based config, it will look like

 
<bean id="myEmf"
 class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
   <property name="dataSource" ref="dataSource" />
   <property name="packagesToScan" value="org.rest" />
   <property name="jpaVendorAdapter">
      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
         <property name="showSql" value="${my_app_common_jpa_showSql}" />
         <property name="generateDdl" value="${my_app_common_jpa_generateDdl}" />
         <property name="databasePlatform" value="${my_app_common_jpa_hibernateDialect}" />
      </bean>
   </property>
</bean>
 
<bean id="dataSource"
 class="org.springframework.jdbc.datasource.DriverManagerDataSource">
   <property name="driverClassName" value="${driverClassName}" />
   <property name="url" value="${url}" />
   <property name="username" value="${user}" />
   <property name="password" value="${password}" />
</bean>
 
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
   <property name="entityManagerFactory" ref="myEmf" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />

Labels: , ,

Oct 10, 2012

Hibernate tutorial with HSQLDB

This tutorial is basically an extension to the "simple" Java and JDBC tutorials. Hibernate is an ORM (Object to Relational Mapping) tool.

Step 1:  First step is to bring in the relevant Hibernate framework jar files like hibernate-xxx.jar, hibernate-annotations-xxxx.jar, and other dependent jar files that are transitively brought in from hibernate framework's pom.xml file. Here is the pom.xml file for simple Java project extended for hibernate.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <groupId>com.mytutorial</groupId>
 <artifactId>simple</artifactId>
 <version>1.0-SNAPSHOT</version>
 <packaging>jar</packaging>

 <name>simple</name>
 <url>http://maven.apache.org</url>

 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 </properties>

 <dependencies>
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>3.8.1</version>
   <scope>test</scope>
  </dependency>

        <!-- jar that contains the HSQLDB driver class  -->
  <dependency>
   <groupId>org.hsqldb</groupId>
   <artifactId>hsqldb</artifactId>
   <version>2.2.8</version>
  </dependency>

        <!--  GA means General Availability -->
        <!--  Hibernate framework JARS-->
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate</artifactId>
   <version>3.2.6.GA</version>
  </dependency>

  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-annotations</artifactId>
   <version>3.3.1.GA</version>
  </dependency>


 </dependencies>
</project>

Now, if you select the "simple" project and then right-mouse-click and select "Maven --> Update Dependencies".



Step 2: Hibernate uses the hibernate.cfg.xml file to configure the session factory with the database connectivity details and define your domain classes that map to to the relational database tables. This file needs to be defined in the src/main/resources folder and be in the classpath.

Create a new folder named "resources" under the "src/main" folder and then right-mouse-click on "resources" folder and then select "Build Path --> Use as Source Folder".



The contents of the hibernate.cfg.xml will include configuring the session factory to connect to the HSQLDB that we set up in the "SQL tutorial with HSQDB" tutorial.

<?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">org.hsqldb.jdbcDriver</property>
        <property name="connection.url">jdbc:hsqldb:hsql://localhost/mytestdb</property>
        <property name="connection.username">sa</property>
        <property name="connection.password"></property>
         
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>
         
        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.HSQLDialect</property>
 
        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>
 
        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
         
        <!-- Echo all executed SQL to stdout useful for debugging if set to true-->
        <property name="show_sql">false</property>
         
        <property name="hbm2ddl.auto">validate</property>
  
        <mapping class="com.mytutorial.domain.Course"/>
         
          
    </session-factory>
</hibernate-configuration>


Step 3: The next step is to define the HibernateUtil class that bootstraps the hibernate by loading the SessionFactory via  the hibernate.cfg.xml.

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

public class HibernateUtil {
 
 
 private static final SessionFactory sessionFactory = buildSessionFactory();
   
    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml file
         return new AnnotationConfiguration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            ex.printStackTrace();
            throw new ExceptionInInitializerError(ex);
        }
        
    }
  
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

}

Step 4: Next step is to define the domain Course class that maps to the "Course" database  table that was created in the "SQL  with HSQLDB" tutorial. Annotations are used for the object to relational mapping

package com.mytutorial.domain;

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


@Entity
@Table(name="Course")
public class Course {
 
 @Id
 @GeneratedValue
 @Column(name="course_id")
 private Integer id;
 
 @Column(name="name")
 private String name;
 
 @Column(name="course")
 private String course;
 
 public Course() {}

 public Integer getId() {
  return id;
 }

 public void setId(Integer id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public String getCourse() {
  return course;
 }

 public void setCourse(String course) {
  this.course = course;
 }
}


Step 5: Define the data access layer interface and the implementation class. The CourseDao is the interface and CourseDaoImpl is the implementation class that retrieves data from the database.




Define the interface.

package com.mytutorial.dao;

public interface CourseDao {
 
 abstract void readAllCourses();

}


Define the implementation class.

package com.mytutorial.dao;

import java.util.List;

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

import com.mytutorial.HibernateUtil;
import com.mytutorial.domain.Course;

public class CourseDaoImpl implements CourseDao {

 public void readAllCourses() {
  SessionFactory sf = HibernateUtil.getSessionFactory();
  Session session = sf.openSession();
  Query q = session.createQuery("from Course");
  @SuppressWarnings("unchecked")
  List<Course> courses = q.list();
  
  for (Course course : courses) {
   System.out.println(course.getName() + " - " + course.getCourse());
  }

 }

}


Step 6: This step is to define a class with a main method that makes use of the CourseDao.

package com.mytutorial;

import com.mytutorial.dao.CourseDaoImpl;
import com.mytutorial.dao.CourseDao;

public class HibernateTutorial {
 
 
 public static void main(String[] args) {
  CourseDao cDao = new CourseDaoImpl();
  cDao.readAllCourses();
 }

}

You should now have the required Java files defined.



Step 7: Before you can run the HibernateTutorial.java, you need to make sure that the HSQL database is running with the Course database as demonstrated in the "SQL tutorial with HSQLDB".

c:\Tools\hsqldb-2.2.9\hsqldb>java -cp ./lib/hsqldb.jar org.hsqldb.server.Server
[Server@79616c7]: [Thread[main,5,main]]: checkRunning(false) entered
[Server@79616c7]: [Thread[main,5,main]]: checkRunning(false) exited
[Server@79616c7]: Startup sequence initiated from main() method
[Server@79616c7]: Loaded properties from [C:\Tools\hsqldb-2.2.9\hsqldb\server.properties]
[Server@79616c7]: Initiating startup sequence...
[Server@79616c7]: Server socket opened successfully in 198 ms.
[Server@79616c7]: Database [index=0, id=0, db=file:mydatabases/tutorialdb, alias=mytestdb] opened sucessfully in 1073 ms
.
[Server@79616c7]: Startup sequence completed in 1277 ms.
[Server@79616c7]: 2012-10-09 11:35:07.347 HSQLDB server 2.2.9 is online on port 9001
[Server@79616c7]: To close normally, connect and execute SHUTDOWN SQL
[Server@79616c7]: From command line, use [Ctrl]+[C] to abort abruptly


Step 8: The final step is to right-mouse-click on HibernateTutorial.java and then select "Run As --> Java Application".

You should get an output like:

Sam - Java
peter - J2EE
paul - JSF
jonathan - Hibernate
james - Spring
Lewis - JDBC

You should also see, hibernate logs as shown below

INFO: configuring from resource: /hibernate.cfg.xml
...
INFO: autocommit mode: false
09/10/2012 11:37:30 AM org.hibernate.connection.DriverManagerConnectionProvider configure
INFO: using driver: org.hsqldb.jdbcDriver at URL: jdbc:hsqldb:hsql://localhost/mytestdb
09/10/2012 11:37:30 AM org.hibernate.connection.DriverManagerConnectionProvider configure
INFO: connection properties: {user=sa, password=****}
....
INFO: Using dialect: org.hibernate.dialect.HSQLDialect
09/10/2012 11:37:31 AM org.hibernate.transaction.TransactionFactoryFactory buildTransactionFactory
INFO: Using default transaction strategy (direct JDBC transactions)
....
INFO: fetching database metadata
09/10/2012 11:37:31 AM org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: table found: PUBLIC.PUBLIC.COURSE
09/10/2012 11:37:31 AM org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: columns: [course, name, course_id]


In the Spring 3.0 tutorial, I will extend this tutorial to show how we can use Spring to inject CourseDao into HibernateTutorial.

Labels: