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

Hibernate spring注释会话未关闭/刷新,hibernate,spring,session,annotations,Hibernate,Spring,Session,Annotations,我“继承”了一个项目,该项目使用Spring注释通过Hibernate管理事务/会话。或者至少是命中注定的。目前,Hibernate会话从不刷新(它们被设置为刷新模式),DAO需要手动刷新才能将任何数据写入数据库 此外,所有DTO对象都驻留在hibernate的内存中,最终导致OutOfMemory错误 我认为我需要告诉Spring/Hibernate关闭会话或提交事务。在我的控制器类中,我有用于处理请求的带注释的方法: @Transactional(propagation = Propagat

我“继承”了一个项目,该项目使用Spring注释通过Hibernate管理事务/会话。或者至少是命中注定的。目前,Hibernate会话从不刷新(它们被设置为刷新模式),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" />
要使Spring/hibernate自动刷新DAO和/或关闭会话以防止hibernate使用大量内存,需要做些什么

干杯 丹


net/company/projectname/domain/ExchangeRate.hbm.xml
org.hibernate.dialogue.mysqlinnodbdialogue
org.hibernate.cache.NoCacheProvider
敞篷车
如果事务(带注释)成功,则会自动调用
事务。提交()
,将内容写入数据库,请检查是否正在调用事务,并且没有引发异常


还要确保将sessionfactory链接到声明的Transaction。

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

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

Spring将事务管理实现为方面,方面是 使用代理实现。其局限性在于,如果一个对象 对自身调用一个方法(这是因为 继承)则代理看不到调用(因为它发生了 在类内部(如调用私有方法),并且不能 那就什么都可以了


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

使用hibernate模板解决了这一问题

@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
       hibernateTemplate = new HibernateTemplate(sessionFactory);
}
然后使用此链接中的模板


共享您的回复将非常好

有另一种方法代替hibernate模板(hibernate模板将spring与hibernate耦合,这就是为什么它在spring 3.1中被弃用的原因) 解决这个问题的关键是删除除dialct和url之外的所有hibernate配置 简单地说,从hibernate属性中删除事务性内容 因为您希望spring管理事务,而不是hibernate。 正如Marten Deinum在这个url中提到的那样 下面是我的SpringXML配置文件的一个片段

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="configLocation">    
        <value>
            classpath:/com/spring/hibernate.cfg.xml
        </value>
    </property>       
    </bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
还有这个

BloodType b = new BloodType();
b.setId(new Long(1));
BloodType b1 = (BloodType)session.get(BloodType.class, 12L);
session.delete(b1);
session.save(b);
无需使用
session.flush()
transaction.commit()

希望它能工作

顺便说一句,我已经尝试将true添加到配置文件中。虽然它现在说已启用自动刷新和会话关闭,但在没有手动刷新DAO的情况下,仍然没有数据写入DB。没有例外,但我在日志中看不到任何有关提交事务的信息。关于会话,我唯一能看到的是:INFO[http-8080-1]sessionfactorympl-构建会话工厂INFO[http-8080-1]SessionFactoryObjectFactory-未将工厂绑定到JNDI,未配置JNDI名称-尝试在调试模式下运行应用程序以查看是否获得任何提交事务条目。我什么也得不到…添加logger.INFO(“Is transaction active”+TransactionSynchronizationManager.isActualTransactionActive());到请求方法的开头显示没有事务处于活动状态。这意味着事务AOP建议尚未启动。请尝试使用xml进行配置(这是我擅长的)``完成了,那-似乎什么也没做。调试[http-8080-6]名称匹配TransactionaAttributeSource-添加属性为[PROPAGATION\u REQUIRED,ISOLATION\u DEFAULT]的事务方法[*]嗨,阿里,不幸的是,我再也无法访问要测试的代码,但我不相信你的建议真的解决了问题。嗨,阿里,不幸的是,我再也无法访问要测试的代码,但我不相信你的建议真的解决了实际问题。我需要事务在定义它们的地方工作(即围绕句柄请求功能)。将事务移动到DAO内将完全改变回滚行为。嗨,阿里,问题是Spring没有拾取@Transactional注释,因为定义它的函数是从同一个类调用的,所以Spring无法代理函数调用。您最终是如何解决的?通过删除e
@Transactional
注释?我将带有@Transactional注释的方法移到了另一个类中。因为它现在在另一个类中,所以Spring代理任何类的方式也起作用。当它与调用它的代码在同一个类中时,代理类被忽略,因为它们在ca内部不起作用填充的方法。呃,如果这没有意义,我可能需要画一个图表来解释。这种情况是否也适用于接口,还是只涉及从超级激光继承的方法?@haki只有在“this”上调用该方法时才应该如此。
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="configLocation">    
        <value>
            classpath:/com/spring/hibernate.cfg.xml
        </value>
    </property>       
    </bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<session-factory> 
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>

<mapping resource="com/spring/BloodType.hbm.xml" />
</session-factory>
Session session = sessionFactory.getCurrentSession();
BloodType b = new BloodType();
b.setId(new Long(1));
BloodType b1 = (BloodType)session.get(BloodType.class, 12L);
session.delete(b1);
session.save(b);