javax.ejb.CreateException:无法创建无状态EJB - 不允许Container托管事务bean使用UserTransaction

时间:2015-10-27 18:10:17

标签: jsf java-ee jta

我有一个xhtml页面,它接受一些信息并调用addUser方法。当它这样做时,我收到错误:

javax.faces.el.EvaluationException: javax.ejb.EJBException: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
at java.lang.Thread.run(Thread.java:745)
Caused by: javax.ejb.EJBException: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB
at com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:435)
at com.sun.ejb.containers.BaseContainer.getContext(BaseContainer.java:2579)
at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1971)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:210)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
at com.sun.proxy.$Proxy228.addUser(Unknown Source)
at com.controllers.UserService.addUser(UserService.java:34)
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:483)
at javax.el.ELUtil.invokeMethod(ELUtil.java:332)
at javax.el.BeanELResolver.invoke(BeanELResolver.java:537)
at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:256)
at com.sun.el.parser.AstValue.invoke(AstValue.java:283)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
... 36 more
Caused by: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB
at com.sun.ejb.containers.StatelessSessionContainer$SessionContextFactory.create(StatelessSessionContainer.java:700)
at com.sun.ejb.containers.util.pool.NonBlockingPool.getObject(NonBlockingPool.java:246)
at com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:430)
... 55 more
Caused by: javax.ejb.CreateException: Could not create stateless EJB
at com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:514)
at com.sun.ejb.containers.StatelessSessionContainer.access$000(StatelessSessionContainer.java:97)
at com.sun.ejb.containers.StatelessSessionContainer$SessionContextFactory.create(StatelessSessionContainer.java:698)
... 57 more
Caused by: java.lang.IllegalStateException: Exception attempting to inject Env-Prop: com.dao.implementation.UserDAOImpl/tx@Field-Injectable Resource. Class name = com.dao.implementation.UserDAOImpl Field name=tx@java.lang.String@java:comp/UserTransaction@@ into class com.dao.implementation.UserDAOImpl: Lookup failed for 'java:comp/env/com.dao.implementation.UserDAOImpl/tx' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming}
at org.glassfish.weld.services.InjectionServicesImpl.aroundInject(InjectionServicesImpl.java:175)
at org.jboss.weld.injection.InjectionContextImpl.run(InjectionContextImpl.java:46)
at org.jboss.weld.injection.producer.DefaultInjector.inject(DefaultInjector.java:68)
at org.jboss.weld.injection.producer.StatelessSessionBeanInjector.inject(StatelessSessionBeanInjector.java:58)
at org.jboss.weld.injection.producer.ejb.SessionBeanInjectionTarget.inject(SessionBeanInjectionTarget.java:117)
at org.glassfish.weld.services.JCDIServiceImpl.injectEJBInstance(JCDIServiceImpl.java:257)
at com.sun.ejb.containers.BaseContainer.injectEjbInstance(BaseContainer.java:1748)
at com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:475)
... 59 more
Caused by: com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Env-Prop: com.dao.implementation.UserDAOImpl/tx@Field-Injectable Resource. Class name = com.dao.implementation.UserDAOImpl Field name=tx@java.lang.String@java:comp/UserTransaction@@ into class com.dao.implementation.UserDAOImpl: Lookup failed for 'java:comp/env/com.dao.implementation.UserDAOImpl/tx' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming}
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:740)
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.inject(InjectionManagerImpl.java:507)
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.injectInstance(InjectionManagerImpl.java:170)
at org.glassfish.weld.services.InjectionServicesImpl.aroundInject(InjectionServicesImpl.java:165)
... 66 more
Caused by: javax.naming.NamingException: Lookup failed for 'java:comp/env/com.dao.implementation.UserDAOImpl/tx' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NamingException: Lookup failed for 'java:comp/UserTransaction' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming, com.sun.enterprise.naming.logicalName=java:comp/env/com.dao.implementation.UserDAOImpl/tx} [Root exception is javax.naming.NameNotFoundException: Lookup of java:comp/UserTransaction not allowed for Container managed Transaction beans]]
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:491)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:438)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:636)
... 69 more
Caused by: javax.naming.NamingException: Lookup failed for 'java:comp/UserTransaction' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming, com.sun.enterprise.naming.logicalName=java:comp/env/com.dao.implementation.UserDAOImpl/tx} [Root exception is javax.naming.NameNotFoundException: Lookup of java:comp/UserTransaction not allowed for Container managed Transaction beans]
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:491)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:438)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at com.sun.enterprise.naming.util.JndiNamingObjectFactory.create(JndiNamingObjectFactory.java:90)
at com.sun.enterprise.container.common.impl.ComponentEnvManagerImpl$1.create(ComponentEnvManagerImpl.java:715)
at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.lookup(GlassfishNamingManagerImpl.java:745)
at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.lookup(GlassfishNamingManagerImpl.java:715)
at com.sun.enterprise.naming.impl.JavaURLContext.lookup(JavaURLContext.java:159)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:471)
... 73 more
Caused by: javax.naming.NameNotFoundException: Lookup of java:comp/UserTransaction not allowed for Container managed Transaction beans
at com.sun.ejb.containers.BaseContainer.checkUserTransactionLookup(BaseContainer.java:918)
at com.sun.ejb.EjbInvocation.userTransactionLookupAllowed(EjbInvocation.java:460)
at com.sun.enterprise.transaction.TransactionNamingProxy.checkUserTransactionLookupAllowed(TransactionNamingProxy.java:114)
at com.sun.enterprise.transaction.TransactionNamingProxy.handle(TransactionNamingProxy.java:95)
at com.sun.enterprise.naming.impl.NamedNamingObjectManager.tryNamedProxies(NamedNamingObjectManager.java:134)
at com.sun.enterprise.naming.impl.JavaURLContext.lookup(JavaURLContext.java:164)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:471)
... 82 more

我猜的主要线索是UserTransaction not allowed for Container managed Transaction beans。我的项目是JTA管理的,我在网上找到的所有教程都使用UserTransaction。我是java ee的新手,所以我不知道如何解决这个问题。

我应该如何重构我的代码(一个例子应该很棒)。我应该切换到项目中的RESOURCE_LOCAL并使用EntityTransaction。这甚至适用于jsf及其容器。如果是的话怎么样?

其余代码如下:

@Named("userService")
@RequestScoped
public class UserService {   

  User usr;    
  @EJB
  private UserDAO usDAO;    

  public void addUser(){
    try {
        if(usDAO == null)
            usDAO = new UserDAOImpl();
        emDAO.addUser(usr);
    } catch (UserException ex) {

    }
}

public void setUsr(User usr) {
    this.usr = usr;
}   

public User getUsr() {
    if(usr == null)
        usr = new User();
    return usr;
}      
}
@Local
public interface UserDAO {...
@Stateless
public class UserDAOImpl implements UserDAO{

    @PersistenceContext
    EntityManager em;

    @Resource
    UserTransaction tx;

    public void addUser(User usr) throws UserException {

    //EntityTransaction tx = em.getTransaction();
    try{
        tx.begin();
        em.persist(usr);
        tx.commit();
    }
    catch(Exception e){
                try {
                    tx.rollback();
                } catch (Exception ex) {

                }
        throw new UserException();
    }

}

1 个答案:

答案 0 :(得分:5)

使用JTA时,您无需手动管理事务。也许您正在阅读Java SE或Tomcat目标教程,这些教程确实需要RESOURCE_LOCAL并手动摆弄事务(没有EJB!)。这在真正的Java EE中是不必要的。

在带有JTA的@Stateless EJB内,单个方法调用默认计为单个事务。

所以,这应该做:

@Stateless
public class UserDAOImpl implements UserDAO {

    @PersistenceContext
    EntityManager em;

    public void addUser(User usr) {
        em.persist(usr);
    }

}

这就是全部。 Java EE容器本身将管理事务的启动,提交和回滚。

另见: