0

I have Netbeans_8.0.2 to development my project using Glassfish_4.1. In the stateless bean, I initialize a named query in a method that has a @postconstruct annotation. But it throws an IllegalStateException when I try to invoke setParameter() on the named query.

Entity Class:

@Entity
@Table(name = "ORDERS")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "OrdersEntity.findByClientNum", query = "SELECT o FROM OrdersEntity o WHERE o.orderClientNum = :orderClientNum")})

public class OrdersEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "ORDER_SYS_NUM")
    private Integer orderSysNum;
    @Column(name = "ORDER_CLIENT_NUM")
    private String OrderClientNum;

    public OrdersEntity() {
    }

    public OrdersEntity(Integer sysNum) {
        this.dtOrderSysNum = sysNum;
    }

//setters & getters

}

Stateless Bean:

@Stateless
public class OrderServices implements OrderServicesRemote {
    @PersistenceContext(unitName = "OrderServicesPU")
    private EntityManager em;

    private TypedQuery<OrdersEntity>  queryFindOrderByOrderClientNum;

    @PostConstruct
    private void initializeBean() {
        queryFindOrderByOrderClientNum = em.createNamedQuery("OrdersEntity.findByClientNum", OrdersEntity.class);
        //comment 1: the following line of code works
        //OrdersEntity oe = queryFindOrderByOrderClientNum.setParameter("OrderClientNum", "OR123").getSingleResult();        
    }


    private OrdersEntity retrieveOrderEntity(String orderClientNum) {
        //comment 2: the following line of code causes the issue
            queryFindOrderByOrderClientNum.setParameter("OrderClientNum",   orderClientNum);

        OrdersEntity oe;
        try {
            oe = queryFindOrderByOrderClientNum.getSingleResult();
        } catch (NoResultException nre) {
            throw new OrderNotFoundException();
        } catch (NonUniqueResultException nure) {
           throw new OrderNotFoundException();
        }

        return oe;
    }
}

persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="RewardsManagerServicesPU" transaction-type="JTA">
    <jta-data-source>jdbc/Rewards_Pool</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
      <property name="eclipselink.jdbc.batch-writing" value="JDBC"/>
    </properties>
  </persistence-unit>
</persistence>

Details:

  1. I ran the program in debugger and figured out that the line of code below comment 2 causes the problem
  2. Entity Manager is functional. I have a couple of other functions in this statless bean, they all work well with it.
  3. As shows in comment 1, if I invoke setParameter() function on the named query immediately after it's initialized, it works.

Stacktrace:

Warning: A system exception occurred during an invocation on EJB OrderServices, method: public OrderServices.retrieveOrderVO(java.lang.String) throws OrderNotFoundException
Warning: javax.ejb.EJBException
at com.sun.ejb.containers.EJBContainerTransactionManager.processSystemException(EJBContainerTransactionManager.java:748)
at com.sun.ejb.containers.EJBContainerTransactionManager.completeNewTx(EJBContainerTransactionManager.java:698)
at com.sun.ejb.containers.EJBContainerTransactionManager.postInvokeTx(EJBContainerTransactionManager.java:503)
at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4566)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2074)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2044)
at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:212)
at com.sun.ejb.containers.EJBObjectInvocationHandlerDelegate.invoke(EJBObjectInvocationHandlerDelegate.java:79)
at com.sun.proxy.$Proxy301.retrieveOrderVO(Unknown Source)
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 com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie.dispatchToMethod(ReflectiveTie.java:143)
at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke(ReflectiveTie.java:173)
at com.sun.corba.ee.impl.protocol.ServerRequestDispatcherImpl.dispatchToServant(ServerRequestDispatcherImpl.java:528)
at com.sun.corba.ee.impl.protocol.ServerRequestDispatcherImpl.dispatch(ServerRequestDispatcherImpl.java:199)
at com.sun.corba.ee.impl.protocol.MessageMediatorImpl.handleRequestRequest(MessageMediatorImpl.java:1549)
at com.sun.corba.ee.impl.protocol.SharedCDRClientRequestDispatcherImpl.marshalingComplete(SharedCDRClientRequestDispatcherImpl.java:119)
at com.sun.corba.ee.impl.protocol.ClientDelegateImpl.invoke(ClientDelegateImpl.java:258)
at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:198)
at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.invoke(StubInvocationHandlerImpl.java:150)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
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: java.lang.IllegalStateException: Attempting to execute an operation on a closed EntityManager.
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.verifyOpen(EntityManagerImpl.java:1913)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.setParameter(EJBQueryImpl.java:592)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.setParameter(EJBQueryImpl.java:1)
at com.sun.enterprise.container.common.impl.QueryWrapper.setParameter(QueryWrapper.java:284)
at com.sun.enterprise.container.common.impl.TypedQueryWrapper.setParameter(TypedQueryWrapper.java:122)
at OrderServices.retrieveOrderEntity(OrderServices.java:394)
at OrderServices.retrieveOrderVO(OrderServices.java:656)
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 org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081)
at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153)
at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4786)
at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:656)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:55)
at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:52)
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 com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doCall(SystemInterceptorProxy.java:163)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:140)
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 com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:369)
at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:4758)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4746)
at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:205)
... 50 more
retupmoc
  • 1
  • 1
  • 3
  • It's not when you call `setParameter()` that you get the exception, it's when you call `getSingleResult()`. I haven't figured out why yet. – Roger Gustavsson Jun 02 '15 at 16:28
  • Thanks for the response. I set the breakpoints and walked through the code line by line. setParameter() does throw the exception. Before invoking the setParameter(), I even called em.isOpen() to make sure entity manager is live. – retupmoc Jun 02 '15 at 16:49
  • Ok. It just looked like the exception had to come from within the try-catch block, since the first line says that an `OrderNotFoundException` is being thrown. – Roger Gustavsson Jun 02 '15 at 16:55
  • The first line is a warning message that shows the function having the issue. OrderNotFoundException you have seen is one part of the function signature. – retupmoc Jun 02 '15 at 17:04
  • You're right. Shows that I'm not reading properly, that nor your details point 1. Sorry. – Roger Gustavsson Jun 02 '15 at 17:06
  • The only thing I can think of is that the bean is `@Stateless`. Perhaps it would work if the bean is `@Stateful`? But that's just a wild guess. Or perhaps it's possible to add `type = PersistenceContextType.EXTENDED` to `@PersistenceContext`? Again, I'm just guessing. – Roger Gustavsson Jun 02 '15 at 17:15
  • From my understanding, PersistenceContextType.EXTENDED is not compatible with @Stateless, I have to use stateless bean in my project though. – retupmoc Jun 02 '15 at 17:23
  • Another idea I have is that you inject a `@PersistenceUnit` instead (which gives you an `EntityManagerFactory`) from which you can get an `EntityManager`. But you will have to handle transactions yourself. – Roger Gustavsson Jun 02 '15 at 17:40
  • Glassfish seems to be closing out the EM underneath, but I can't tell why. You can avoid this by wrapping the calling method, retrieveOrderVO, in a transaction. This might force the container to keep the EM open. – Chris Jun 03 '15 at 12:49

1 Answers1

0

First of all using attributes (queryFindOrderByOrderClientNum) in stateless beans is in general discouraged as it makes no sense in general. A bit of an oversimplification, but think as stateless beans of shared objects between multiple clients. Using injection (em) it is fine as the container will make sure each client has an appropriate instance.

In PostConstruct you are creating a new instance of a named query that is associated with the current transaction and current entitymanager. After the PostConstruct method is done, the transaction is commited and the entitymanager "discarded". That means your named query instance will not work anymore.

There is actually no reason at all to pre-allocate the named query. Just create a new named query each time you query. In your case, create the query in the method retrieveOrderEntity.

If you tried to optimize by "caching" the named query creation, it will never work. The application server, persistence provider and database will optimize already using many techniques. Rely on them and remember "premature optimization is the root of all evil"

Dainesch
  • 1,320
  • 13
  • 19
  • I removed the named query from the PostConstruct method and create a new named query each time I query. It works now. Thanks. – retupmoc Jun 11 '15 at 15:06