使用spring的hibernate的正确方法是什么?

时间:2013-01-16 20:30:55

标签: spring hibernate integration

我最近开始使用hibernate和spring。

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

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

我认为这是非常可靠的,直到一位同事告诉我这种方式已被弃用,我不应该使用HibernateDAOSupport类。但是在我的dao实现类中使用SessionFactory实例,在新的单独服务类中使用该类的实例。由于这似乎是一个很好的方法,我决定遵循这条道路。

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

我也听过关于实体经理的讨论,那是什么?

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

2 个答案:

答案 0 :(得分:5)

这是将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并使用事务包装所有代码。 / p>

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

答案 1 :(得分:4)

关于Spring中的Hibernate,和2013年一样,HibernateDaoSupport已被弃用(以及HibernateTemplate)。它不适用于Hibernate 4.0。

我认为使用带有sessionFactory.getCurrentSession()的{​​{3}}注释类用于Hibernate特定和@PersistenceContext带注释的EntityManager属性来自动装配JPA配置的持久性上下文是当前的默认选择。

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

StackOveflow上有很多类似的问题prior to JPA 2.0 1 2等等。

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