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

spring4, hibernate4 整合问题

2016-07-07 12:03 429 查看
在整合spring和hibernate中,出现了以下错误:

org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current
在Dao层程序中获取session是这样的:

@Repository
public class BookShopDaoImpl implements BookShopDao {

@Autowired
private SessionFactory sessionFactory;

public Session getSession(){
return sessionFactory.getCurrentSession();
}
不确定是问题是出在自动装配还是获取session上,加了如下测试代码:

public Session getSession(){
System.out.println("Now, it is in getSession");
if(sessionFactory==null){
System.out.println("Session is null!");
return null;
}
System.out.println("Session is not null!");
return sessionFactory.getCurrentSession();
}
发现打印输出了
Session is not null!
定位问题在getCurrentSession()处。查找了一下原因,按照:

http://www.oschina.net/question/273712_221495?fromerr=WjHJ9XZn

提供的思路,在Dao层也添加了事务,发现能够成功运行,具体修改如下图:


e

而按照添加:<property name="hibernate.current_session_context_class">thread</property> 尝试发现并没有解决问题。

但是具体原因是什么,没有找到解释。。有待后面熟悉后再来反思。

2016-07-08日更新:

对于昨天写的以上内容,经过尝试和查资料,算是有了一个清楚的认识。

具体如下:

1、之所以在测试的出现:

org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current
是因为在测试代码中,是直接操作Dao层进行测试的,代码如下:

@Test
public void TestFindBookPriceByIsbn() {
System.out.println("test start!");
System.out.println(bookShopDao);
System.out.println(bookShopService);
int price = bookShopDao.findBookPriceByIsbn(1001);
System.out.println(price);
}
前面三个打印输出语句是在调试中,查看Dao和Service是否注入成功写的。然后直接使用Dao层的代码获取价格,而一开始的代码,在Dao层并没有使用事务,配置代码时如下:

<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true" />
<tx:method name="*" />
</tx:attributes>
</tx:advice>

<aop:config>
<aop:pointcut id="txPointcut"
expression="execution(* com.yefeng.service.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />
</aop:config>
因此直接调用Dao层时,是没有使用事务的,因此,在前面的尝试中,在Dao层也加了事务后,测试代码成功。

2、一般只在Service层加事务,是因为service的操作可能会涉及多个Dao操作,因为需要加上事务防止有的Dao操作不成功进行回滚。而Dao层操作大多是一个单独的数据库操作,因此没必要使用。

因此,我尝试去掉了Dao层的事务,直接测试Service,test代码和Service实现如下:

@Test
public void bookShopSevrviceTest(){
bookShopService.purchase("aa", 1001);
}
@Repository
public class BookShopServiceImpl implements BookShopService {

<span style="white-space:pre">	</span>private BookShopDao bookShopDao;
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>@Override
<span style="white-space:pre">	</span>public void purchase(String username, int isbn) {
<span style="white-space:pre">		</span>// TODO Auto-generated method stub
<span style="white-space:pre">		</span>int price = bookShopDao.findBookPriceByIsbn(isbn);
<span style="white-space:pre">		</span>bookShopDao.updateBookStock(isbn);
<span style="white-space:pre">		</span>bookShopDao.updateUserAccount(username, price);
<span style="white-space:pre">	</span>}
}
发现此时出现的是java.lang.NullPointerException。空指针异常,一开始的时候,我是先测试的Service层,发现出错了,才写了Dao层测试代码。而测试Dao层没有事务,因此出现题目中的错误。

但Service层的错误是因为,忘记添加@autowired注解导致的。

总结:

1、属性之间相互依赖时,@Autowire注解不能忘。

2、使用getCurrentSession()一定要在事务中执行。一般事务是加在Service层,因此单独测试Dao层时,会出现,Could not obtain transaction-synchronized Session for current 错误,此时可以先在Dao层添加事务进行测试,或者改成OpenSession(),在测试完Dao层时将Dao层的事务取消或者将OpenSession()改为getCurrentSession()。

3、<property name="hibernate.current_session_context_class">thread</property>是不需要添加的,因为此时Context上下文已经绑定到SpringSessionContext中。具体细节参考:

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