【问题标题】:What's the correct way to use hibernate with spring用spring使用hibernate的正确方法是什么
【发布时间】:2012-12-31 07:03:44
【问题描述】:

我最近开始使用 hibernate 和 spring。

一开始我被告知要使用 sessionFactory 和 openSession 以及 beginTransaction 来进行数据库调用。

后来我听说了 dao,所以我开始使用它,方法是创建一个接口,在一个类中实现这个接口,然后让这个类扩展 HibernateDAOSupport。

我认为这是相当可靠的,直到一位同事告诉我这种方式已被弃用并且我不应该使用 HibernateDAOSupport 类。而是在我的 dao 实现类中使用 SessionFactory 实例,并在新的单独服务类中使用该类的实例。由于这似乎也是一个不错的方法,所以我决定走这条路。

刚刚我读到这个方法也被新版本的spring弃用了...... 所以我的问题是:究竟什么是将hibernate和spring结合在一起的正确最新方法??

我还听说过关于实体管理器的讨论,那是关于什么的?

我正在寻找使用它们的一般方法,如果一般规则有任何例外,请同时提供这些例外的示例。

【问题讨论】:

    标签: spring hibernate integration


    【解决方案1】:

    这是将 Hibernate 集成到 Spring 中的众多方法之一...

    您的服务(或 DAO)类应该看起来像这样简单:-

    // annotate this class so that Spring is aware of it 
    @Service
    public class EmployeeServiceImpl implements EmployeeService {
    
        @Autowired
        private SessionFactory sessionFactory;
    
        // this is straight-up HQL... really, no magic here
        @Override
        @SuppressWarnings("unchecked")
        public Collection<Employee> getAllEmployees() {
            return sessionFactory.getCurrentSession()
                    .createQuery("from Employee e order by e.lastName, e.firstName")
                    .list();
        }
    }
    

    现在,你需要配置sessionFactory,否则自动装配会失败。所以,这就是你的配置方式:-

    <?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:aop="http://www.springframework.org/schema/aop"
            xmlns:tx="http://www.springframework.org/schema/tx"
            xmlns:jee="http://www.springframework.org/schema/jee"
            xsi:schemaLocation="
                http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
                http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd">
    
        <!-- 
            When creating the session factory, point it to your existing hibernate.cfg.xml.
            You can also port your entire Hibernate configuration and HBM mappings here, but
            for simplicity sake, I'll reference the existing hibernate.cfg.xml here so that we 
            are not cluttering Spring configuration file with Hibernate-specific configuration.
        -->
        <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            <property name="configLocation" value="classpath:hibernate.cfg.xml"/>
        </bean>
    
        <!-- If you are running in production, you will want to use JNDI connection -->
        <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/myapp"/>
    
        <!-- If you are running testcases, you might want to use JDBC instead -->
        <!--
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
            <property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver"/>
            <property name="url" value="jdbc:jtds:sqlserver://machine/myapp"/>
            <property name="username" value="myapp"/>
            <property name="password" value="myapp"/>
        </bean>
        -->
    
        <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory"/>
        </bean>
    
        <tx:advice id="txAdvice">
            <tx:attributes>
                <tx:method name="*" propagation="REQUIRED"/>
            </tx:attributes>
        </tx:advice>
    
        <aop:config proxy-target-class="true">
            <aop:advisor pointcut="execution(* com.myapp..*.*(..))" advice-ref="txAdvice"/>
        </aop:config>
    
    </beans>
    

    有两种配置事务的方法:1) 使用@Transactional,您可以注释哪些类(或特定方法)需要正确的事务处理,以及 2) 使用 AOP 并用事务包装所有代码。

    在上面的示例中,我将所有代码都用基本包com.myapp 与事务包装在一起。您可以更改(或添加)切入点以减少事务包装器。

    【讨论】:

    • 感谢您的详细回答,但有一个问题:您会直接使用带有 sessionFactory 的服务,而不是使用具有带有 sessionFactory 的 DOA 的服务吗?这样做有什么理由吗?
    • 这取决于你。我将会话工厂放在我的服务中以简化我的示例。
    【解决方案2】:

    关于 Spring 中的 Hibernate,至于 2013 年,不推荐使用 HibernateDaoSupport(以及 HibernateTemplate)。它在 Hibernate 4.0 中不起作用。

    我认为当前的默认选择是使用带有 sessionFactory.getCurrentSession()@Transactional 注释类和 @PersistenceContext 注释 EntityManager 属性来自动连接 JPA 配置的持久性上下文。

    JPA 是一个标准,而 Hibernate 不是,但是大多数 Hibernate 特定的东西都可以在 JPA 配置中工作(当然这意味着您将不再遵守标准,并且切换到另一个 JPA 实现会更加困难),只有少数仅在纯 Hibernate 中可用,例如,您无法从会话 prior to JPA 2.0 中分离独立对象。在专有框架中实现一些新功能比更改标准更简单,但我相信 JPA 2.0 适合大多数情况。

    StackOveflow上有很多类似的问题123等等。

    使用 JPA 配置的一个很好的理由是它可以与 Spring Data JPA 一起使用 - 一个简化实现存储库的框架(您只需要声明接口,而不是在接口和基于通用存储库的类之间保持并行层次结构)。

    【讨论】:

      猜你喜欢
      • 2018-02-15
      • 2017-09-25
      • 2020-03-31
      • 1970-01-01
      • 1970-01-01
      • 2012-02-18
      • 1970-01-01
      • 2021-11-24
      • 2021-09-23
      相关资源
      最近更新 更多