Pergunta

Eu tenho essa aula (Mix de Jax-Rs/Jersey e 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();
  }
}

Este é o teste de unidade:

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

Tudo está bem aqui, exceto um: em é NULL lado de dentro read(). Parece o Grizzly (estou usando este servidor junto com a estrutura de teste de Jersey) não está injetando PersistenceContext. O que eu estou fazendo errado aqui?

Foi útil?

Solução

Tudo está bem aqui, exceto um: em é nulo interno read (). Parece o Grizzly (estou usando este servidor junto com a estrutura de teste de Jersey) não está injetando PersistEncecontext. O que eu estou fazendo errado aqui?

  1. Não tenho certeza se o Grizzly oferece injeção.
  2. Não tenho certeza de este tópico Mas não consegui encontrar evidências claras dessa reivindicação).

Então, pelo que sei, a solução mais fácil seria injetar o entityManager em um EJB 3.1 Sessão sem estado Bean (SLSB), que pode ser exposta diretamente como recursos de repouso (anotando-o com anotações JAX-RS).

Outra opção faria com que o recurso Jax-rs Bean gerenciado e usar CDI para injeção. Essa é a abordagem do TOTD #124: Usando CDI + JPA com Jax-Rs e Jax-Ws.

Nos dois casos, acho que você precisará usar o recipiente de peixe de vidro incorporado como recipiente para seus testes de camisa.

Recursos

Outras dicas

Eu encontrei uma solução para com.sun.jersey/Jersey-Grizzly2 versão 1.x. Eu implementei um costume InjetávelProvider. O código a seguir é retirado de um Artigo do Oracle:

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

Eu tive que adaptá -lo um pouco para se encaixar no meu ambiente. Observe também que o provedor deve estar no mesmo pacote que sua classe de serviço, caso contrário, não será retirado (não diz isso no artigo).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top