我正在尝试学习交易。所以我在ejb 3.1和hibernate 5.2中开发了一个小应用程序。现在我有一个类似下面的场景
@Stateles
@TransactionManagement(TransactionManagementType.CONTAINER)
public class MyEJb implements ejbxyz {
@Resource
SessionContext sessionContext;
@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void method(){
Dao dao=new Dao() //Dao class is simple java class
try{
dao.fooMethod();
}catch(DaoException e){
sessionContext.setRollbackOnly();
}
try{
dao.barMethod(); // this method updates some other record
}catch(DaoException e){
sessionContext.setRollbackOnly();
}
}
}
public class Dao{
void fooMethod(){
try{
Session session=sessFactory.getCurrentSession();
....
session.save(x);
}catch(Exception e){
throw new DaoException();
}
}
void barMethod(){
try{
Session session=sessFactory.getCurrentSession();
session.getNamedQuery("xyz").executeUpdate();
}catch(HibernateException ex){
throw new DaoException();
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.datasource">java:/XYZDB</property>
<property name="show_sql">true</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hbm2ddl.auto">update</property>
</session-factory>
</hibernate-configuration>
下面是我尝试运行应用程序时遇到的异常堆栈跟踪。
org.hibernate.HibernateException: save is not valid without active transaction
- at com.ebs.service.implementation.OnlineBankingServiceImpl.fundTransfer(OnlineBankingServiceImpl.java:27)
- at com.ebs.presentation.action.TransferFundAction.create(TransferFundAction.java:127)
- at com.ebs.presentation.action.TransferFundAction$$FastClassBySpringCGLIB$$bd64a4af.invoke(<generated>)
- at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
- at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720)
- at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
- at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:69)
- at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
- at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
- at com.ebs.presentation.action.TransferFundAction$$EnhancerBySpringCGLIB$$7fb221bd.create(<generated>)
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
- at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
- at java.lang.reflect.Method.invoke(Method.java:498)
Exception明确表示在保存操作期间没有活动事务。但那么为什么呢?因为我希望EJB能够自己启动一个事务。 有什么我想念的。
答案 0 :(得分:0)
尝试下面的代码: -
Session session=getSessionFactory().getCurrentSession();
Transaction trans=session.beginTransaction();
session.save(entity);
trans.commit();
也使用@Transactional(propagation = Propagation.REQUIRED)
注释
答案 1 :(得分:0)
块引用
为什么不使用JPA?定义persistence.xml,使用@PersistenceContext注入一个EntityManager ...它应该给你一些在Container Transaction中工作的东西。使用不同测试用例的简单战争可以帮助看到:war examplebean该bean用于比较类似ejb的环境,以及使用arquillian运行的野生蝇。因此,存在不同的事务情况以及一个模拟的原始实体。
如果您需要使用hibernate API,因为遗留代码可以以稳定的方式移植并且只需很少的工作量:使用unwrap可以访问entityManager下的会话。使用此Object完成的Db操作应在当前事务的上下文中处理。您可能不应该在不同的线程和事务上下文中使用hibernates会话,而是在遗留代码运行之前立即获取它。但是要检查。