Java, JPA, управляемые компонентом транзакции, TransactionRequiredException
У меня есть два EJB без гражданства. Один использует управляемые контейнером транзакции, другой - управляемый компонентом. Из EJB, управляемой контейнером, я вызываю метод EJB, управляемый бином.
public class firstEJB{
public void myMethod(){
ejb.longRunningMethod();
}
@EJB
private secondEJB ejb;
}
@TransactionManagement(TransactionManagementType.BEAN)
public class secondEJB {
public void longRunningMethod(){
while (true) {
this.ut.begin();
//do smth
this.ut.commit();
}
}
@Resource
private UserTransaction ut;
}
и я получил ошибку
Caused by: javax.persistence.TransactionRequiredException:
Exception Description: No externally managed transaction is currently active for this thread
at org.eclipse.persistence.internal.jpa.transaction.JTATransactionWrapper.throwCheckTransactionFailedException(JTATransactionWrapper.java:86)
at org.eclipse.persistence.internal.jpa.transaction.JTATransactionWrapper.checkForTransaction(JTATransactionWrapper.java:46)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.checkForTransaction(EntityManagerImpl.java:1776)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.executeReadQuery(EJBQueryImpl.java:449)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getResultList(EJBQueryImpl.java:742)
at com.sun.enterprise.container.common.impl.QueryWrapper.getResultList(QueryWrapper.java:195)
at com.sun.enterprise.container.common.impl.TypedQueryWrapper.getResultList(TypedQueryWrapper.java:129)
at VIGS.Statistics.DataProcessor.secondEJB.longRunningMethod(secondEJB.java:34)
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:42)
at sun.reflect.GeneratedMethodAccessor69.invoke(Unknown Source)
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.GeneratedMethodAccessor68.invoke(Unknown Source)
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.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:370)
at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5360)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5348)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:214)
... 42 more
Могу ли я вызвать метод EJB для управляемых компонентом транзакций из EJB, управляемой контейнером? Если да - что не так?
PS У меня есть ошибка в строке 34. Это код этой строки:
while ((lf = this.em.createNamedQuery("getNotProcessedLogFiles", LogFile.class).setMaxResults(0).setLockMode(LockModeType.PESSIMISTIC_WRITE).getResultList().get(0)) != null) {
1 ответ
Решение
Все было очень просто - в моем цикле while я пытаюсь установить режим блокировки LockModeType.PESSIMISTIC_WRITE Но мы можем сделать это только внутри транзакции...