Hibernate Tutorial in Kurzform

Hibernate Tutorials sind oft schwergewichtig und komplex. Aus diesem Grund möchte ich einen kleinen Beispiel-Code veröffentlichen, wie man in Hibernate die Attribute (Variablen) einer Java Klasse (Plain Old Java Object) in einer relationalen Datenbank (MySQL) abspeichert. Weil Hibernate ein Thema für fortgeschrittene Java-Entwickler ist, gehe ich davon aus, dass man anhand des Codes sich die Zusammenhänge erschließen kann.

Für die im Beispiel verwendete Datenbank wurden folgende Einstellungen getroffen:

Host (Server): localhost
Port: 3306 (Standard)
Datenbank: demodb
Benutzer: demouser
Passwort: NxEcT5tjJTuLBLTQ
Kollation: utf8_general_ci
Tabellen-Typ: InnoDB

Diese Einstellungen werden in der Konfigurationsdatei hibernate.cfg.xml für Hibernate hinterlegt:

hibernate.cfg.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?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="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/demodb</property>
        <property name="hibernate.connection.username">demouser</property>
        <property name="hibernate.connection.password">NxEcT5tjJTuLBLTQ</property>
 
        <!-- SQL dialect -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
 
        <!-- JDBC connection pool (built-in) -->
        <property name="connection.pool_size">10</property>
 
        <!-- Disable the second-level cache -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
 
        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>
 
        <!-- Mapping files -->
        <!-- Not needed, because of Annotations -->
    </session-factory>
</hibernate-configuration>

Danach kann man die Datenbank mitsamt einer Tabelle in phpMyAdmin anlegen. In unserem Beispiel soll es die Tabelle users geben, welche die Felder user_id, first_name und last_name beinhaltet. Die „user_id“ soll eine Ganzzahl (Integer) sein, welche unsere Benutzer mit fortlaufend nummeriert (1, 2, 3, …). Über diese Identifikationsnummer kann dann jeder Eintrag in unserer „users“-Tabelle eindeutig bestimmt werden. Die „user_id“ wird also zu einem Primärschlüssel (Primary Key). Die fortlaufende Nummerierung übernimmt MySQL dank „Auto Increment“ selbstständig.

Damit das Anlegen der Tabelle etwas leichter fällt, hier ein Screenshot:

Nachdem man die Tabelle angelegt hat, kann man nun diese Tabelle in einem Werteobjekt (Value Object) abbilden. Dazu überlegt man sich eine Java-Klasse, die dem entspricht, was in der Tabelle angelegt wurde. Der Datentyp VARCHAR ist eine variable Zeichenkette und in Java somit ein String. Der Datentyp INT ist in Java ebenfalls ein int (Integer).

Wir erstellen also eine User-Klasse mit den drei Attributen (ID, FirstName, LastName) als Klassen-Variablen:

VO_User.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package de.bennyn.example.hibernate;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Entity;
import javax.persistence.GenerationType;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
 
@Entity
@SequenceGenerator(name="user_id", initialValue=1, allocationSize=1)
@Table(name="users")
public class VO_User implements Serializable
{
    int     intUserID;
    String  strFirstName;
    String  strLastName;
 
    // Default-Konstruktor:
    public VO_User()
    {
 
    }
 
    /* Getter */
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="user_id", nullable=false)
    public int getIntUserID()
    {
        return intUserID;
    }
 
    @Column(name="first_name", nullable=false)
    public String getStrFirstName()
    {
        return strFirstName;
    }
 
    @Column(name="last_name", nullable=false)
    public String getStrLastName()
    {
        return strLastName;
    }
 
    /* Setter */
    public void setIntUserID(int intUserID)
    {
        this.intUserID = intUserID;
    }
 
    public void setStrFirstName(String strFirstName)
    {
        this.strFirstName = strFirstName;
    }
 
    public void setStrLastName(String strLastName)
    {
        this.strLastName = strLastName;
    }
}

Für Hibernate ist dabei besonders wichtig, dass die Klasse einen leeren Default-Konstruktor hat und jede Klassen-Variable über eine Getter-Methode, benannt nach dem Standard-Namensschema (getVariablenName()), verfügt. Am Besten man lässt sich die Setter/Getter automatisch generieren (mit NetBeans über „Source“ > „Insert Code“).

Hinweis: Die Annotations sind erst ab JDK Version 1.5 verfügbar.

Über die „Annotations“ (die Anmerkungen mit dem vorangestellten @-Zeichen) wird Hibernate klar gemacht, wie die Klasse und ihre Attribute auf eine relationale Datenbank abgebildet wird. Diesen Vorgang nennt man „Mapping“. Jede Klasse wird beim Mapping zu einer eigenen Entität und bekommt daher ein @Entity. Die Annotation @Table legt fest, wie die Tabelle heißt, in der die Objekte der Klasse abgespeichert werden.

Mit @SequenceGenerator wird der Primärschlüssel („user_id“) angegeben und das Format, wie er aussehen soll. In unserem Beispiel beginnt der Primärschlüssel bei „1“ (initialValue) und wird immer um „1“ weitergezählt (allocationSize). Damit Hibernate auch wirklich weiß, welche Variable wir als Primärschlüssel benutzen wollen, bekommt die Getter-Methode der Primärschlüssels noch ein @Id. Außerdem wird mit @GeneratedValue noch die Strategie festgelegt, nach der der Primärschlüssel erstellt wird. Wir überlassen dieses Problem in diesem Fall mit GenerationType.AUTO der Datenbank.

Die Annotation @Column wird dazu verwendet, um anzugeben, wie die Spalte heißt, in der die Variablen abgespeichert werden. Mit dem Zusatz nullable=false kann festgelegt werden, dass die entsprechenden Spalten nicht leer sein dürfen.

Hat man diese Minimalkonfigurationen berücksichtigt, kann man auch schon damit beginnen, seine Java-Objekte persistent (nachhaltig) in der Datenbank abzuspeichern. Dazu benötigen wir eine kleine Helferklasse, welche uns eine Session für Transaktionen bereitstellt:

HibernateUtil.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import de.bennyn.example.hibernate.VO_User;
 
 
public class HibernateUtil
{
    private static SessionFactory sessionFactory;
 
    static
    {
        try
        {
            sessionFactory = new AnnotationConfiguration()
                                .addPackage("de.bennyn.example.hibernate")
                                .addAnnotatedClass(VO_User.class)
                                .configure()
                                .buildSessionFactory();
        }
        catch (RuntimeException ex)
        {
            System.out.println(ex.getMessage());            
        }
    }
 
    public static SessionFactory getSessionFactory()
    {
        return sessionFactory;
    }
}

Jetzt ist die Grundlage geschaffen, um endlich einen Eintrag in die Datenbank zu machen. Der folgende Code ist ausführbar und erstellt einen Eintrag in der Datenbank, sofern ein MySQL-Server läuft in die Datenbank mit der entsprechenden Tabelle angelegt ist.

Test_Hibernate.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import de.bennyn.example.hibernate.VO_User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
 
public class Test_Hibernate
{
    public static void main(String[] args)
    {
        VO_User newUser = new VO_User();
        newUser.setStrFirstName("Benny");
        newUser.setStrLastName("Neugebauer");
 
        SessionFactory sf       = HibernateUtil.getSessionFactory();
        Session session         = null;
        Transaction transaction = null;
 
        // Neuen Benutzer in Datenbank speichern:
        try
        {
            session             = sf.getCurrentSession();
            transaction         = session.beginTransaction();
            session.save(newUser);
            transaction.commit();
        }
        catch (Exception e)
        {
            // rollback(transaction);
            System.out.println(e.getMessage());
        }
    }
}

Damit das Beispiel sich fehlerfrei kompilieren lässt, müssen folgende 12 Libraries dem Projekt hinzugefügt werden:

Weiterführende Links zu Hibernate:
http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/
http://www.ordix.de/ORDIXNews/3_2007/Java_J2EE_JEE/hibernate_teilV.html
http://blog.doubleslash.de/wp-content/uploads/2007/03/java-persistenz-mit-hibernate.pdf
http://www.galileocomputing.de/artikel/gp/artikelID-328
http://www.saturius.de/2007/10/02/hibernate/

7 Gedanken zu „Hibernate Tutorial in Kurzform“

  1. Sehr schönes Tutorial 🙂
    Wobei ich ehrlich sagen muss, dass ich ewig nach einem Fehler in meiner Persistierung gesucht hatte, weil ich kein Auto_Increment eingestellt hatte.
    Vielleicht wäre es sinnvoll, zusätzlich zum screenshot doch noch das SQL-Statement zur Tabellenerzeugung darzustellen- für mich wär’s einfacher gewesen..

  2. Hey,
    richtig gutes kleines Tutorial, danke!
    Eine Sache hast du allerdings vergessen zu erwähnen, die mich ne Stunde gekostet hat: Man braucht die Java Enterprise Edition, wegen den java.persistence.* Klassen.

    (Leider habe ich es als Mac user nicht geschafft jene zu installieren…)

  3. Das Projekt als ganzes on zu stellen würde deine Leistung noch etwas großartiger machen.
    Mich als armen Azubi hat jetzt die „krieg-das-mal-irgendtwie-hin“ Keule erwischt.
    Ich fände es das Project hier laden zu können oder wenn du es mir als PM schicken könntest (bzw. etwas deatailierte beschreiben könntest wie ich im Eclipse überhaupt anfange)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.