Comment et qui devrait injecter PersistenceContext lors de l'exécution des tests par Jersey / Grizzly?

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

Question

J'ai cette classe (mélange de JAX-RS / Jersey et 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();
  }
}

Ceci est le test unitaire:

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

Tout est bien ici, sauf un ceci: em est NULL l'intérieur read(). On dirait que Grizzly (j'utilise ce serveur avec cadre Jersey test) n'est pas l'injection PersistenceContext. Qu'est-ce que je fais mal ici?

Était-ce utile?

La solution

  

Tout est bien ici, sauf un ceci: em est NULL dans read (). On dirait que Grizzly (j'utilise ce serveur avec cadre Jersey test) n'est pas l'injection PersistenceContext. Qu'est-ce que je fais mal ici?

  1. Je ne suis pas sûr Grizzly offre injection.
  2. Je ne suis pas sûr que l'injection est pris en charge dans « une » ressource Jersey de toute façon (Paul Sandoz semble impliquer qu'il devrait être dans ce fil mais je ne pouvais pas trouver des preuves claires de cette demande).

Alors, à ma connaissance, la solution la plus simple serait d'injecter la EntityManager dans un EJB 3.1 Stateless Session Bean (SLSB) qui peut être exposé directement en tant que ressources REST (en annotant avec JAX- RS annotations).

Une autre option rendrait les JAX-RS ressources bean géré et utiliser CDI pour l'injection. C'est l'approche de la TOTD # 124: Utilisation CDI + JPA avec JAX-RS et JAX-WS .

Dans les deux cas, je pense que vous aurez besoin d'utiliser le conteneur GlassFish Embarqués comme récipient pour vos tests de Jersey.

Ressources

Autres conseils

J'ai trouvé une solution pour com.sun.jersey / jersey grizzly2 Version 1.x . Je mis en œuvre une coutume InjectableProvider . Le code suivant est tiré d'un Oracle article :

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

Je devais adapter légèrement pour l'adapter à mon environnement. Notez également que le fournisseur doit être dans le même package que votre classe de service, sinon il ne sera pas pris (il ne dit pas que dans l'article).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top