Hibernate for beginners

Introduction
Used tools
First Step
Second step
Log4J
Third step create a new Eclipse Project
Test class
Create a POJO
Create a hibernate config
What now

Introduction

One day late in 2008 we found that starting with hibernate is not easy - even for experienced Programmers. Against this background I decided to give this documentation - with the intention to provide a SIMPLE start with hibernate. This Document is not to make a proper hibernate project which is using all features and has only the needed jars referenced. It is explicitly opposite to that: The intention is to get quick success, to produce a running project with hibernate and to understand the idea behind that - quick and dirty :-). A minimum of swing knowledge is helpful as we use a simple dialog to write to db.

Used tools:

  • Hibernate
  • Hibernate annotations
  • h2 Database
  • Eclispe
  • Environment: Java 5 or higher should work - all is tested under java 6-11on Ubuntu 8.10

Fist Step:

download:

hibernate
http://sourceforge.net/project/showfiles.php?group_id=40712&package_id=127784
(3.2.6 recommend)

hibernate-annotations
http://sourceforge.net/project/showfiles.php?group_id=40712&package_id=139933
(3.3 recommend)

slf4j (used by hibernate)
http://www.slf4j.org/

h2
http://www.h2database.com/html/main.html
(1.1.104 (28th of Nov 2008) all platform recommend)

Extract all downloaded files
Hint: if you plan to use further extensions later (e.g hibernate-tools), check the compatibility matrix on hibernates homepage.

Second Step

Create an empty folder
mkdir /home/mydev

Copy following jars from download (either from ./ (root) of your downloaded file and/or from ./lib folder you should have the following jars:

from hibernate32
  • hibernate3.jar
from hibernate-32/lib
  • ant-1.6.5.jar
  • ant-antlr-1.6.5.jar
  • ant-junit-1.6.5.jar
  • ant-launcher-1.6.5.jar
  • antlr-2.7.6.jar
  • ant-swing-1.6.5.jar
  • asm-attrs.jar
  • asm.jar
  • c3p0-0.9.1.jar
  • cglib-2.1.3.jar
  • checkstyle-all.jar
  • cleanimports.jar
  • commons-collections-2.1.1.jar
  • commons-logging-1.0.4.jar
  • concurrent-1.3.2.jar
  • dom4j-1.6.1.jar
  • ehcache-1.2.3.jar
  • hibernate3.jar
  • jaas.jar jacc-1_0-fr.jar
  • javassist.jar
  • jaxen-1.1-beta-7.jar
  • jboss-cache.jar
  • jboss-common.jar
  • jboss-jmx.jar
  • jboss-system.jar
  • jgroups-2.2.8.jar
  • jta.jar
  • junit-3.8.1.jar
  • log4j-1.2.11.jar
  • oscache-2.1.jar
  • proxool-0.8.3.jar
  • swarmcache-1.0rc2.jar
  • syndiag2.jar
  • versioncheck.jar
  • xerces-2.6.2.jar
  • xml-apis.jar
from hibernate annotations
  • hibernate-annotations.jar
from annotations/lib
  • ejb3-persistence.jar
  • hibernate-annotations.jar
  • hibernate-commons-annotations.jar
form slf4j
  • slf4j-simple-1.5.6.jar
from h2/bin
  • h2-1.1.104.jar

Check that you have ALL jars !!!

Third step create a new Eclipse Project

File New Java Project
Set build Path:

  • richtclick on your project and select "Buildpath" and then "Configure Buildpath ... "
  • goto libraries sheet and select "Add external jar"
  • In the dialog navigate to the folder to which you have collected the jars above and select all jars (ctrl + a, then OK).
Worst is done now :-)

Log4J

Create in src folder of your project a file named log4j.properties and add the following content

log4j.rootLogger=INFO,MeinConsoleAppender, FileAppender
log4j.appender.MeinConsoleAppender=org.apache.log4j.ConsoleAppender
log4j.appender.MeinConsoleAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.MeinConsoleAppender.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c: %m%n
log4j.appender.FileAppender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.FileAppender.file=MeineLogDatei.log
log4j.appender.FileAppender.Append=true
log4j.appender.FileAppender.MaxFileSize=10000KB
log4j.appender.FileAppender.MaxBackupIndex=2
log4j.appender.FileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.FileAppender.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c: %m%n

Test class

Create a new Testclass
In Eclipse press (in Menu) File -> new ->Java class and name it Test (case-sensitive).
Paste the following code into the Test class (note that it is directly in src Folder - no packages for simpleness ...)

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

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

public class Test extends JFrame {
  private JButton button;
  private JTextField textField;
  private SessionFactory sessionFactory;

  public static void main(String[] args){
    new Test();
  }

  public Test(){
// get a sessionfactory from hibernate on startup - this is needed to get a
    // session later
    try{
// if you do not like annotations, you might configur with xml Files -
// if so, the Factory is a different (Configuration())
      sessionFactory = new AnnotationConfiguration().configure()
          .buildSessionFactory();

    }
    catch(Throwable e){
      throw new ExceptionInInitializerError(e);
    }
    createView();
    createListener();
    pack();
    setVisible(true);
  }

  private void createView(){
    setLayout(new FlowLayout());
    add(textField = new JTextField(6));
    add(button = new JButton("button"));
  }

  private void createListener(){
    button.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent arg0){
// in hibernate you usually communicate with DB by
// getting / providing POJOs
        POJO p = new POJO();
        p.setValue(textField.getText());
// take a session
        Session sess = sessionFactory.getCurrentSession();
// Start transaction
        sess.beginTransaction();
        sess.save(p);
// commit transaction
        sess.getTransaction().commit();
      }
    });
  }
}
timpt.de - X2H V 0.17

This Test class is just providing a Dialog with a Textbox and a Button.
On start it will set the Sessionfactory for Hibernate Annotations.
In the Actionlistener it will create a POJO (which is a pojo - see next Chapter), sets the value of that POJO and stores it in DB.

Create a POJO

As you can see in source above, communication is done using POJOs - we need to create one.
In eclipse press on File ->New -> Java Class and name it POJO.
Paste the following content in POJO class.

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

import org.hibernate.annotations.GenericGenerator;

@Entity
@Table(name = "POJO")
public class POJO {
  @Column(name = "value", length = 60)
  public String getValue(){
    return value;
  }

  public void setValue(String value){
    this.value = value;
  }

  @Id
  @GeneratedValue(generator = "system-uuid")
  @GenericGenerator(name = "system-uuid", strategy = "uuid")
  public String getIdentifier(){
    return identifier;
  }

  public void setIdentifier(String identifier){
    this.identifier = identifier;
  }

  private String value;
  private String identifier;

timpt.de - X2H V 0.17

As you can see, the POJO is just a POJO - plus some Annotations. Some explanation might help you:

  • @Entity @Table(name = "POJO") - This are Annotations on Class Level* and mark that this Class represents an Entity and that there is a corresponding Table with the name "POJO"
  • @Column(name = "value", length = 60) - This provides information that this attribute is corresponding to the column value in the table POJO and that size is limited to 60 characters
  • @Id - This marks an Attribute as Identifier (ID)
  • @GeneratedValue(generator="system-uuid") @GenericGenerator(name="system-uuid", strategy = "uuid") - This describes how IDs will be generated. This is one of the first things you will change, because it is usually not the best idea to use an Identifier of type String (we did it for simplicity, if you change it be aware that not all Databases work with all Strategies!) to use a different generator, read hibernate Documentation (Keyword: Strategy)
* The level of Annotations describe the position and the validity range - e.g. a Class Level Annotation is valid for all Elements of the class.

Create a hibernate config

This file is the fix-point for Configuration of hibernate.
It provides the Info how to connect to DB along with the info which File will be mapped (name and relative Path, here not necessary due to all Files are in one folder).
In Eclipse in Menu press on File ->New ->File , name it hibernate.cfg.xml (case sensitive) in the src folder.
Paste the following code in this file:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.bytecode.use_reflection_optimizer">false</property>
<property name="hibernate.connection.driver_class">org.h2.Driver</property>
<property name="hibernate.connection.password">obiwan</property>
<property name="hibernate.connection.url">jdbc:h2:file:~/marcel</property>
<property name="hibernate.connection.username">kenobi</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<mapping class="POJO"/>
</session-factory>
</hibernate-configuration>

This will create a Database EACH time you will start the program (due to <property name="hibernate.hbm2ddl.auto">create</property>)
Usually you will use it only on first start up, because it automatically create an empty Database on EVERY Start
Therefore after first start you should change it to <property name="hibernate.hbm2ddl.auto">update</property>
By this only new Columns will be added if you add them to the POJO AND you have annotated them.

Now you might start the program (right-click on Test class and select runas Java Application).

A dialog will be displayed.
You can write something into the textfield and press the button - the content of the textfield will be written into the DB.
You can stop it with eclipse (Terminate button in Console View) - due to simpleness and laziness a Windowadapter is missing.

If you do not trust the results download a db tool (eg. Squirrel) and configure it to connect to db.
Be aware that this is only possible if you will have the Test class NOT running - due to the fact that in the given scenario only one connection to DB is configured.

A simple configuration for Squirrel would be:

  • Start Squirrel and add the H2 diver to Squirrel:
    Menubar -> Driver -> New Driver -> Alternative Class Path select add , then select the h2xxx.jar (you have downloaded at the beginning ) and press show Driver Button.
  • goto Aliases Window, press plus sign and give settings:
    • Name - Myhib
    • Driver - select the h2 driver you have added in previous step
    • url - copy it from the hibernate.cfg.xml ( jdbc:h2:file:~/marcel )
    • user - as given in hibernate.cfg.xml
    • password - as given in hibernate.cfg.xml

Say OK and doubleclick on Myhib, confirm user and password and the db will be opened ...
You will see in the public / table node the table POJO with the value you gave ...

That's all, folks ...!


What now?

If you need more than one POJO, you can create it, annotate id accordingly and add a mapping in hibernate.cfg.xml.
If the Pojo is in a package, add the package in dotted notation e.g. my.package.hib.Person.
Read about the generators in the hibernate documentation!
In my eyes one of the most famous tools for hibernate is the hibernate tools - by which you can reengineer from a database the complete hibernate stuff including annotated Pojos!
If you would like to test it, TAKE A LOOK into COMPATILIBITY MATRIX on Hibernate Homepage, otherwise you will be very soon highly frustrated.
Be aware that for me a one2many annotation did NOT remove the orphan elements, although it was proper annotated.
An alternative to hibernate might be OpenJPA -not Mainstream, but it is an Apache child.

What if something is not working?

That cannot happen :-)
... but if...
Depending on the Eclispe Version / Settings files are not copied to the folder which holds the .class files- but this is mandatory.
Check if hibernate.cfg.xml and log4j.properties, POJO.class and Test.class are all in one Folder.
Marcel (by the way: Thank You!) found that the latest version of H2 causes some trouble (I could not reproduce). However, he solved it by taking the November 2008 Version (103).
I hope that some Colleagues will read and and give Feedback (Infotech (Hyderabad, India) as well as some friends here, e.g. "Hochwürden", "Hartmudus K....saurus", ...)