3

I am trying to get a small sample web app up and running but I have run into a problem injecting the Entity Manager Factory.

My persistence.xml is as follows;

<persistence version="2.0" xmlns=" http://java.sun.com/xml/ns/persistene"
         xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/persistence ttp://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="main" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/Maindb</jta-data-source>
    <properties>
        <property name="eclipselink.ddl-generation" value="drop-and-create-tables" /> 
        <property name="eclipselink.ddl-generation.output-mode" value="database" /> 
    </properties>
</persistence-unit>

The web application has two functions; return a customer and a list of items.

The CustomerResource object injects the entity manager factory as follows:

@PersistenceUnit(unitName="main")
private EntityManagerFactory emf;

and queries the persistence layer by the following code;

EntityManager em = emf.createEntityManager();
Customer customer = (Customer) em.find(Customer.class, customerID);

This works with no problems (that I am aware of), I get the expected data returned.

The ItemResource object does the same thing against the same persistence unit.

@PersistenceUnit(unitName="main")
private EntityManagerFactory emf;

But the injection fails and emf is always null.

EntityManager em = emf.createEntityManager(); <- emf is null here

I am unsure of what I have done wrong here, my guess is that I am using the entity manager factory incorrectly.

Any help would be much appreciated! Thanks

Update

I was taking out the troublesome code to put in a war file for everyone to look at which helped me isolate the problem.

The issue seems to be with the url patterns I am using.

web.xml

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<listener>
    <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
<servlet>
    <servlet-name>Item</servlet-name>
    <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Item</servlet-name>
    <url-pattern>/Item/*</url-pattern>
</servlet-mapping>
<servlet>
    <servlet-name>Customer</servlet-name>
    <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Customer</servlet-name>
    <url-pattern>/Customer</url-pattern>
</servlet-mapping>
</web-app>

sun-jaxws.xml:

<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
    <endpoint name="Item" implementation="com.test.item.ItemResource" url-pattern="/Item/*" />
    <endpoint name="Customer" implementation="com.test.customer.CustomerResource" url-pattern="/Customer" />
</endpoints>

The item resource right now has two web methods;

  1. Get Item Details
    Type: Get
    Path: /
    Web param: item id

  2. Get Item List
    Type: Get
    Path: /list
    Web param: Item Colour

With the wild cards in the url patterns the entity manager is always null. If I remove the wild cards then I can successfully request an item, put I cannot request a list of items because it is not mapped.

The customer resource requests are always successful because it does not contain any wild cards in the mappings.

Thanks

Rupesh Yadav
  • 12,096
  • 4
  • 53
  • 70
mb789845
  • 33
  • 1
  • 5
  • Is the ItemResource class an EJB, a servlet or a managed bean? – Vineet Reynolds Jul 14 '10 at 16:25
  • I *think* that @PersistenceUnit is only guaranteed to work on objects managed by the EJB container. I could be mistaken, though. Are both CustomerResource and ItemResource EJBs of some type? If you're not sure, you could show the class definitions. – Dan LaRocque Jul 14 '10 at 16:30
  • @Dan, the annotation works for all container managed objects (both the servlet and EJB container fit this definition). EJBs are one such kind of managed objects. – Vineet Reynolds Jul 14 '10 at 16:37
  • the classes implement javax.xml.ws.Provider and are anointed with @WebServiceProvider – mb789845 Jul 14 '10 at 17:51
  • I think you should try out Pascal's advice of injecting the EntityManager instead of the EntityManagerFactory. The WebServiceProvider annotation appears to be one of those that is recognized by the container, and should inject the dependency. – Vineet Reynolds Jul 14 '10 at 18:15
  • Can you post the code for ItemResource. I'm with Dan on this one. – Preston Jul 15 '10 at 13:00

1 Answers1

3

I am not sure this will answer the question (why is the EMF null in the second case?) but since you're using an application-managed entity manager, do you close the EntityManager properly? Something like this:

public class LoginServlet extends HttpServlet {
    @PersistenceUnit(unitName="EmployeeService")
    EntityManagerFactory emf;

    protected void doPost(HttpServletRequest request, HttpServletResponse response) {
        String userId = request.getParameter("user");
        // check valid user
        EntityManager em = emf.createEntityManager();
        try {
            User user = em.find(User.class, userId);
            if (user == null) {
                // return error page
                // ...
            }
        } finally {
            em.close();
    }
}

But, honestly, I really wonder why you aren't using a container-managed entity manager. It is much simpler to let the container manage its life cycle in my opinion. To get an EntityManager injected:

@PersistenceContext(unitName = "main")
private EntityManager em;
Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
  • I have tried to inject the entity manager and I receive the same error. – mb789845 Jul 14 '10 at 18:20
  • @mb789845: Can you show the stacktrace that you get in the server logs? – Pascal Thivent Jul 14 '10 at 18:58
  • There were no exceptions thrown in the log files (the null pointer was being checked for). I have updated to question post to include log entries and more code, Thanks. – mb789845 Jul 14 '10 at 20:19
  • @mb789845: Maybe if you post some code allowing to reproduce your case (ideally, a war that you'd upload somewhere) I could investigate this problem further. With the current level of detail, I don't think its possible. – Pascal Thivent Jul 14 '10 at 20:54
  • I've updated the main description with the isolated problem, if you'd like me to send the project I would still be happy to do so. Thanks – mb789845 Jul 19 '10 at 17:28
  • I've uploaded a war file to http://rapidshare.com/files/407978139/error.war with the error I'm seeing. Example request that works: /CustomerResourceService?CustomerID=1 Example request with a null Entity Manager /Customer?CustomerID=1 – mb789845 Jul 20 '10 at 12:44