You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring 5与Hibernate 5应用中整合Spring JPA并配置相关组件

Hey there! Let's walk through how to set up Spring JPA and Hibernate 5 side by side in your Spring 5 application, covering transaction managers, entity managers, Hibernate Sessions, and how to use all of this in your code—all configured via applicationContext.xml.

1. First: Set Up Your Data Source

You can't do much without a database connection. Let's configure a basic data source (I'll use Apache Commons DBCP here, but you can swap in HikariCP or another implementation if preferred):

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/your_db?useSSL=false&serverTimezone=UTC"/>
    <property name="username" value="db_user"/>
    <property name="password" value="db_password"/>
    <property name="initialSize" value="5"/>
    <property name="maxTotal" value="20"/>
</bean>

2. Configure the EntityManagerFactory (Spring JPA's Core)

Spring JPA relies on EntityManagerFactory to manage entity managers, and since Hibernate is our JPA provider, we'll use LocalContainerEntityManagerFactoryBean to wire everything up. This bean automatically creates a Hibernate SessionFactory under the hood, so you get both JPA and Hibernate support in one setup:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <!-- Wire up our data source -->
    <property name="dataSource" ref="dataSource"/>
    
    <!-- Tell Spring where to scan for your JPA entity classes -->
    <property name="packagesToScan" value="com.yourpackage.entities"/>
    
    <!-- Specify Hibernate as the JPA vendor -->
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
    </property>
    
    <!-- Add Hibernate-specific configuration properties -->
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.format_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop> <!-- Adjust to create/create-drop/validate as needed -->
        </props>
    </property>
</bean>

3. Transaction Managers: JPA + Hibernate

Here's a key insight: JpaTransactionManager works seamlessly with Hibernate because Hibernate is a JPA implementation. This manager handles transactions for both JPA EntityManager and Hibernate Session operations. If you have legacy code that relies on a dedicated Hibernate transaction manager, you can configure both—though the JPA manager is sufficient for most modern use cases.

This is the default setup you'll want for most applications:

<!-- JPA Transaction Manager -->
<bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<!-- Enable annotation-driven transaction management -->
<tx:annotation-driven transaction-manager="jpaTransactionManager"/>

Option 2: Add Hibernate Transaction Manager (If Needed)

If you have code that uses Hibernate's native API exclusively, add this alongside the JPA manager:

<!-- Hibernate Transaction Manager -->
<bean id="hibernateTransactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    <property name="sessionFactory" value="#{entityManagerFactory.unwrap(org.hibernate.SessionFactory.class)}"/>
</bean>

When using this, specify the manager in your @Transactional annotation like: @Transactional("hibernateTransactionManager").

4. Expose Hibernate SessionFactory & Session

If you want to use Hibernate's Session directly (instead of JPA's EntityManager), you can expose the auto-created SessionFactory as a bean, or even a thread-bound Session:

<!-- Expose Hibernate SessionFactory (extracted from EntityManagerFactory) -->
<bean id="sessionFactory" factory-bean="entityManagerFactory" factory-method="unwrap">
    <constructor-arg value="org.hibernate.SessionFactory"/>
</bean>

<!-- Optional: Expose a thread-bound current Hibernate Session -->
<bean id="currentSession" factory-bean="sessionFactory" factory-method="getCurrentSession"/>

5. Using These Beans in Your Application

Injecting EntityManager (Spring JPA)

Use @PersistenceContext to inject the JPA EntityManager into your DAOs or services:

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;

@Repository
public class UserDao {
    @PersistenceContext
    private EntityManager entityManager;
    
    public User findById(Long id) {
        return entityManager.find(User.class, id);
    }
    
    public void saveUser(User user) {
        entityManager.persist(user);
    }
}

Using Hibernate Session

Inject the SessionFactory to get the current thread-bound session, or inject the currentSession bean directly:

import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class UserHibernateDao {
    @Autowired
    private Session currentSession;
    
    public User findById(Long id) {
        return currentSession.get(User.class, id);
    }
    
    // Alternatively, inject SessionFactory:
    // @Autowired
    // private SessionFactory sessionFactory;
    // public User findById(Long id) {
    //     return sessionFactory.getCurrentSession().get(User.class, id);
    // }
}

Managing Transactions

Add the @Transactional annotation to your service methods to handle transactions automatically. It uses the default manager we configured, or specify a custom one if needed:

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserService {
    @Autowired
    private UserDao userDao;
    
    @Transactional // Uses jpaTransactionManager by default
    public User createUser(User user) {
        userDao.saveUser(user);
        return user;
    }
    
    // If using the Hibernate transaction manager:
    // @Transactional("hibernateTransactionManager")
    // public User updateUser(User user) {
    //     currentSession.merge(user);
    //     return user;
    // }
}

Full Example of applicationContext.xml

Putting it all together, here's a complete configuration snippet:

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

    <!-- Scan for @Service, @Repository, etc. -->
    <context:component-scan base-package="com.yourpackage"/>

    <!-- Data Source -->
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/your_db?useSSL=false&serverTimezone=UTC"/>
        <property name="username" value="db_user"/>
        <property name="password" value="db_password"/>
    </bean>

    <!-- EntityManagerFactory -->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="packagesToScan" value="com.yourpackage.entities"/>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
        </property>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>

    <!-- JPA Transaction Manager -->
    <bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <!-- Optional: Hibernate Transaction Manager -->
    <bean id="hibernateTransactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" value="#{entityManagerFactory.unwrap(org.hibernate.SessionFactory.class)}"/>
    </bean>

    <!-- Expose Hibernate SessionFactory -->
    <bean id="sessionFactory" factory-bean="entityManagerFactory" factory-method="unwrap">
        <constructor-arg value="org.hibernate.SessionFactory"/>
    </bean>

    <!-- Enable Annotation-Driven Transactions -->
    <tx:annotation-driven transaction-manager="jpaTransactionManager"/>

</beans>

内容的提问来源于stack exchange,提问作者Kingamere

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:24:19