简体   繁体   中英

Unable to make container managed transaction work in ejb 3

I am trying to learn the transactions. So I have developed a small application in ejb 3.1 and hibernate 5.2 .Now I have a scenario like below

 @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>

Below is the stacktrace of exception that I get when I try to run the application.

 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 says clearly that there is no active transaction during save operation. But then why ? since I expect EJB to start a transaction by itself. Is there anything that I missed.

try bellow code :-

 Session session=getSessionFactory().getCurrentSession();
 Transaction trans=session.beginTransaction();
 session.save(entity);
 trans.commit();

also use @Transactional(propagation = Propagation.REQUIRED) annotation

Blockquote

Why don't you use JPA? define persistence.xml, inject an EntityManager using @PersistenceContext ... that should give you something which works inside the Container Transaction. A simple war with different testcases could help see: war examplebean the bean is used to compare an ejb-like environment, to a wildfly running with arquillian. So therefore there are different transactional situation together with one primitive Entity simulated.

if you need to use the hibernate API because of legacy code to be ported in a stable way and with minimal effort: using unwrap you can access the session underlying the entityManager. Db-Operation done using this Object should be handled in context of the current transaction. You should probably not use the hibernates session in different thread and transaction contextes but fetch it always immediately before the legacy code is running. But that is to be checked.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM