【问题标题】:UserTransaction failed when call utx.begin() throws "java.lang.IllegalStateException: Operation not allowed"调用 utx.begin() 时 UserTransaction 失败抛出“java.lang.IllegalStateException:不允许操作”
【发布时间】:2012-08-01 22:35:52
【问题描述】:

我想使用 ejb 和 jpa 控制器,在 netbeans 中控制器是自动生成的...我尝试从类 (UniversidadServiceEJB) 调用 jpa 控制器,这是一个无状态会话 bean,我调试了项目以及 UserTransaction 和 EntityManagerFactory创建成功但是在jpa控制器(UniversityJpaController)中调用utx.begin方法时会抛出这个异常:

java.lang.IllegalStateException: 不允许操作。

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

Session Bean 类是:

@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);
        } 

    } 

}

而jpacontroller类是:

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();
            }
        }
    }
}

持久化单元是:

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

请问是什么问题?... 非常感谢...

【问题讨论】:

    标签: jpa controller ejb eclipselink stateless-session-bean


    【解决方案1】:

    通常在 EJB 环境中,事务由容器管理。它将 Bean 方法包装在事务中,并在发生异常时自动回滚。这也意味着不允许手动启动/提交/回滚事务并抛出 IllegalStateException。

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

    【讨论】:

    • 谢谢...现在我有这个例外,您可以帮帮我。例外是 java.lang.IllegalArgumentException:对象:entities.universidad[ id=null ] 不是已知的实体类型。我查看了其他帖子,但没有找到解决方案。我使用 EclipseLink,ID.Generated 的类型是 IDENTITY,这是我在主类中创建的实体:Universidad universidad = new Universidad(); universidad.setName("UCV"); universidadController.create(universidad);
    【解决方案2】:

    如上所述,在容器管理事务 (CMT) 下,如果您使用 API,您将获得 getStatus() 异常。

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

    但您可以作为替代使用: @资源 TransactionSynchronizationRegistry

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

    顺便说一句,getStatus() api 会在 glassfish 上运行,但不会在 weblogic 12.1.2 上运行。 Weblogic 实际上应该在 get status api 上抛出异常。

    @资源 TransactionSynchronizationRegistry

    在两个容器上都可以正常工作。

    【讨论】:

      猜你喜欢
      • 2012-06-19
      • 1970-01-01
      • 2012-08-18
      • 1970-01-01
      • 2019-01-25
      • 2023-01-27
      • 2021-12-03
      • 2021-09-09
      • 2020-09-14
      相关资源
      最近更新 更多