EJB3 - EntityManager is null (not injected?)

Hi, I'm trying to use EntityManager from the processRequest() method of my servlet. It's declared in the fields like this

@PersistenceContext(unitName="testunit1") EntityManager em;

The problem is that the EntityManager object, em, is null.

My persistence.xml looks like this:

<?xml version="1.0" encoding="UTF-8"?>

<!-- example of adefault persistence.xml -->

<persistence>

<persistence-unit name="testunit1" transaction-type="RESOURCE_LOCAL">

<jta-data-source>java:/OracleDS</jta-data-source>

<class>testing.Pdfinstalledfonts</class>

<properties>

<property name="jboss.entity.manager.jndi.name" value="java:/testunit1"/>

<property name="jboss.entity.manager.factory.jndi.name" value="java:/testunit1Factory"/>

<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle9Dialect" />

<property name="hibernate.connection.driver_class" value="oracle.jdbc.driver.OracleDriver" />

<property name="hibernate.connection.username" value="xxxxxxx" />

<property name="hibernate.connection.password" value="xxxxxxx" />

<property name="hibernate.connection.url" value="jdbc:oracle:thin:@xxxxxxx:1521:xxxxxx" />

<property name="hibernate.ejb.autodetection" value="class" />

</properties>

</persistence-unit>

</persistence>

I'm using JBoss 4.0.4 CR 2

[2071 byte] By [borbjoa] at [2007-10-2 19:43:57]
# 1

Be careful where you put the annotation or you'll get problems

public class MyServlet extends HttpServlet {

@PersistenceContext(unitName="testunit1") EntityManager shouldWork;

...

void someMethod() {

@PersistenceContext(unitName="testunit1") EntityManager wontWork;

assert shouldWork != null;

assert wontWork == null;

}

}

...

}

Also, the container should not look for annotations in your web classes unless the web.xml is using the correct schema version.

i.e. if the web.xml is a schema version before annotations were introduced, then there shouldn't be any annotations to find and so the container is free to not bother looking for them!

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

DrS@STVConsultantsa at 2007-7-13 22:22:23 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 2

Thank you for those bits of information - it could've gone wrong with any of those , as I was unaware of it - especially the web.xml thing.

However, it doesn't have anything to do with that, the start of my web.xml looks like this:<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

.. and my servlet class with it's annotation looks like this:

public class TestServlet extends HttpServlet {

@PersistenceContext(unitName="testunit1") EntityManager em;

/** Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.

* @param request servlet request

* @param response servlet response

*/

protected void processRequest(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

(...)

}

borbjoa at 2007-7-13 22:22:23 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 3
Hmm, it seems dependency injections don't work for servlets?
borbjoa at 2007-7-13 22:22:23 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 4

Feck Feck Feck!

Sorry, the revised spec says that you cannot inject an entity manager into the web tier. You have to inject an EntityManagerFactory and use that to get the EntityManager.

Forgot about that spec change!

There's a good reason why you have to jump through those hoops, it's to do with threading and transactions I think. Check Sahoo's Blog around Jan/Feb for when he spotted the details.

DrS@STVConsultantsa at 2007-7-13 22:22:23 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 5

allright, thanks :) *handing dukes* ... but since you seem to know this stuff - you wouldn't happen to know what would cause this exception:

javax.naming.NameNotFoundException: PdfInstalledfontsSessionEJB not bound

at org.jnp.server.NamingServer.getBinding(NamingServer.java:529)

at org.jnp.server.NamingServer.getBinding(NamingServer.java:537)

at org.jnp.server.NamingServer.getObject(NamingServer.java:543)

at org.jnp.server.NamingServer.lookup(NamingServer.java:296)

at sun.reflect.GeneratedMethodAccessor108.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:585)

at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:294)

at sun.rmi.transport.Transport$1.run(Transport.java:153)

at java.security.AccessController.doPrivileged(Native Method)

at sun.rmi.transport.Transport.serviceCall(Transport.java:149)

at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)

at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)

at java.lang.Thread.run(Thread.java:595)

at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:247)

at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:223)

at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:126)

at org.jnp.server.NamingServer_Stub.lookup(Unknown Source)

at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:625)

at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:587)

at javax.naming.InitialContext.lookup(InitialContext.java:351)

at testing.PdfInstalledfontsSessionEJBClient.main(PdfInstalledfontsSessionEJBClient.java:15)

I guess I have to bind it ;-) .. but I thought I'd done that in my ejb-jar.xml:

<?xml version="1.0"?>

<ejb-jar

xmlns="http://java.sun.com/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"

version="3.0">

<description>Teste and Story</description>

<display-name>Teste and Story</display-name>

<enterprise-beans>

<session>

<display-name>PdfInstalledfontsSessionEJB Session Stateless Bean</display-name>

<ejb-name>PdfInstalledfontsSessionEJBBean</ejb-name>

<remote>testing.PdfInstalledfontsSessionEJB</remote>

<ejb-class>testing.PdfInstalledfontsSessionEJBBean</ejb-class>

<session-type>Stateless</session-type>

<transaction-type>Container</transaction-type>

</session>

<entity>

<display-name>Pdfinstalledfonts</display-name>

<ejb-name>Pdfinstalledfonts</ejb-name>

<remote>testing.PdfInstalledfontsSessionEJB</remote>

<ejb-class>testing.Pdfinstalledfonts</ejb-class>

<reentrant>False</reentrant>

<persistence-type>Container</persistence-type>

</entity>

</enterprise-beans>

<assembly-descriptor />

</ejb-jar>

borbjoa at 2007-7-13 22:22:23 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 6

My question is how are you starting the testing client?

It looks like your testing client is being run outside of the EJB container,

If that is the case, then your testing client may not know how to lookup the name correctly.

When you are running in the web tier, the web container knows about the EJB container, and so the InitialContext.lookup knows to ask the EJB container if it knows about your session bean.

If you are just doing something like

java testing.PdfInstalledfontsSessionEJBClient

Then you need to ensure things are configured correctly such that the correct InitialContext is used that knows about the EJB Container.

If you are using Glassfish, then the appclient command will do all this for you. Alternatively, setting up java web start and deploying your appclient.jar works too.

I know in JBoss there is some classpath or other trickery that does the same thing. There may be some classpath trickery with Glassfish that you can use too (in case you are running the client from withing an IDE), but to be honest, I'm not that familiar with how these things have been simplified in JavaEE5 and too rusty on how they used to be done!

DrS@STVConsultantsa at 2007-7-13 22:22:23 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 7
Ok, thanks .. I'm running it from the command line, but I get the same exception if I try to use the same code from a servlet.I'm sure it's a configuration problem somewhere, but it's just difficult to know what it is when being new to EJB.
borbjoa at 2007-7-13 22:22:23 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 8

Hi,

I have constant problems of these sort.. I even took NetBeans sample application JsfSpa, run it successfully (it worked), then modified slightly and the problems begun. I have no ide what is the problem. I have modified method:

private Wuser getUser() {

/*try {

Wuser user = (Wuser)

em.createNamedQuery("Wuser.findByUsername").

setParameter("username", username).getSingleResult();

return user;

} catch (NoResultException nre) {

return null;

}

*/

return (new dao.UserPersistenceServiceBean()).getUserByName(username);

}

and added the class:

package dao;

import enterprise.jsf_jpa_war.Wuser;

import javax.persistence.PersistenceContext;

import javax.persistence.EntityManager;

import javax.persistence.NoResultException;

public class UserPersistenceServiceBean {

@PersistenceContext

private EntityManager em;

public Wuser getUserByName( String userName ) {

try {

return (Wuser)em.createNamedQuery("Wuser.findByUsername").setParameter("username", userName).getSingleResult();

} catch( NoResultException nrExc ) {

return null;

}

}

}

I get NullPointerException (em is null). Whats more, I have the same problems with Session EJB. I developed a simple application in Eclipse...

package services;

import services.RegisterNewUserService;

import javax.ejb.EJB;

public class Dummy {

@EJB private RegisterNewUserService registerService;

public String doRegister(domain.NewUserData userData) {

if (registerService == null)

return "failure";

else

return registerService.doRegister(userData);

}

}

and registerService is null. Anyone has any idea? I use Sun Java System Application Server 9 and JDK 1.5

Regards

Mariusz Lipi駍ki

Mariolia at 2007-7-13 22:22:23 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...