【问题标题】:Manually open a hibernate session with Spring config使用 Spring 配置手动打开休眠会话
【发布时间】:2014-08-02 00:07:55
【问题描述】:

我遇到的问题是我使用 Spring 为我的 Web 应用程序管理和加载休眠。我目前正在使用 OpenSessionInViewFilter。这在我查看应用程序时按预期工作,但当我尝试从非视图相关活动(例如 Quartz 任务或我创建以帮助完成某些任务的一些 Runnable 线程)访问休眠时,效果就不那么好了。这会导致延迟初始化异常并且没有会话可用异常发生。

这是我目前使用 Spring 管理 Hibernate 的方式

<bean id="mainDataSource" 
    class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

    [..DB config..]
</bean>

<bean id="sessionFactory" 
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

    <property name="dataSource">
        <ref bean="mainDataSource"/>
    </property>
</bean>

<bean id="txManager" 
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">

    <property name="sessionFactory"><ref local="sessionFactory"/></property>
    <property name="dataSource"><ref local="mainDataSource"/></property>
</bean>

然后我配置扩展 HibernateDaoSupport 的 DAO 对象并将它们注入到服务类中

<bean id="myDAO"
    class="package.myDAO">
    <property name="sessionFactory">
        <ref bean="sessionFactory" />
    </property>
</bean>

<bean id="mySvcTarget" class="package.myService">
    <property name="myDAO"><ref bean="myDAO"/></property>
</bean> 

<bean id="myService" 
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager">
        <ref bean="txManager"/>
    </property>

    <property name="target">
        <ref bean="mySvcTarget"/>
    </property>

    <property name="transactionAttributes">
        <props>
            <prop key="*">PROPAGATION_REQUIRED</prop>
        </props>
    </property>
</bean>

然后在我的应用程序中,myService 被注入到我的控制器类中,因此我使用它来访问我的 DAO。对于我的情况,尽管看起来我需要以其他方式访问我的 DAO(或服务最好)并手动打开和关闭我的休眠会话,因为我的服务类似乎只在查看会话期间打开。我不确定最好的方法来做到这一点。所有的休眠配置都已经在 Spring 中,所以我假设它只是一个问题或以某种方式调用它们。

【问题讨论】:

    标签: java spring hibernate hibernate-session


    【解决方案1】:

    首先,您正在使用的所有附加服务(非视图)应该对 Spring 可见。最简单的方法是使用@Service 注解。为了让它工作,你可以在你的配置中添加&lt;context:component-scan base-package="your.package"&gt;

    在此之后,如果 Spring 将您的服务视为 bean,则使用 @Transactional 注释在其中包含 Hibernate 会话就足够了。

    【讨论】:

    • 申请@Transactional 完全可以。不需要在服务的 CRUD 方法中调用 Session session=sessionFactory.openSession(); 吗?正如@Raymond 想要“手动打开和关闭休眠会话”
    • ..那么 filter 在 web.xml 中为 org.springframework.orm.hibernate.support.OpenSessionInViewFilter 写的呢,它保持不变,不需要删除这个过滤器。
    • @Amogh 澄清一下,我说我说我想手动打开和关闭会话的唯一原因是因为我认为这是完成我需要的唯一方法。如果我不必这样做,我也不想这样做。
    • @sap1ens 不幸的是,这不起作用。我按照你的建议做了,但仍然得到懒惰的初始化错误。为了安全起见,我将事务注释放在我调用的每个方法上,并将我使用的类标记为事务但仍然没有运气
    猜你喜欢
    • 1970-01-01
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 2013-12-19
    • 2013-02-18
    • 2014-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多