User Tools

Site Tools


java:fiststepswithhibernate

Put hibernate into your life

I've created from zero various projects with hibernate, and because it a step somewhat complex, I've decided to document it, so in the following stages it will be easier to achieve.

Get the mysql driver

Ok, if you are using oracle, you have to change this step for the proper download of the oracle JDBC driver.

To download the mysql driver, check out www.mysql.com. Gather the jar file (something called “mysql-connector-java-X.X.XX-bin.jar” and install into your libraries directory of your eclipse project.

Download Hibernate

Point your browser to http://www.hibernate.org and check out for the latest version of the library. In the bundle you will download there is a “lib” directory with various directories in it: envers, jpa, optional, required.

Put all the following jar files:

  • from the “envers” folder, all the files
  • from the “jpa” folder, all the files
  • from the “required” folder, all the files
  • from the “optional” folder, I've put only the contents of the c3p0 (the connection pooling system C3P0)
  • from the “ehcache” folder, all the jar files

Add the new jar files into your eclipse project

Of course, you have to add all the new jar files into your eclipse project.

Open your applicationContext.xml and let's start the party

First Step: create a datasource

You have to have in place a running database, so you will have to have the following values:

  • server address (and port if it is different than 3306)
  • user (for god's sake, don't use root!!!!)
  • password (Have I to say that the more complex the better?)

And put these values into the proper places in the following xml snippet. And by the moment, you are done.

  <!-- 
  STEP ONE 
 
  Datasource, the access to mysql. This datasource uses 
  c3p0, a connection pooling interface and hence it 
  optimizes the use of connections. This configuration
  uses a new connection each time is requested.
 
  -->
  <bean id="dataSource"
        class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close"
        scope="singleton">
      <!-- 
      To test a connection: 
      mysql -h HOSTNAME -u USERNAME -p 
      and aftwerwards introduce the password when requested
       -->
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    <property name="jdbcUrl" value="jdbc:mysql://PUT-THE-DATASERVER-HERE:3306/DATABASE-NAME"/>
    <property name="user" value="PUT-THE-USERNAME-HERE"/>
    <property name="password" value="PUT-THE-PASSWORD-HERE"/>
  </bean>
 

Second Step: create a JdbcTemplate bean

We will create a bean named “simpleJdbcTemplate”. This is not really-really needed: this simpleJdbcTemplate is an object put by Spring to ease the integration of your beans with jdbc. However I prefer to have this wiring done by the Spring itself.

 
	<bean id="simpleJdbcTemplate"
	      class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate"
	      scope="prototype">
		<constructor-arg ref="dataSource"/>
	</bean>	      

Third Step: create a hibernateTemplate bean to add to your beans

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

Hola, este es un texto de ejemplo para Oscar.

Four step: create a sessionFactory (the mother of all hibernate sessions)

The sessionFactory object is the core of hibernate. It's the provider of the session objects, the point of contact for every of your objects to get access to the data. Here you will have to configure your hibernate entities (the objects that map your database tables) and the configuration of the hibernate.

Of course, you can put the configuration in a properties file, but haven't you noticed that I prefer having all the configuration in only one place???

Here is my example:

    <bean id="sessionFactory"
          class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="annotatedClasses">
            <list>
                <!--
                <value>HERE-WILL-YOUR-HIBERNATE-ENTITIES-BUT-LEAVE-IT-EMPTY-BY-THE-MOMENT</value>
                -->
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
            </props>
        </property>
    </bean>

Map your first table

Despite you can use the Hibernate Tools to create it, by the moment I prefer to map the tables to objects by hand.

I've created this table:

DROP TABLE IF EXISTS jn_local_folder; 
 
CREATE TABLE jn_local_folder
(
id	       BIGINT AUTO_INCREMENT PRIMARY KEY NOT NULL,
message_id      VARCHAR(1000)
);

and I mapped it into an object:

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
 
 
@Entity
@Table( name = "jn_local_folder" )
public class LocalFolder
{
	private long id; 
	private String messageId;
 
	@Id
	@Column( name="id" )
	@GeneratedValue
	public long getId()
    {
    	return id;
    }
	public void setId(long id)
    {
    	this.id = id;
    }
 
	@Column( name="message_id", nullable = true, length = 1000 )
	public String getMessageId()
    {
    	return messageId;
    }
	public void setMessageId(String messageId)
    {
    	this.messageId = messageId;
    }
 
}

Use it into your own beans

It's the first time I've used hibernate 4 with spring, so I am in the process of investigating their possibilities. The first shock I've received is that there is no HibernateTemplate object at all: you have to use Hibernate natively in your own application.

Thinking it twice, it's better because the over-use of HibernateTemplate tied your code very much to Spring. With this approximation, it enforces you to use Hibernate directly, which I honestly think it's better because it frees you to remove Spring in the future without too much hassle.

I've made a very simple DAO object that can act as a basis for future developments. Here it is:

import org.hibernate.Query;
 
import org.hibernate.Session;
import org.hibernate.SessionFactory;
 
public class LocalFolderDao
{
	private SessionFactory sessionFactory; 
	private Session ses;
 
 
	public void setSessionFactory( SessionFactory sessionFactory )
	{
		this.sessionFactory = sessionFactory; 
		this.ses = sessionFactory.openSession();
	}
	public SessionFactory getSessionFactory()
	{
		return this.sessionFactory;
	}
 
	public void doSomething()
	{
 
		StringBuilder hql = new StringBuilder();
 
		hql.append( "from LocalFolder " );
		hql.append( "where messageId = :messageId " );
 
		Query q = ses.createQuery( hql.toString() );
 
		q.setParameter( "messageId", "hola" );
 
		System.out.println( q.list().size() );
	}
}
package com.supermanhamuerto.nestor.localfolder;
 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;
 
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
 
import com.supermanhamuerto.nestor.MailMessage;
import com.supermanhamuerto.nestor.entity.MessageEnt;
 
public class LocalFolderDaoImpl implements LocalFolder
{
	private static Log log = LogFactory.getLog( LocalFolderDaoImpl.class );
	private SessionFactory sessionFactory; 
	private Session ses;
 
 
	public void setSessionFactory( SessionFactory sessionFactory )
	{
		this.sessionFactory = sessionFactory; 
		this.ses = sessionFactory.openSession();
	}
	public SessionFactory getSessionFactory()
	{
		return this.sessionFactory;
	}
 
	/* (non-Javadoc)
     * @see com.supermanhamuerto.nestor.localfolder.LocalFolder#messageExist(com.supermanhamuerto.nestor.MailMessage)
     */
	@Override
    public boolean messageExist( MailMessage msg )
	{
		return messageExist( msg.getId() );
	}
 
	@Override
	public boolean messageExist(String id)
	{
		// in case of error, the message is declared as "existent"
		// to avoid entering the same message again and again
		boolean result = true;
 
		try
		{
			StringBuilder hql = new StringBuilder();
 
			hql.append( "from MessageEnt " );
			hql.append( "where messageId = :messageId " );
 
			Query q = ses.createQuery( hql.toString() );
 
			q.setParameter( "messageId", id ); 
 
			result = !q.list().isEmpty();
 
		}
		catch( Exception e )
		{
			log.error( e ); 
		}
 
		return result;
	}
 
	/* (non-Javadoc)
     * @see com.supermanhamuerto.nestor.localfolder.LocalFolder#saveMessage(com.supermanhamuerto.nestor.MailMessage)
     */
	@Override
    public void saveMessage( MailMessage msg )
	{
		MessageEnt msgEntity = new MessageEnt(); 
 
		Transaction tx = ses.beginTransaction();
 
		msgEntity.setMessageId( msg.getId() );
		msgEntity.setSent( msg.getSentDateAsDate() );
		msgEntity.setMsgFrom( msg.getFrom() );
		msgEntity.setMsgTo( msg.getTo() );
		msgEntity.setSubject( msg.getSubject() );
		msgEntity.setBody( msg.getBodyAsText() );
		ses.saveOrUpdate( msgEntity );
 
		tx.commit();
	}
 
	@Override
	public void deleteMessage( MailMessage msg )
	{
		MessageEnt msgEntity = new MessageEnt(); 
 
		Transaction tx = ses.beginTransaction();
 
		msgEntity.setMessageId( msg.getId() );
		msgEntity.setSent( msg.getSentDateAsDate() );
		msgEntity.setMsgFrom( msg.getFrom() );
		msgEntity.setMsgTo( msg.getTo() );
		msgEntity.setSubject( msg.getSubject() );
		msgEntity.setBody( msg.getBodyAsText() );
		ses.delete( msgEntity );
 
		tx.commit();
	}
 
 
}

~~DISQUS~~

java/fiststepswithhibernate.txt · Last modified: 2022/12/02 22:02 by 127.0.0.1