您的位置:首页 > 编程语言 > Java开发

spring2.5与hibernate3升级后的bug

2015-09-30 19:42 597 查看
手头有一个项目,使用的是struts2 hibernate3 spring2.5

是之前的老项目了,spring与hibernate的版本都比较低

自己看了最新的spring4与hibernate4,发现hibernateDaoSupport与hibernatetemplate已经不建议使用了。

那么换句话说,事务管理就得自己来整了

直接更新jar包,呵呵,大家试试更新一下自己项目里的老jar包,你就知道有多么蛋疼了。

所以我试着不更新hibernate与spring jar的基础上,使用它们推荐的编码方式。

hibernate的配置

1

使用下面的配置,即不给hibernate.current_session_context_class设值

<prop key="hibernate.hbm2ddl.auto">update</prop>

<prop key="hibernate.show_sql">false</prop>

<prop key="hibernate.format_sql">true</prop>

<!--

<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate3.SpringSessionContext</prop>

-->

</props>

报下面的错误:

No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

另外如果使用声明式事务管理current_session_context_class就不需要设值了

关于这个current_session_context_class,更详细的资料,大家参见 http://blog.csdn.net/z69183787/article/details/8768421

2

给它赋值,如下:

<prop key="hibernate.current_session_context_class">thread</prop>

另外关于事务,我使用的是注解的方法

<bean id="txManager"

class="org.springframework.orm.hibernate3.HibernateTransactionManager">

<property name="sessionFactory" ref="sessionFactory"/>

</bean>

<tx:annotation-driven transaction-manager="txManager"/>

在action里面,方式头上加上 @Transactional

(另外,如果方法头没有加 @Transactional 也会报No Hibernate Session bound to thread....的错误)

代码如下,逻辑写的有点乱,而且也不应该在action里面获得Criteria。

大家先看技术层面的问题吧

@SuppressWarnings("unchecked")
@Transactional
public String checkUnCompletedFile(){
System.out.println("check");
//获取已经创建但是未完成的冠心病病人档案

Criteria c=commonService.createCriteria(CdmGXBFile.class);
c.add(Restrictions.eq("status", "0"));
c.add(Restrictions.eq("cdmUser", getSessionUser()));
unCompletedFileList=c.list();

}
commonService最终调用了dao类,dao里面包含sessionFactory,并且通过spring注入

public <T> Criteria createCriteria(Class<T> entityClass) {

Criteria criteria = getSession().createCriteria(entityClass);

return criteria;

}

public Session getSession() {

// 事务必须是开启的(Required),否则获取不到

return sessionFactory.getCurrentSession();

}

运行的时候会报下面的错误:

org.hibernate.HibernateException: createCriteria is not valid without active transaction

at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:338)

at com.sun.proxy.$Proxy44.createCriteria(Unknown Source)

at cdm.core.dao.allbase.GenericBaseCommonDao.createCriteria(GenericBaseCommonDao.java:425)

at cdm.core.service.CommonServiceImpl.createCriteria(CommonServiceImpl.java:271)

at cdm.module.file.gxb.action.BasicInfoAction.checkUnCompletedFile(BasicInfoAction.java:522)

at cdm.module.file.gxb.action.BasicInfoAction$$FastClassByCGLIB$$7f24d4a9.invoke(<generated>)

3

给current_session_context_class设值:

<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate3.SpringSessionContext</prop>

报下面的错误...

Could not execute action: /modules/file_gxb/createFile/checkUnCompletedFile

java.lang.NoSuchMethodException: com.sun.proxy.$Proxy43.checkUnCompletedFile()

我去NoSuchMethodException是个什么鬼?

(如果使用声明式事务管理就不会有这个错误)

怎么办?

在spring的配置文件里加上

<aop:config proxy-target-class="true">

</aop:config>

下面是它的解释

因为你对action配置了aop,并且你用的是默认的jdk动态代理。

jdk代理只能针对接口创建代理,他创建出来的对象只有你实现的接口里面的方法,也就没有你在action里面写的get或者insert之类的方法,运行起来自然会报NoSuchMethodError

加了<aop:config proxy-target-class="true">会使用cglib创建代理,他直接创建目标对象的子类对象,你在action写的那些方法被代理子类对象继承下来了,所以不会报NoSuchMethodException了

感谢panhaichun大神,具体资料见http://bbs.csdn.net/topics/380133183

那么我们就还有另一个办法,就是让我们的bean不要继承接口。

参考资料:

http://bbs.csdn.net/topics/380133183

http://blog.csdn.net/z69183787/article/details/8768421
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: