当前位置: 首页 > 面试题库 >

Hibernate Spring注释会话未关闭/刷新

闾丘德宇
2023-03-14
问题内容

我已经“继承”了一个项目,该项目使用Spring批注来管理Hibernate的事务/会话。或至少是注定的。当前,Hibernate会话永远不会被刷新(它们设置为FLUSH_MODE_NEVER),并且DAO需要手动刷新才能将任何数据写入数据库。

同样,所有DTO对象都驻留在hibernate的内存中,最终导致OutOfMemory错误。

我相信我需要告诉Spring / Hibernate关闭会话或提交事务。在我的控制器类中,我具有带注释的方法来处理请求:

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
    ...
    ...
}

我相信我在applicationContetxt.xml文件中设置了hibernate事务管理器,并告诉spring使用注释:

<!-- hibernate3 transaction manager -->
<bean id="transactionManagerLocal" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="dataSource" ref="${local.data.source}" />
    <property name="sessionFactory" ref="localSessionFactory" />
</bean>

<!-- Demarcate using @Transactional annotation -->
<tx:annotation-driven transaction-manager="transactionManagerLocal" order="200" />

我不仅可以确定配置是否错误,而且在没有手动调用每个DAO上的flush的情况下不会将数据写入数据库,从日志文件中我们还可以看到事务管理器已禁用了flushing和关闭会话关闭:

INFO  [http-8080-2] TransactionFactoryFactory - Transaction strategy: org.springframework.orm.hibernate3.SpringTransactionFactory
INFO  [http-8080-2] TransactionManagerLookupFactory - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
INFO  [http-8080-2] SettingsFactory - Automatic flush during beforeCompletion(): disabled
INFO  [http-8080-2] SettingsFactory - Automatic session close at end of transaction: disabled

要使Spring / hibernate自动刷新DAO和/或关闭会话以防止Hibernate使用大量内存,需要做些什么?

欢呼丹

<!-- MySQL/InnoDB session factory -->
<bean id="localSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="${local.data.source}"/>
    <property name="mappingResources">
        <list>
            <value>net/company/projectname/domain/ExchangeRate.hbm.xml</value>
            <!-- Other  -->

        </list>
    </property>

   <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
            <prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
            <prop key="hibernate.connection.zeroDateTimeBehavior">convertToNull</prop>
            <!-- 
            DOES NOTHING
            <prop key="hibernate.transaction.flush_before_completion">true</prop>
            <prop key="hibernate.transaction.auto_close_session">true</prop>
            -->
        </props>
    </property>
</bean>

<!-- hibernate3 transaction manager -->
<bean id="transactionManagerLocal" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="dataSource" ref="${local.data.source}" />
    <property name="sessionFactory" ref="localSessionFactory" />
</bean>


<!-- Demarcate using @Transactional annotation -->
<tx:annotation-driven transaction-manager="transactionManagerLocal" order="200" />

<bean id="exchangeRateDAO" class="net.company.project.dao.hibernate.impl.ExchangeRateDAOImpl">
     <property name="sessionFactory" ref="localSessionFactory"/>
 </bean>

问题答案:

我的一位聪明的同事发现了问题所在。

实际的问题是,您声明为@Transactional的方法是从基类调用的继承方法,这意味着Spring无法截获对该方法的调用并将其包装在事务中。

Spring将事务管理作为方面来实现,而方面则通过代理来实现。这样做的局限性在于,如果一个对象本身调用了一个方法(由于继承而在这里发生了这种情况),则代理看不到该调用(因为它发生在类内部,就像调用私有方法一样),并且对此无能为力。

这是有道理的,但似乎非常危险,因为它无法在没有任何错误消息或警告的情况下写入任何数据。



 类似资料:
  • 问题内容: 当我按如下方式调用session.begin事务方法时: 然后我得到以下异常消息 造成此错误的原因是什么? 问题答案: 更新: 我想调用并不能保证该会话实际上是打开的。第一次,您应该使用 代替。该建议实际上与您找到的页面一致。 之前: 根据到目前为止的可用信息,我们可以得出结论,错误的原因是会话未打开;-)

  • 问题内容: 遵循我们在如何在MySQL中关闭sqlalchemy连接中的注释之后,我正在检查SQLAlchemy创建到数据库中的连接,如果不退出Python,我将无法关闭它们。 如果我在python控制台中运行此代码,它将保持会话打开状态,直到我退出python为止: 我发现要关闭它的唯一解决方法是在最后调用。 根据我上面给出的链接中的评论,我的问题现在是: 为什么需要关闭会议? 还不够吗 问题答

  • 我有两个运行在不同机器上的ActiveMQ Artemis代理,组成一个简单的集群。我正在使用一个Java应用程序(非常基本)来生成和使用消息,以分析集群的行为。Java代码如下所示: 同时在处使用断点调试上述应用程序。如果我停止我的主代理,那么我会看到从代理接管,所有的消息都像预期的那样被移动到从代理。但是,此时,如果我继续使用我的应用程序,它将抛出,而不是在从代理中使用消息。当我再次启动主代理

  • 问题内容: 我最近开始在应用程序中使用hibernate和c3p0作为ORM。但是,当我关闭会话工厂时,连接池不会自行关闭!这是我的应用程序中 唯一 可以进行会话操作的地方。 这是我的配置文件 请注意,空闲连接非常短的原因是它是我尚未通过集成测试的唯一方法。他们经常打开和关闭会话工厂,因此我总是用尽所有连接。正如我们在项目开始时一样,从长远来看,我认为这不是一个非常可持续的策略。 需要注意的“有趣

  • 问题内容: 下面的函数是我在Web应用程序中具有的按钮的actionListener,我正在从数据库中的表中删除旧选择的行,并将新行插入数据库中。 我一直在例外:会话关闭!有人可以解释一下如何在hibernate状态下关闭会话(自动吗?)以及如何使用它们。 这是该异常的详细堆栈跟踪: 谢谢, 问题答案: 在Hibernate会话显然配置为基于请求的情况下,您在会话范围内的受管Bean中使用了延迟获

  • 编辑问题以包括所需的行为、特定问题或错误以及重现问题所需的最短代码。这将有助于其他人回答这个问题。 这样的问题。当添加注释@ spring boot application(exclude = { securityautoconfiguration . class })时,生成名称时出现错误,IDE会这样写:在此输入图像描述 会有什么问题呢?