views:

41

answers:

1

I have this class (mix of JAX-RS/Jersey and JPA/Hibernate):

public class Factory {
  @PersistenceContext(unitName = "abc")
  EntityManager em;
  @Path("/{id}")
  @GET
  public String read(@PathParam("id") int i) {
    return em.find(Employee.class, i).getName();
  }
}

This is the unit test:

public class FactoryTest extends JerseyTest {
  public FactoryTest() throws Exception {
    super("com.XXX");
  }
  @Test
  public void testReadingWorks() {
    String name = resource().path("/1").get(String.class);
    assert(name.length() > 0);
  }
}

Everything is fine here except one this: em is NULL inside read(). Looks like Grizzly (I'm using this server together with Jersey Test Framework) is not injecting PersistenceContext. What am I doing wrong here?

+1  A: 

Everything is fine here except one this: em is NULL inside read(). Looks like Grizzly (I'm using this server together with Jersey Test Framework) is not injecting PersistenceContext. What am I doing wrong here?

  1. I'm not sure Grizzly offers injection.
  2. I'm not sure injection is supported in "any" Jersey resource anyway (Paul Sandoz seems to imply it should be in this thread but I couldn't find clear evidence of that claim).

So to my knowledge, the easiest solution would be to inject the EntityManager into an EJB 3.1 Stateless Session Bean (SLSB) which can be exposed directly as a REST resources (by annotating it with JAX-RS annotations).

Another option would make the JAX-RS resource a managed bean and to use CDI for injection. That's the approach of the TOTD #124: Using CDI + JPA with JAX-RS and JAX-WS.

In both cases, I think you'll need to use the Embedded GlassFish container as container for your Jersey Tests.

Resources

Pascal Thivent
@Pascal "In both cases, I think you'll need to use the Embedded GlassFish container as container for your Jersey Tests." — instead of Grizzly?
Vincenzo
@Vincenzo Yes, instead of Grizzly.
Pascal Thivent
@Pascal "Another option would make the JAX-RS resource a managed bean" — meaning that I have to split my `Factory` class onto two classes `FactoryRest` and `FactoryBean`, then CDI-injecting `FactoryBean` into `FactoryRest`. Did I understand you right?
Vincenzo
@Vincenzo Well, you could try to inject an EMF via CDI (keep in mind an EntityManager isn't thread safe). Or you could indeed have 2 classes and inject an EJB. But I don't really see the point of having 2 classes if you can expose an EJB directly as a REST resource.
Pascal Thivent