Reputation: 94
Yet another 'EntityManager is null' question. I've searched for an answer but haven't found one that works for me. I'm taking over a large project and I'm trying to simplify it to cut out red herrings when debugging. I'm down to a simple Customer/Order system and I'm just trying to deploy it and view the list of customers. Based on another question I asked and a resulting suggestion I'm down to the following (actual question and stack trace at bottom):
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/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_2_0.xsd">
<persistence-unit name="my_PU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>my_datasource</jta-data-source>
<class>my.database.model.Customer</class>
<class>my.database.model.Order</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
</persistence-unit>
</persistence>
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_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>MyWebApp</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>resources.application</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/balusc.taglib.xml</param-value>
</context-param>
<context-param>
<param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
<param-value>true</param-value>
</context-param>
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>false</param-value>
</context-param>
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
</web-app>
webpage - menu.xhtml
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<link rel="stylesheet" type="text/css" media="screen,projection"
href="../css/menu.css" /></head>
<ui:component>
<div class="menu-container">
<div class="menu-tab">
<ul>
<li><a href="index.xhtml"><span>Home</span></a></li>
<li><h:outputLink
value="#{customerController.getUrl()}">
<span><h:outputText value="Customer" /></span>
</h:outputLink></li>
<li><a href=""><span>Logout</span></a></li>
</ul>
</div>
</div>
</ui:component>
</html>
CustomerController.java
package my.webapp.web.controller;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
import my.model.Customer;
@Named(value = "customerController")
@RequestScoped
public class CustomerController// extends FormRequestController
{
private Customer customer;
private String id;
protected List<?> entityObjectList;
protected boolean editMode;
@PostConstruct
public void init() {
System.out.println("CustomerController init");
setEntityObjectList(findAll());
}
public List<?> findAll() {
List<Customer> dataList = Customer.getAllRecords();
return dataList;
}
public String getUrl()
{
System.out.println("CustomerController getUrl");
return "www.google.com";
}
//getters and setters ommitted for brevity
}
Customer.java
package my.model;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.ejb.EJB;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import my.database.manager.PersistenceStoreManager;
@Entity
@Table(name=Customer.TBL_NAME)
@NamedQueries({
@NamedQuery(name=Customer.QRY_ALL, query="select object(a) from Customer a")
})
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
/**
* Manager class to manager DB connections
*/
@EJB
private static PersistenceStoreManager<Customer> psm;
// Table constants
public static final String TBL_NAME = "Customer";
public static final String QRY_ALL = TBL_NAME + ".all";
private int id;
private String name;
private Set<Order> orders;
public Customer() {
}
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public int getId() {
return this.id;
}
//bi-directional many-to-one association to Order
@OneToMany(mappedBy="id")
public Set<Order> getOrders() {
return this.orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
public static List<Customer> getAllRecords(){
Map<String, Object> params = new HashMap<String, Object>();
return psm.getResultSetList(QRY_ALL, params);
}
//other getters and setters omitted for brevity
}
PersistenceStoreManager.java
package my.database.manager;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
/**
* This class is responsible for performing CRUD operations using the
* EntityManager of the PersistenceContext.
*
*
*/
@Stateless
public class PersistenceStoreManager<T>
{
@PersistenceContext(unitName = "my_PU")
private EntityManager em;
public PersistenceStoreManager ()
{
System.out.println("PersistenceStoreManager loaded");
System.out.println("em is null: "+(em==null));
}
@PostConstruct
public void postInject()
{
System.out.println("postInject");
System.out.println("em is null: "+(em==null));
}
/**
* @param namedQuery
* @param criteria
* @return
*/
public List<T> getResultSetList(String namedQuery,
Map<String, Object> criteria) {
Query q = em.createNamedQuery(namedQuery);
for (Map.Entry<String, Object> entry : criteria.entrySet()) {
q.setParameter(entry.getKey(), entry.getValue());
}
List<T> resultSetList = q.getResultList();
return resultSetList;
}
}
My Application deploys but I get the ubiquitous NullPointerException
when trying to view the menu.xhtml
page. The following is logged when I deploy my application:
-WARNING|org.apache.catalina.connector.Request|_ThreadID=37;_ThreadName=Thread-2;|PWC4011: Unable to set request character encoding to UTF-8 from context , because request parameters have already been read, or ServletRequest.getReader() has already been called|#]
-INFO|uploadFileName=MyWebApp-0.0.1-SNAPSHOT.war|#]
-INFO|javax.enterprise.system.container.ejb.com.sun.ejb.containers|Portable JNDI names for EJB PersistenceStoreManager: [java:global/MyWebApp-0.0.1-SNAPSHOT/PersistenceStoreManager, java:global/MyWebApp-0.0.1-SNAPSHOT/PersistenceStoreManager!my.database.manager.PersistenceStoreManager]|#]
-INFO|javax.enterprise.system.std.com.sun.enterprise.server.logging|PersistenceStoreManager loaded|#]
-INFO|javax.enterprise.system.std.com.sun.enterprise.server.logging|em is null: true|#]
-INFO|javax.enterprise.resource.webcontainer.jsf.config|Initializing Mojarra 2.1.6 (SNAPSHOT 20111206) for context '/MyWebApp-0.0.1-SNAPSHOT'|#]
-INFO|org.primefaces.webapp.PostConstructApplicationEventListener|Running on PrimeFaces 3.4.1|#]
-INFO|javax.enterprise.system.container.web.com.sun.enterprise.web|WEB0671: Loading application [MyWebApp-0.0.1-SNAPSHOT] at [/MyWebApp-0.0.1-SNAPSH 6243 OT]|#]
-INFO|javax.enterprise.system.tools.admin.org.glassfish.deployment.admin|MyWebApp-0.0.1-SNAPSHOT was successfully deployed in 1,598 milliseconds.|#]
When I navigate to myserver:8080/MyWebApp-0.0.1-SNAPSHOT/faces/index.xhtml The following is logged:
[#|2014-06-06T16:51:56.988+0100|SEVERE|glassfish3.1.2|javax.enterprise.resource.webcontainer.jsf.application|_ThreadID=36;_ThreadName=Thread-2;|Error Rendering View[/index.xhtml]
javax.el.ELException: /templates/menu.xhtml @15,64 value="#{customerController.getUrl()}": org.jboss.weld.exceptions.WeldException: WELD-000049 Unable to invoke [method] @PostConstruct public my.webapp.web.controller.CustomerController.init() on my.webapp.web.controller.CustomerController@4085f7ff
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
...[long stack trace]...
Caused by: java.lang.NullPointerException
at my.model.Customer.getAllRecords(Customer.java:64)
at my.webapp.web.controller.CustomerController.findAll(CustomerController.java:41)
at my.webapp.web.controller.CustomerController.init(CustomerController.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
...[long stack trace]...
None of the logging in the postInject()
methods in Customer
, CustomerController
and PersistenceStoreManager
is being output. Since they are annotated with @PostConstruct
and should be called after injection, I assume that the EJB injection isn't taking place.
Can anyone see why the EJB injection isn't happening?
Upvotes: 0
Views: 878
Reputation: 42074
EJB is not injected because they can be only injected in container managed classes and entities are not container managed classes. Container managed classes are listed for example in Java EE 6 specification.
Upvotes: 1