Tutorials  /  JavaScript

Spring Hibernate Integration Beispiel

Ccentron Redaktion · Februar 2024 ·7 Min. Lesezeit ·JavaScript, Tutorial

Spring ist eines der am meisten verwendeten Java EE Frameworks und Hibernate ist das beliebteste ORM-Framework. Deshalb wird die Kombination aus Spring und Hibernate häufig in Unternehmensanwendungen eingesetzt.

Spring Hibernate

In diesem Tutorial werden wir heute Spring 4 verwenden und es mit Hibernate 3 integrieren, und dann dasselbe Projekt aktualisieren, um Hibernate 4 zu verwenden. Da es viele Versionen sowohl für Spring als auch für Hibernate gibt und das Spring ORM-Artefakt sowohl Hibernate 3 als auch Hibernate 4 unterstützt, ist es gut, dass ich alle Abhängigkeiten aufliste, die ich in meinem Projekt verwendet habe. Beachten Sie, dass ich festgestellt habe, dass nicht alle Spring- und Hibernate-Versionen kompatibel sind. Die unten aufgeführten Versionen haben bei mir funktioniert, also denke ich, dass sie kompatibel sind. Wenn Sie andere Versionen verwenden und java.lang.NoClassDefFoundError erhalten, bedeutet dies, dass sie nicht kompatibel sind. Meistens liegt das daran, dass Hibernate-Klassen von einem Paket in ein anderes verschoben wurden, was diesen Fehler verursacht. Zum Beispiel wurde die Klasse org.hibernate.engine.FilterDefinition in neueren Hibernate-Versionen nach org.hibernate.engine.spi.FilterDefinition verschoben.

  • Spring Framework-Version: 4.0.3.RELEASE
  • Hibernate Core und Hibernate EntityManager-Version: 3.6.9.Final und 4.3.5.Final
  • Spring ORM-Version: 4.0.3.RELEASE
VM

Passende Infrastruktur bei centron

Node-Anwendungen wollen deployt werden: ccloud³ VMs mit vollem Root-Zugriff ab 3,11 € im Monat – oder gleich als Managed Server, wenn der Betrieb nicht bei Ihnen liegen soll. Cloud Server mieten →

Datenbankeinrichtung

Ich verwende eine MySQL-Datenbank für mein Projekt, daher wird das untenstehende setup.sql-Skript die notwendige Tabelle für dieses Beispiel erstellen.

SQL
CREATE TABLE `Person` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL DEFAULT '',
  `country` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
commit;
Spring-Hibernate-Integration-Example-Project

Maven-Abhängigkeiten für die Spring-Hibernate-Integration

Sehen wir uns zuerst die Datei pom.xml mit allen benötigten Abhängigkeiten und ihren Versionen an.

Die wichtigen Abhängigkeiten für ein Projekt mit Spring-Hibernate-Integration sind:

Code
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.springframework.samples</groupId>
    <artifactId>SpringHibernateExample</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <!-- Generic properties -->
        <java.version>1.6</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        <!-- Spring -->
        <spring-framework.version>4.0.3.RELEASE</spring-framework.version>

        <!-- Hibernate / JPA -->
        <!-- <hibernate.version>4.3.5.Final</hibernate.version> -->
        <hibernate.version>3.6.9.Final</hibernate.version>

        <!-- Logging -->
        <logback.version>1.0.13</logback.version>
        <slf4j.version>1.7.5</slf4j.version>
    </properties>

    <dependencies>
        <!-- Spring and Transactions -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>

        <!-- Spring ORM support -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>

        <!-- Logging with SLF4J & LogBack -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
            <scope>runtime</scope>
        </dependency>

        <!-- Hibernate -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate.version}</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.9</version>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
    </dependencies>
</project>
  • spring-context und spring-tx für die Kernfunktionen von Spring. Beachten Sie, dass ich Version 4.0.3.RELEASE verwende.
  • spring-orm für die ORM-Unterstützung von Spring; diese Abhängigkeit ist für die Hibernate-Integration in unserem Spring-Projekt erforderlich.
  • hibernate-entitymanager und hibernate-core für das Hibernate-Framework. Die Version ist hier 3.6.9.Final; für Hibernate 4 genügt es, sie auf 4.3.5.Final zu ändern, wie in der pom.xml oben kommentiert.
  • mysql-connector-java als MySQL-Treiber für die Datenbankverbindung.

Modellklasse bzw. Entity Bean mit JPA-Annotationen

Wir können sowohl das XML-basierte Mapping von Hibernate als auch das Mapping über JPA-Annotationen verwenden. Hier nutze ich JPA-Annotationen, weil Hibernate eine JPA-Implementierung mitbringt.

Go
package com.journaldev.model;

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

/**
 * Entity bean with JPA annotations
 * Hibernate provides JPA implementation
 * @author pankaj
 *
 */
@Entity
@Table(name="Person")
public class Person {

    @Id
    @Column(name="id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
    
    private String name;
    
    private String country;

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }
    
    @Override
    public String toString(){
        return "id="+id+", name="+name+", country="+country;
    }
}

DAO-Interface

In unseren DAO-Klassen implementieren wir zwei Methoden: die erste speichert das Person-Objekt in der Tabelle, die zweite liest alle Datensätze aus der Tabelle und gibt sie als Liste von Person-Objekten zurück.

Go
package com.journaldev.dao;

import java.util.List;
import com.journaldev.model.Person;

public interface PersonDAO {
    public void save(Person p);
    public List<Person> list();
}

Die Implementierung der DAO-Klasse sieht dann so aus:

Go
package com.journaldev.dao;

import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import com.journaldev.model.Person;

public class PersonDAOImpl implements PersonDAO {
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    public void save(Person p) {
        Session session = this.sessionFactory.openSession();
        Transaction tx = session.beginTransaction();
        session.persist(p);
        tx.commit();
        session.close();
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<Person> list() {
        Session session = this.sessionFactory.openSession();
        List<Person> personList = session.createQuery("from Person").list();
        session.close();
        return personList;
    }
}

Beachten Sie, dass dies die einzige Stelle ist, an der wir Hibernate-Klassen verwenden. Dieses Muster hält unsere Implementierung flexibel und erleichtert den Wechsel von einer Technologie zu einer anderen. Wollten wir zum Beispiel das ORM-Framework iBatis einsetzen, bräuchten wir lediglich eine DAO-Implementierung für iBatis und müssten die Spring-Bean-Konfigurationsdatei anpassen. Im obigen Beispiel verwende ich das Transaktionsmanagement der Hibernate-Session. Genauso lässt sich aber das deklarative Transaktionsmanagement von Spring über die Annotation @Transactional nutzen

Spring-Bean-Konfigurationsdatei für die Hibernate-3-Integration

Code
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
    xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:aop="https://www.springframework.org/schema/aop"
    xmlns:tx="https://www.springframework.org/schema/tx"
    xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
        https://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        https://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

    <bean
        destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/TestDB" />
        <property name="username" value="pankaj" />
        <property name="password" value="pankaj123" />
    </bean>

    <!-- Hibernate 3 XML SessionFactory Bean definition-->
    <!--  <bean
       >
        <property name="dataSource" ref="dataSource" />
        <property name="mappingResources">
            <list>
                <value>person.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <value>
                hibernate.dialect=org.hibernate.dialect.MySQLDialect
            </value>
        </property>
    </bean> -->

    <!-- Hibernate 3 Annotation SessionFactory Bean definition-->
    <bean
       >
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>
                <value>com.journaldev.model.Person</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.current_session_context_class">thread</prop>
                <prop key="hibernate.show_sql">false</prop>
            </props>
        </property>
    </bean>
    
    <bean>
        <property name="sessionFactory" ref="hibernate3AnnotatedSessionFactory" />
    </bean>
</beans>

Es gibt zwei Wege, Hibernate die Verbindungsdaten der Datenbank mitzugeben: erstens alles über hibernateProperties zu übergeben, zweitens eine DataSource anzulegen und diese an Hibernate zu übergeben. Ich bevorzuge den zweiten Ansatz – deshalb ist die Abhängigkeit Apache Commons DBCP eingebunden, um über die Verbindungseigenschaften eine BasicDataSource zu erzeugen. Für die Integration von Spring und Hibernate 3 stellt Spring ORM zwei Klassen bereit: org.springframework.orm.hibernate3.LocalSessionFactoryBean für XML-basierte Hibernate-Mappings und org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean für annotationsbasiertes Mapping. Eine einfache Bean-Konfiguration für LocalSessionFactoryBean habe ich als Kommentar hinterlegt, falls Sie XML-basierte Mappings verwenden. AnnotationSessionFactoryBean erbt von LocalSessionFactoryBean und verfügt damit über alle grundlegenden Eigenschaften für die Hibernate-Integration. Die Eigenschaften sind größtenteils selbsterklärend und Hibernate-spezifisch, deshalb gehe ich hier nicht weiter auf sie ein. Wenn Sie sich fragen, woher hibernateProperties und annotatedClasses kommen: ein Blick in den Quellcode der Bean-Klasse hilft weiter. Beachten Sie die Bean-Definition von personDAO – wie erwähnt müssten wir für einen Wechsel zu einem anderen ORM-Framework hier die Implementierungsklasse austauschen und die jeweils nötigen Eigenschaften setzen.

Testprogramm für Spring 4 und Hibernate 3

Go
package com.journaldev.main;

import java.util.List;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.journaldev.dao.PersonDAO;
import com.journaldev.model.Person;

public class SpringHibernateMain {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

        PersonDAO personDAO = context.getBean(PersonDAO.class);

        Person person = new Person();
        person.setName("Pankaj"); person.setCountry("India");

        personDAO.save(person);

        System.out.println("Person::"+person);

        List<Person> list = personDAO.list();

        for(Person p : list){
            System.out.println("Person List::"+p);
        }
        //close resources
        context.close(); 
    }
}

Wenn wir das obige Programm ausführen, erhalten wir viel Hibernate-bezogene Ausgabe, weil ich das Logging nicht sauber konfiguriert habe – das führt hier aber zu weit. Unser Programm erzeugt jedenfalls die folgende Ausgabe.

Code
Person::id=3, name=Pankaj, country=India
Person List::id=1, name=Pankaj, country=India
Person List::id=2, name=Pankaj, country=India
Person List::id=3, name=Pankaj, country=India

Änderungen für die Integration von Spring 4 und Hibernate 4

Stellen wir unsere Anwendung nun von Hibernate 3 auf Hibernate 4 um. Für diese Migration sind lediglich die folgenden Konfigurationsänderungen nötig.

pom.xml aktualisieren

Ändern Sie die Hibernate-Version in der Datei pom.xml auf 4.3.5.Final, wie oben in den Kommentaren gezeigt.

Spring-Bean-Konfigurationsdatei für die Hibernate-4-Integration

Passen Sie die Spring-Bean-Konfigurationsdatei an. Inzwischen dürfte deutlich geworden sein, dass diese Datei der Schlüssel zur Integration von Spring und Hibernate ist. Unten steht die Konfiguration, die mit Spring 4 und Hibernate 4 funktioniert.

Code
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
    xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:aop="https://www.springframework.org/schema/aop"
    xmlns:tx="https://www.springframework.org/schema/tx"
    xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
        https://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        https://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

    <bean
        destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/TestDB" />
        <property name="username" value="pankaj" />
        <property name="password" value="pankaj123" />
    </bean>

    <!-- Hibernate 4 SessionFactory Bean definition -->
    <bean
       >
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>
                <value>com.journaldev.model.Person</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.current_session_context_class">thread</prop>
                <prop key="hibernate.show_sql">false</prop>
            </props>
        </property>
    </bean>

    <bean>
        <property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
    </bean>
</beans>

Für Hibernate 4 verwenden wir org.springframework.orm.hibernate4.LocalSessionFactoryBean für die SessionFactory-Bean. Spring ORM hat die beiden Klassen aus Hibernate 3 zusammengeführt, es gibt jetzt nur noch eine – das vermeidet Verwechslungen. Alle übrigen Konfigurationen bleiben unverändert.

Damit ist unser Projekt erfolgreich auf Hibernate 4 migriert. Ändern Sie in der Klasse SpringHibernateMain lediglich die Bean-Konfiguration auf spring4.xml, dann läuft alles wie zuvor – mit derselben Ausgabe.

Jetzt 200 € Guthaben sichern

Testen Sie Ihr Setup auf ccloud³

Registrieren Sie sich in der ccloud³ und erhalten Sie 200 € Startguthaben für Ihr Projekt – z. B. für eine PostgreSQL-VM mit automatischen Backups.

centron Redaktion Technische Redaktion

Das Redaktionsteam von centron schreibt Anleitungen aus dem Betriebsalltag: getestet auf unserer eigenen Plattform, betrieben im Rechenzentrum in Hallstadt bei Bamberg.

Kategorie JavaScript
Teilen
Noch offene Fragen?

Unser Team hilft Ihnen bei Ihrem konkreten Setup weiter – von Menschen, die die Plattform selbst betreiben.

War dieses Tutorial hilfreich?

Ihre Antwort wird anonym gespeichert und hilft uns, die Tutorials zu verbessern.

Kommentare

Noch keine Kommentare – stellen Sie die erste Frage zu diesem Tutorial.

Zum Kommentieren anmelden

Kommentare stehen centron-Kunden offen. Melden Sie sich in Ihrem Konto an, um eine Frage zu diesem Tutorial zu stellen.

Jetzt kostenlos anfangen

Melden Sie sich an und erhalten Sie in den ersten 60 Tagen ein Guthaben von 200 € bei centron.

Dieses Werbeangebot gilt nur für neue Konten. Angebot ausschließlich für Gewerbetreibende.