问题
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