Hibernate with MySQL – a beginners guide – part 2

This post is a follow on from my previous post Hibernate with MySQL – a beginners guide – part 1. Having followed part 1, you should have a simple java application that prints ‘ok’, an ant build script, and downloaded hibernate and the MySQL connector. Now it’s time to do something useful!

In this part, we’re going to create a simple class called ‘Blog’ which will store blog posts. It will have a subject, a body, and a created date.

Setting up and installing MySQL is not something I’m going to cover here, so I’ll assume you have a running MySQL server. Create yourself a database now for hibernate to use. In this example my database name is simply ‘hibernate’.

Creating the Blog class

Create a class to hold information about a blog post, I put this in src/uk/co/pookey/Blog.java

package uk.co.pookey;

import java.util.Date;

public class Blog {

  private Long id;

  private String subject;

  private String body;

  private Date createdAt;

  public Long getId() {
    return id;
  }

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

  public String getSubject() {
    return subject;
  }

  public void setSubject(String subject) {
    this.subject = subject;
  }

  public String getBody() {
    return body;
  }

  public void setBody(String body) {
    this.body = body;
  }

  public Date getCreatedAt() {
    return createdAt;
  }

  public void setCreatedAt(Date createdAt) {
    this.createdAt = createdAt;
  }
}

Unit Testing

To unit test our new class, we’ll use testNG (mostly because the junit site was broken at time of writing!). First we need to modify our ant build script. This will allow us to run tests simply by running ‘ant test’. When developing an application, it is vitally important you make it as easy as possible to run the tests, otherwise you’ll not bother to do it. Here is the extra snippet that needs adding:

    
    
      
        
          
        
        
      
    

Now lets download and install testng

$ cd lib
$ wget "http://testng.org/testng-5.7.zip"
$ unzip testng-5.7.zip
$ cp testng-5.7/*.jar .

All we need to do now is write our tests for the Blog class.

package uk.co.pookey;

import uk.co.pookey.Blog;
import java.util.Date;
import org.testng.annotations.*;

public class BlogTest {

  @Test
  public void setIdTest() {
    Blog b = new Blog();
    b.setId(new Long(10));
    assert (b.getId() == 10) : "ID was not returned as expected";
  }

  @Test
  public void setBodyTest() {
    Blog b = new Blog();
    b.setBody("this is a test");
    assert "this is a test".equals(b.getBody());
  }

  @Test
  public void setSubjectTest() {
    Blog b = new Blog();
    b.setSubject("this is a test");
    assert "this is a test".equals(b.getSubject());
  }

  @Test
  public void setCreatedAtTest() {
    Blog b = new Blog();
    Date d = new Date();
    b.setCreatedAt(d);
    assert d.equals(b.getCreatedAt());
  }

}

Finally, we’ll run our test to make sure everything is working as expected.

$ ant test
Buildfile: build.xml

clean:
   [delete] Deleting directory /home/pookey/hibernate/bin
    [mkdir] Created dir: /home/pookey/hibernate/bin

copy-resources:
     [copy] Copying 1 file to /home/pookey/hibernate/bin
     [copy] Copied 4 empty directories to 2 empty directories under /home/pookey/hibernate/bin

compile:
    [javac] Compiling 3 source files to /home/pookey/hibernate/bin
    [javac] warning: [path] bad path element "/usr/share/ant/lib/xml-apis.jar": no such file or directory
    [javac] warning: [path] bad path element "/usr/share/ant/lib/xercesImpl.jar": no such file or directory
    [javac] warning: [path] bad path element "/usr/share/ant/lib/xalan.jar": no such file or directory
    [javac] 3 warnings

test:
   [testng] [Parser] Running:
   [testng]   Ant suite
   [testng]
   [testng] PASSED: setCreatedAtTest
   [testng] PASSED: setIdTest
   [testng] PASSED: setBodyTest
   [testng] PASSED: setSubjectTest
   [testng]
   [testng] ===============================================
   [testng]     Ant test
   [testng]     Tests run: 4, Failures: 0, Skips: 0
   [testng] ===============================================
   [testng]
   [testng]
   [testng] ===============================================
   [testng] Ant suite
   [testng] Total tests run: 4, Failures: 0, Skips: 0
   [testng] ===============================================
   [testng]

Time to hibernate

First, we need to copy over the required Jar files into our lib folder – you should have downloaded hibernate in part 1, so all you need to do is copy the following:

cp lib/hibernate-3.2/hibernate3.jar lib/
cp lib/hibernate-3.2/lib/dom4j-1.6.1.jar lib/
cp lib/hibernate-3.2/lib/commons-logging-1.0.4.jar lib
cp lib/hibernate-3.2/lib/commons-collections-2.1.1.jar lib
cp lib/hibernate-3.2/lib/jta.jar lib/
cp lib/hibernate-3.2/lib/log4j-1.2.11.jar lib/
cp lib/hibernate-3.2/lib/cglib-2.1.3.jar ./lib
cp lib/hibernate-3.2/lib/asm.jar ./lib/

Hibernate has several ways to configure it’s connection properties, in this example we’re going to use an XML config file. Here is an example of this file, which should be created in src/hibernate.cfg.xml



  
    jdbc:mysql://localhost/hibernate
    root
    "Schipiaf2
    com.mysql.jdbc.Driver
    org.hibernate.dialect.MySQLDialect

    true

    true
    create

    
    1
    thread

    
  

The next step is to tell hibernate about our Blog class. Again we’re going to do this using a xml file, src/uk/co/pookey/Blog.hbm.xml



  
    
      
    
    
    
    
  

Having created this file, we need to add it to the hibernate.cfg.xml file just below the comment.

    
    

Modify your HibernateUtil class (src/uk/co/pookey/hibernate/HibernateUtil.java) created in part 1 to this:

$ cat src/uk/co/pookey/hibernate/HibernateUtil.java
package uk.co.pookey.hibernate;

import org.hibernate.SessionFactory;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import uk.co.pookey.Blog;

public class HibernateUtil {

  private static org.hibernate.SessionFactory sessionFactory;

  public static SessionFactory getSessionFactory() {
    if (sessionFactory == null) {
      initSessionFactory();
    }
    return sessionFactory;
  }

  private static synchronized void initSessionFactory() {
    sessionFactory = new Configuration().configure().buildSessionFactory();
  }

  public static Session getSession() {
    return getSessionFactory().openSession();
  }

  public static void main (String[] args) {
    Blog blog = new Blog();
    blog.setSubject("My test post");
    blog.setBody("This is the body of my blog post");
    blog.setCreatedAt(new java.util.Date());

    Session session = getSession();

    Transaction transaction = session.beginTransaction();

    session.save(blog);

    transaction.commit();
  }
}

Now all that remains is to run out application, and watch it insert data into the database!

$ ant run
Buildfile: build.xml

clean:
   [delete] Deleting directory /home/pookey/hibernate/bin
    [mkdir] Created dir: /home/pookey/hibernate/bin

copy-resources:
     [copy] Copying 2 files to /home/pookey/hibernate/bin
     [copy] Copied 4 empty directories to 1 empty directory under /home/pookey/hibernate/bin

compile:
    [javac] Compiling 3 source files to /home/pookey/hibernate/bin
    [javac] warning: [path] bad path element "/usr/share/ant/lib/xml-apis.jar": no such file or directory
    [javac] warning: [path] bad path element "/usr/share/ant/lib/xercesImpl.jar": no such file or directory
    [javac] warning: [path] bad path element "/usr/share/ant/lib/xalan.jar": no such file or directory
    [javac] 3 warnings

run:
     [java] log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
     [java] log4j:WARN Please initialize the log4j system properly.
     [java] Hibernate:
     [java]     select
     [java]         max(id)
     [java]     from
     [java]         blog
     [java] Hibernate:
     [java]     insert
     [java]     into
     [java]         blog
     [java]         (subject, body, createdAt, id)
     [java]     values
     [java]         (?, ?, ?, ?)

BUILD SUCCESSFUL
Total time: 3 seconds

Checking this output on MySQLs CLI shows that the record was correctly inserted.

mysql> select * from blog;
+----+--------------+----------------------------------+---------------------+
| id | subject      | body                             | createdAt           |
+----+--------------+----------------------------------+---------------------+
|  1 | My test post | This is the body of my blog post | 2008-08-01 17:50:28 |
+----+--------------+----------------------------------+---------------------+
1 row in set (0.00 sec)

In part 3 (assuming I get some feedback from the first 2 parts, or get bored enough to do a third part!) I shall cover loading and modifying a persistent object, information on how to increase the logging level, and relationships.

23 thoughts on “Hibernate with MySQL – a beginners guide – part 2”

  1. In part 1 and part 2 I showed how to get up and running with hibernate. This part continues from where we left off. I have packaged up all the files form part 2, including all required jars, and the build script. The file is 4.5meg, and is down

  2. Thanks for the introduction to using Hibernate with MySQL. I hope you get around to writing some more parts to this series!

  3. Hi, I’m new to Hibernate. I found your tutorial really useful. But, I’m facing an issue: When i try and change code of HibernateUtil.java and change values of subject and body of Blog object and build again using ant.
    The new data is inserted successfully, but the old data is removed from the database. Why is this happening when we are doing commit ??

  4. Had many troubles with this. After downloading all the jar files that were given in step 1 to install hibernate, I kept getting different errors and ended up having to add jar for xerces as well.

    If you have trouble, keep persisting and eventually you’ll come across the right resource that you are after!

  5. Hi,

    Had troubles, much like trav, but I did get there. A total n00b won’t get there without some hints, so here are some.

    First, you need an SFL4J jar in addition to those listed, to make it work. I chose slf4j-simple-1.5.8.jar which I just downloaded from the slf4j web site.

    Second, you probably want to change the username and password as listed in the src/hibernate.cfg.xml file. Change it to something that’ll work for your database, otherwise clearly it’s not going to work as it won’t connect to your database. The error is bleeding obvious when you hit this, mind you, but it’s worth pointing out that you *need to change the user credentials for this example to work*.

    Third, as someone pointed out in the previous page, running “ant run” won’t work because it’ll try to load a class called events.EventManager, which doesn’t exist. Change the line in build.xml that refers to that class to this instead:

    That was about it. Once I’d done those three things and followed the rest of the instructions, it all worked.

    It might be worth pointing out that you don’t even need to set up your database table; Hibernate takes care of that for you. Unfortunately, running the example twice will drop the table and create it again, so don’t get confused when you run it three times and wonder why there is only one entry in the table, rather than appending new entries each time.

    1. Please use this line to replace ‘events.EventManager’ entry in build.xml:
      java fork=”true” classname=”uk.co.pookey.hibernate.HibernateUtil” classpathref=”libraries”

      Kenny’s info is not readable in browser (you can view page source to discover it). Hope it helps.

  6. Hi All,

    I ran into some trouble and got a solution, so thought of sharing this info.

    I had to execute the below query to allow the Hibernate to connect to MySQL.

    grant all privileges on *.* to [email protected]’RAM’ identified by ‘admin’;

    where RAM is my computer name.

    Thanks,
    Ram

  7. Found the tutorial friendly to beginners and very helpful.
    I followed the instructions. Added the items Kenny listed.
    I got this error ( removed the ” to make it readable:
    java fork=”true” classname=”uk.co.pookey.hibernate.HibernateUtil” classpathref=”libraries”

    Do you have suggestions for fixing it? Many thanks.

  8. sorry, too tired, had type. my error msg:
    Exception in thread “main” java.lang.IllegalAccessError: tried to access field org.slf4j.impl.StaticLoggerBinder.SINGLETON from class org.slf4j.LoggerFactory

    Thanks for your help.

    1. Solution:
      1. Remove file:
      hibernatelibslf4j-api-1.5.2.jar

      2. Add to your project two new files:
      slf4j-api-1.5.11.jar
      slf4j-log4j12-1.5.11.jar

      Just make sure they are the same version.
      It should resolve the above problem.

  9. Thank you very much. I’ve been through 3 example programs before this and it the first one that worked. No problems at all.

  10. Very useful articles though some dependency issues were there. Also I had given the password as given in
    “Schipiaf2

    Thinking it was not closed, I used “pwd”. took much time to figure out that this is the reason that the connection was failing 🙂

  11. Everytime I run this with modified values, it does not insert new record. Instead it updates the first record it created. I tried setting blog.Id() to a new value. even then it updated the same records where id=1. What’s wrong?

  12. worked fine, juts the [java fork=”true” classname=”[yourPackage].HibernateUtil” classpathref=”libraries”] issue, and i also mention that i put in my /lib all jars from the hibernate bunddle.

    thanks

  13. This is a great article for a beginner like me, thanks a lot for sharing this, it would be nice if there where more explanation on sessionFactory too. when ur going to up the 3rd part., cant wait for it……..

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.