Thursday, September 3, 2015

Hibernate 4 migration tips

I was migrating the spring and hibernate in my application and found couple of issues. 

The hibernate 3.2.5 was not working with the old configuration methods.


With all the dependencies I got a null pointer exception 


java.lang.NullPointerException at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:207) at org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:75)

The above  exception message can be resolved by adding below in Hibernate property:

<property name="hibernate.temp.use_jdbc_metadata_defaults">false</property>

For developing a standalone hibernate code to ensure the entity works with the web application we can have a utility class with main method and make the changes.

hbm.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
      "-//Hibernate/Hibernate Mapping DTD //EN"
          "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-configuration>
    <session-factory>
       <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
       <property name="hibernate.connection.username">schemaname</property> 
       <property name="hibernate.connection.password">password</property>
       <property name="hibernate.connection.url">jdbc:oracle:thin:@database.com:port:databasename </property>
      <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
      <property name="connection.pool_size">1</property>
      <property name="show_sql">true</property>
      <property name="hibernate.temp.use_jdbc_metadata_defaults">false</property>
      <property name="hibernate.format_sql">false</property>
    </session-factory>
</hibernate-configuration>


public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
  //above config location - if present outside the class path, we use this file in the configuration object
        File f = new File("C:\\hibernate.cfg.xml");
        String xmlFile = "C:\\resources\\hibernate.query.xml";
//Add file that has the named query - use the addFile chaining method in configuration object.
//1. create a configuration object
Configuration config= new Configuration().configure(f);
config.addAnnotatedClass(Entity1.class)
.addAnnotatedClass(Entity2.class)
                .addFile(xmlFile);
//2. Create a service registry builder object and this needs to be attached to the config to get the session factory.
ServiceRegistryBuilder builder = new ServiceRegistryBuilder().applySettings(config.getProperties());

//3. buildSessionFactory expects a serviceRegistry object to create a session Factory
// the session object can be obtained from this sessionFactory - object factory.
sessionFactory = config.buildSessionFactory(builder.buildServiceRegistry());
}
public void main(String args[]){
  Session session = sessionFactory.openSession();
  Query query = session.createQuery("from entity1");
  List<Object> resobj = query.list();
  
//if we need to update the filter to the session use
 session.enableFilter("filterName");
 // Named Query
 Query query1 = session.getNamedQuery("QUERY_NAME_IN_XMLFILE");
List<Object> resobj1 = query1.list();

//if to execute the native SQL query and transform it to a entity within.
Query query2 = session.createSQLQuery("select * from ENTITY1_TABLE");
 query2.setResultTransformer(Transformers.aliasToBean(Entity1.class));
List<Entity1> resobj2 = query2.list();
}
}

//The above will execute and returns the results as expected.
Note: if there is a filter then we should use the enableFilter("name of filter")
if we have a parameterized filter we can set that using  session.enableFilter("name").setParameter("filterparam");

Friday, July 31, 2015

Hibernate+JPA+Derby demo.

Hibernate + JPA + Derby:

IDE used was Eclipse:

JPA stands for java persistence API, it is just a specification comes with javax.persistance.* package.

EclipseLink is another provider which uses the JPA specs.

Hibernate is also another provider which uses the JPA specs, Most of the developer use the hibernate to connect with JPA and it also depends on the requirement.

Hibernate itself has its own session, transaction management which is sophisticated for development compared to the JPA entitymanagerfactory,

We can also use the maven project to develop a sample application, but here we are not going to do this.
We identify the dependency jars for derby, hibernate and jpa.


The hibernate dependent jar can be downloaded from http://mvnrepository.com/artifact/org.hibernate/hibernate-entitymanager  select appropriate version of the hibernate-entity manager jar and it compile dependencies.

In order to setup the Derby database we need to download the derby.jar from Apache derby website. link is http://db.apache.org/derby/derby_downloads.html.

In eclipse we can either create a java project and build the JPA+HIBERNATE+DERBY sample application. But here we will create a simple JPA project.

In Eclipse,  Navigate to File -> New -> JPA Project
Provide the project name eg: JPADemo1.
Select the JPA version (else leave the default eg. 2.1)
Select the target runtime, as jre (which version of jre has been configured in eclipse and based on the option, i am using jre7)
Click Next button.

If we need to change the output folder location, we can change it here. Leave the default.
Click Next button.

We need to configure the JPA Facet now.
If you have the Derby connection already set, you can use that
If you have configured the Eclipse datatool plugin for derby, we can select the option Add driver library to build path option and select the Derby Embedded JDBC Driver.

Click Finish.

JPA persistance-api-XXX.jar expects the persistence.xml file to be present in META-INF/persistence.xml.
This is a xml file with <persistence> as a root element.
This file defines the database and other configuration details for JPA application.
sample persistence content is below in the snapshot.

Note: there might be mismatch with the hibernate Jars in the class path or build path of the project with that of the JPA generic version we used to create the Eclipse project.


<?xml version="1.0" encoding="UTF-8"?>
<!-- <persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
       http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> -->
<persistence version="2.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_2_0.xsd">
       <persistence-unit name="JPAdemo1">
              <provider>org.hibernate.ejb.HibernatePersistence</provider>
              <class> com.jpademo.test.entity.Employee</class>
              <properties>
                     <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
                     <property name="javax.persistence.jdbc.url" value="jdbc:derby:C:\Users\userId\MyDB;create=true" />
                     <property name="javax.persistence.jdbc.user" value="demoschema" />
                     <property name="javax.persistence.jdbc.password" value="" />
                     <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect"></property>
              </properties>
       </persistence-unit>
</persistence>
Snapshot of persistence.xml

The Derby database was already set in the Eclipse using the Eclipse datatool, this can be done using the eclipse market place.

JPA expects the persistence.xml file to be included in the class path.
The provider tag will contain the information of the which JPA implementation we are using. For example we have used the hibernate provider.
EclipseLink provider can also be used. Refer the link for different example:
https://gist.github.com/mortezaadi/8619433

The class tag just to represent the entity class, in this case Employee.java is the entity.

The properties tag represents the property needed to connect the database / schema.

Employee.java - a entity class to represent the data.
this class file is packaged under com.jpademo.test.entity;

package com.jpademo.test.entity;

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

@Entity
public class Employee {

                public String employeename;

                public String employeeId;

                @Column(name = "employee_name")
                public String getEmployeename() {
                                return employeename;
                }

                public void setEmployeename(String employeename) {
                                this.employeename = employeename;
                }

                @Id
                @Column(name = "employee_id")
                public String getEmployeeId() {
                                return employeeId;
                }

                public void setEmployeeId(String employeeId) {
                                this.employeeId = employeeId;
                }
}

Below is a sample main method on how to insert records into the derby database table.
package com.jpademo.test;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import com.jpademo.test.entity.Employee;

public class DemoMain {
     public static void main(String args[]){
                try{
                                EntityManagerFactory entitymangerfactory = Persistence.createEntityManagerFactory("JPAdemo1");
                                EntityManager entityManager = entitymangerfactory.createEntityManager();

                                Employee employee = new Employee();
                                employee.setEmployeeId("5");
                                employee.setEmployeename("employee5");

                                EntityTransaction transaction = entityManager.getTransaction();
                                transaction.begin();
                                entityManager.persist(employee);
                                transaction.commit();

                                entityManager.close();
                                entitymangerfactory.close();
                }catch (Exception exe){
                                System.out.println("EXCEPTION FOUND "+exe.toString());
                }
      }
}


If the derby database instance is opened in eclipse datatool, The main class would display error message in the console.


Installing Eclipse Data tools platform:
Search for the Eclipse DTP (data tools platform) in Eclipse Market place.

After installing the plugin, navigate to Window -> Open Perspective -> Database Development.

Configure the Database connections by selecting the database connection in Data Source Explorer. Right click and select New.
Select the Derby Database, click the icon to add a Driver.
update the Derby.jar which was downloaded earlier. from Apache derby server.

Once configured,
we can create a sql file in any of the project and open in the editor section. Select the query to be executed.
Right click and use execute all or execute selected text. the query will be executed in the pane.

Below is the sample screen of derby sql results.