无法使容器管理的事务在ejb 3中工作

时间:2017-07-10 17:41:00

标签: java hibernate transactions

我正在尝试学习交易。所以我在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能够自己启动一个事务。 有什么我想念的。

2 个答案:

答案 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会话,而是在遗留代码运行之前立即获取它。但是要检查。