NameNotFoundException in Container Managed EntityM

2019-08-26 02:10发布

问题:

I am trying to use Container Managed EntityManager, however I am getting NameNotFoundException. I have tried adding entries in web.xml but in vain.

@Stateless
@Path("/mypath")
public class EmployeeService {

    @EJB
    private EmployeeDAO employeeDAO;

    @GET
    @Path("/myresults")
    @Produces(MediaType.APPLICATION_JSON)
    public Employee getValues() {
        Employee emp = new Employee();
        try  {
            emp = employeeDAO.getEmployees(); // exception here
        } catch (Exception ex)  {
            ex.printStackTrace();
        } 
        return emp;
    }

EmployeeDAO code snippet

public class EmployeeDAO {
    @PersistenceContext(unitName = "test-ejb", name = "persistence/em")

    public Employee getEmployees() throws NamingException {
        int empNo = 342;
        Context context = new InitialContext();
        context.lookup("java:comp/env");
        EntityManager em = (EntityManager)context.lookup("persistence/em");
        return em.find(Employee.class, empNo);
    }

persistence.xml

<?xml version="1.0" encoding="UTF-8" ?>
<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_1_0.xsd" version="1.0"
             xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="test-ejb" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/testDS</jta-data-source>
    <class>test.entity.Employees</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
      <property name="eclipselink.target-server" value="OC4J"/>
      <property name="javax.persistence.target-database" value="Oracle"/>
      <property name="javax.persistence.logging.parameters" value="TRUE"/>
    </properties>
  </persistence-unit>
</persistence>

Exception stack

javax.naming.NameNotFoundException: persistence/em not found at com.evermind[Oracle Containers for J2EE 10g (10.1.3.5.0) ].server.rmi.RMIServerContext.lookup(RMIServerContext.java:207) at com.evermind[Oracle Containers for J2EE 10g (10.1.3.5.0) ].server.ApplicationContext.unprivileged_lookup(ApplicationContext.java:256) at com.evermind[Oracle Containers for J2EE 10g (10.1.3.5.0) ].server.ApplicationContext.lookup(ApplicationContext.java:196) at javax.naming.InitialContext.lookup(InitialContext.java:392) at test.dao.EmployeeDAO.getValues(EmployeeDAO.java:39) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60) at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:185) at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75) at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302) at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108) at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84) at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1511) at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1442) at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1391) at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1381) at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416) at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538) at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716) at javax.servlet.http.HttpServlet.service(HttpServlet.java:856) at com.evermind[Oracle Containers for J2EE 10g (10.1.3.5.0) ].server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:734) at com.evermind[Oracle Containers for J2EE 10g (10.1.3.5.0) ].server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:391) at com.evermind[Oracle Containers for J2EE 10g (10.1.3.5.0) ].server.http.HttpRequestHandler.doProcessRequest(HttpRequestHandler.java:908) at com.evermind[Oracle Containers for J2EE 10g (10.1.3.5.0) ].server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:458) at com.evermind[Oracle Containers for J2EE 10g (10.1.3.5.0) ].server.http.HttpRequestHandler.serveOneRequest(HttpRequestHandler.java:226) at com.evermind[Oracle Containers for J2EE 10g (10.1.3.5.0) ].server.http.HttpRequestHandler.run(HttpRequestHandler.java:127) at com.evermind[Oracle Containers for J2EE 10g (10.1.3.5.0) ].server.http.HttpRequestHandler.run(HttpRequestHandler.java:116) at oracle.oc4j.network.ServerSocketReadHandler$SafeRunnable.run(ServerSocketReadHandler.java:260) at com.evermind[Oracle Containers for J2EE 10g (10.1.3.5.0) ].util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:303) at java.lang.Thread.run(Thread.java:662)

Update 1

@Stateless
@LocalBean
public class EmployeeDAO {
    @PersistenceContext(unitName = "test-ejb", name = "persistence/em")

    public Employee getEmployees() throws NamingException {
        int empNo = 342;
        Context context = new InitialContext();
        context.lookup("java:comp/env");
        EntityManager em = (EntityManager)context.lookup("persistence/em");
        return em.find(Employee.class, empNo);
    }

Exception

javax.ejb.EJBException: Setter injection being applied to non-setter method: getValues; nested exception is: java.lang.InstantiationException: Setter injection being applied to non-setter method: getValues

Full stack

Caused by: java.lang.InstantiationException: Setter injection being applied to non-setter method: getValues at com.evermind.server.deployment.J2EEContextAnnotationParser.validateInjectionSetter(J2EEContextAnnotationParser.java:713) at com.evermind.server.deployment.J2EEContextAnnotationParser.createInjectionTarget(J2EEContextAnnotationParser.java:729) at com.evermind.server.deployment.J2EEContextAnnotationParser.parseInjectedMethod(J2EEContextAnnotationParser.java:378) at com.evermind.server.ejb.deployment.BeanDescriptorAnnotationParser.parseInjectedMethodAndCallbacks(BeanDescriptorAnnotationParser.java:276) at com.evermind.server.ejb.deployment.SessionBeanDescriptorAnnotationParser.parseInjectedMethodAndCallbacks(SessionBeanDescriptorAnnotationParser.java:95) at com.evermind.server.ejb.deployment.BeanDescriptorAnnotationParser.parseAnnotations(BeanDescriptorAnnotationParser.java:77) at com.evermind.server.ejb.deployment.BeanDescriptorAnnotationParser.parseAnnotations(BeanDescriptorAnnotationParser.java:48) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.evermind.server.ejb.BeanAnnotationListener.parseAnnotatedClass(BeanAnnotationListener.java:45)

回答1:

Change:

public class EmployeeDAO {
    @PersistenceContext(unitName = "test-ejb", name = "persistence/em")
...

to:

@PersistenceContext(unitName = "test-ejb", name = "persistence/em")
@Stateless
public class EmployeeDAO {
...


回答2:

EmployeeDAO must be a container-managed class (listener, filter, servlet, EJB, managed bean, CDI managed bean, etc.), not a POJO. The JPA container will only search for JPA annotations on container-managed classes, not on POJOs.

Your options are:

  1. Change EmployeeDAO to be a container-managed class. For example, if your application server supports EJBs, then add the @Stateless annotation to the class.
  2. Move the @PersistenceContext annotation to a container-managed class. For example, if you have an existing listener, filter, or servlet, move the annotation to that class.
  3. Add <persistence-context-ref> to web.xml.

Note, your application server must support container-managed JPA for any of these approaches to work.