UserTransaction failed when call utx.begin() throws “java.lang.IllegalStateException: Operation not allowed”

天大地大妈咪最大 提交于 2019-12-25 05:04:16

问题


i want to use ejb and jpa controller, in netbeans the controller is generated automatically... I try to call the jpa controller from class (UniversidadServiceEJB) that is a session bean stateless, I debugged the project and the UserTransaction and EntityManagerFactory is created successfully but when call the method utx.begin in the jpa controller (UniversityJpaController) throws this exception:

java.lang.IllegalStateException: Operation not allowed.

at com.sun.enterprise.transaction.UserTransactionImpl.checkUserTransactionMethodAccess(UserTransactionImpl.java:146) at com.sun.enterprise.transaction.UserTransactionImpl.begin(UserTransactionImpl.java:162) at controller.UniversidadJpaController.create(UniversidadJpaController.java:47) at services.UniversidadServiceEJB.create(UniversidadServiceEJB.java:40) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052) at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124) at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5388) at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:619) at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800) at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571) at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:49) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861) at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800) at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571) at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162) at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ... ... ...

The Session Bean class is:

@Stateless(name="UniversidadJpa")
@Remote(IGestionUniversidad.class)
public class UniversidadServiceEJB {

    @Resource
    private UserTransaction utx;
    @PersistenceUnit(unitName="ApplicationEJBPU")
    EntityManagerFactory emf;


    public void create(Universidad universidad)  throws Exception {        
        try {
            UniversidadJpaController universidadController = new UniversidadJpaController(utx,emf);
            universidadController.create(universidad);
        } catch (RollbackFailureException ex) {
            Logger.getLogger(UniversidadServiceEJB.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(UniversidadServiceEJB.class.getName()).log(Level.SEVERE, null, ex);
        } 

    } 

}

And the jpacontroller class is:

public class UniversidadJpaController implements Serializable {

    public UniversidadJpaController(UserTransaction utx, EntityManagerFactory emf) {
        this.utx = utx;
        this.emf = emf;
    }
    private UserTransaction utx = null;
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Universidad universidad) throws RollbackFailureException, Exception {
        if (universidad.getEstudiantes() == null) {
            universidad.setEstudiantes(new ArrayList<Estudiante>());
        }
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            List<Estudiante> attachedEstudiantes = new ArrayList<Estudiante>();
            for (Estudiante estudiantesEstudianteToAttach : universidad.getEstudiantes()) {
                estudiantesEstudianteToAttach = em.getReference(estudiantesEstudianteToAttach.getClass(), estudiantesEstudianteToAttach.getId());
                attachedEstudiantes.add(estudiantesEstudianteToAttach);
            }
            universidad.setEstudiantes(attachedEstudiantes);
            em.persist(universidad);
            for (Estudiante estudiantesEstudiante : universidad.getEstudiantes()) {
                Universidad oldUniversidadOfEstudiantesEstudiante = estudiantesEstudiante.getUniversidad();
                estudiantesEstudiante.setUniversidad(universidad);
                estudiantesEstudiante = em.merge(estudiantesEstudiante);
                if (oldUniversidadOfEstudiantesEstudiante != null) {
                    oldUniversidadOfEstudiantesEstudiante.getEstudiantes().remove(estudiantesEstudiante);
                    oldUniversidadOfEstudiantesEstudiante = em.merge(oldUniversidadOfEstudiantesEstudiante);
                }
            }
            utx.commit();
        } catch (Exception ex) {
//            try {
//                utx.rollback();
//            } catch (Exception re) {
//                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
//            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }
}

And the Persistence Unit is:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="ApplicationEJBPU" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>sqlServer</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
      <property name="eclipselink.ddl-generation" value="create-tables"/>
    </properties>
  </persistence-unit>
</persistence>

Please what is the problem?.. Thank you very much...


回答1:


Usually in an EJB Environment, the transaction is managed by the the container. It wraps the Bean methods in transactions with automatic rollback when an exception occurs. This also means that manually starting/committing/rollback a Transaction is not allowed and throws an IllegalStateException.

Reference: http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/Transaction3.html




回答2:


As posted above, under a Container Managed Transaction (CMT) you will get the getStatus() exception if you use the API.

https://issues.jboss.org/browse/JBSEAM-456

But you can as an alternative use: @Resource TransactionSynchronizationRegistry

How to tell if a transaction is active in a Java EE 6 interceptor?

By the way - the getStatus() api blows on glassfish, but it does not blow up on weblogic 12.1.2. Weblogic should actually be throwing the exception on the get status api.

The @Resource TransactionSynchronizationRegistry

Works fine on both containers.



来源:https://stackoverflow.com/questions/11768556/usertransaction-failed-when-call-utx-begin-throws-java-lang-illegalstateexcep

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!