Cómo y quién debe inyectar PersistenceContext cuando se ejecuta a través de pruebas de Jersey / Grizzly?

StackOverflow https://stackoverflow.com/questions/3814621

Pregunta

Tengo esta clase (mezcla de JAX-RS / Jersey y 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();
  }
}

Esta es la prueba de la unidad:

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);
  }
}

Todo está bien aquí, excepto uno esto: em es NULL dentro read(). Se parece a Grizzly (estoy usando este servidor junto con Marco Prueba Jersey) no está inyectando PersistenceContext. ¿Qué estoy haciendo mal aquí?

¿Fue útil?

Solución

  

Todo está bien aquí, excepto uno esto: em es NULL en el interior de lectura (). Se parece a Grizzly (estoy usando este servidor junto con Marco Prueba Jersey) no está inyectando PersistenceContext. ¿Qué estoy haciendo mal aquí?

  1. No estoy seguro de inyección ofertas Grizzly.
  2. No estoy seguro de inyección se apoya en "cualquier" recurso Jersey de todos modos (Sandoz Pablo parece dar a entender que debería estar en este hilo pero no pude encontrar evidencia clara de que la reclamación).

Así que yo sepa, la solución más fácil sería para inyectar el EntityManager en un EJB 3.1 Stateless Session Bean (SLSB) que puede ser expuesto directamente como un recurso REST (anotando con JAX- RS anotaciones).

Otra opción sería hacer que los JAX-RS de recursos de un bean administrado y utilizar CDI para inyección. Ese es el enfoque de la totd # 124: El uso de CDI + JPA con JAX-RS y JAX-WS .

En ambos casos, creo que tendrá que utilizar el contenedor GlassFish Embedded como contenedor para sus pruebas Jersey.

Recursos

Otros consejos

He encontrado una solución para com.sun.jersey / Jersey-grizzly2 versión 1.x . He implementado una costumbre InjectableProvider . El código siguiente se toma de una Oracle artículo :

import javax.ejb.EJB;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.ws.rs.ext.Provider;

import com.sun.jersey.core.spi.component.ComponentContext;
import com.sun.jersey.core.spi.component.ComponentScope;
import com.sun.jersey.spi.inject.Injectable;
import com.sun.jersey.spi.inject.InjectableProvider;

@Provider
public class EJBProvider implements InjectableProvider<EJB, Type> {

    public Scope getScope() {
        return Scope.Singleton;
    }

    public Injectable getInjectable(ComponentContext cc, EJB ejb, Type t) {
        if (!(t instanceof Class)) return null;

        try {
            Class c = (Class)t;        
            Context ic = new InitialContext();

            final Object o = ic.lookup(c.getName());

            return new Injectable<Object>() {
                public Object getValue(HttpContext c) {
                    return o;
                }                    
            };            
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

he tenido que adaptar ligeramente para que se ajuste mi entorno. También tenga en cuenta que el proveedor tiene que estar en el mismo paquete que la clase de servicio, de lo contrario no será recogido (no dice que en el artículo).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top