GlassFish + EJB + CDI + JSF2 problemas na UnitPersistence[SOLVED]

Ola pessoal,

tenho um modulo EJB com um webservice rodando, tenho meus beans, repositorios, meu persistence.xml tudo funciona ok, porém precisei incuir um portal no modulo web, minha dúvida é quanto a utilização dos recursos do modulo EJB ex:

no project web preciso utilizar os repositorios que estão la no modulo EJB, porém ao injetar esses caras em meu beanManager tenho a seguinte exception:

Unable to retrieve EntityManagerFactory for unitName null

os beans do JSF e o PhaseListener estão no projeto web, as entidades e repositorios estão no projeto EJB, quando vou verificar se o usuario existe no banco de dados tenho a exception acima, como devo proceder em apps enterprise ? preciso ter um persistence só para o projeto web ? como vocês fazem ? abraços.

ex:

@Named
@Stateless
public class LoginBean implements Serializable {

    @Inject
    private Usuario usuario;
    @Inject
    private UsuarioRepository usuarioRepository;
    @Inject
    private UsuarioLogado usuarioLogado;

Como estão declarados estes repositórios? São CDI beans ou Stateless? Você tem apenas um ou mais entity managers declarados no persistence.xml? O caused-by aponta para qual classe?

os repositórios São CDI beans, estão assim no módulo EJB:

@Repository
public class UsuarioRepository {

    @PersistenceContext
    private EntityManager em;

    public Usuario findByPK(Long id) {
        return em.find(Usuario.class, id);
    }

    public boolean exists(Usuario usuario) {
        boolean encontrado = false;
        try {
            Query query = em.createQuery("SELECT u FROM Usuario u WHERE u.login = :uLogin and u.senha = :uSenha");
            query.setParameter("uLogin", usuario.getLogin());
            query.setParameter("uSenha", usuario.getSenha());
            encontrado = !query.getResultList().isEmpty();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return encontrado;
    }

no beanManager(módulo project web) gostaria de fazer uso desses repositórios, só tenho um em declarado, fiz assim:

@Named
@RequestScoped
public class LoginBean implements Serializable {

    @Inject
    private Usuario usuario;
    @Inject
    private UsuarioRepository usuarioRepository;
    @Inject
    private UsuarioLogado usuarioLogado;

    public String makeLogin() {
        boolean loginValido = usuarioRepository.exists(this.usuario);
        if (loginValido) {

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="wspurchaseorder-ejbPU" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>OracleWSPurchaseorderDS</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
      <property name="eclipselink.ddl-generation" value="create-tables"/>
    </properties>
  </persistence-unit>
</persistence>

ele gera erro no momento em que vai criar a query do UsuarioRepository

SEVERE:   java.lang.IllegalStateException: Unable to retrieve EntityManagerFactory for unitName null
	at com.sun.enterprise.container.common.impl.EntityManagerWrapper.init(EntityManagerWrapper.java:138)
	at com.sun.enterprise.container.common.impl.EntityManagerWrapper._getDelegate(EntityManagerWrapper.java:171)
	at com.sun.enterprise.container.common.impl.EntityManagerWrapper.createQuery(EntityManagerWrapper.java:455)
	at br.com.wspurchaseorder.repository.UsuarioRepository.exists(UsuarioRepository.java:56)
	at br.com.wspurchaseorder.view.LoginBean.makeLogin(LoginBean.java:36)
	at br.com.wspurchaseorder.view.LoginBean$Proxy$_$$_WeldClientProxy.makeLogin(Unknown Source)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at com.sun.el.parser.AstValue.invoke(AstValue.java:275)
	at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
	at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
	at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
	at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
	at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
	at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
	at javax.faces.component.UICommand.broadcast(UICommand.java:315)
	at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
	at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
	at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
	at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
	at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
	at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
	at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
	at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
	at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
	at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
	at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
	at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
	at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
	at java.lang.Thread.run(Thread.java:722)

Confere se o persistence.xm está no classes/META-INF, se você tem o beans.xml em ambos projetos (EJB e Web).

Não sei se o Glassfish injeta EJB como se fosse CDI Beans, então se as opções acima não funcionarem, tente injetar os EJBs com @EJB ao invés de @Inject.

Injetei com @EJB meu repository e tenho a seguinte stack:

java.lang.IllegalStateException: 
Exception attempting to inject Remote ejb-ref name=br.com.wspurchaseorder.view.LoginBean/usuarioRepository,
Remote 3.x interface =br.com.wspurchaseorder.repository.UsuarioRepository,
ejb-link=null,
lookup=,
mappedName=,
jndi-name=br.com.wspurchaseorder.repository.UsuarioRepository,
refType=Session into class br.com.wspurchaseorder.view.LoginBean: 
Lookup failed for 'java:comp/env/br.com.wspurchaseorder.view.LoginBean/usuarioRepository' 
in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, 
java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl,
java.naming.factory.url.pkgs=com.sun.enterprise.naming}

Se você usa um módulo EJB, então injete o repositório em um EJB, e chame este EJB no teu JSF bean. Não dá para injetar um @Dependant entre módulos diferentes.

obrigado pela ajuda garcia-jj, vou implementar aqui e testar, vlw por enquanto :slight_smile: assim que sobrar um time prometo ler a spec, abraços.

Obrigado garcia-jj,

era isso mesmo, bastou injetar o repositorio em um EJB e uso esse EJB no webproject, vlw, abraços.

outra forma foi:

criei um facade

criei a interface

/**
 *
 * @author dcunha
 */
@Local
public interface UsuarioFacadeLocal {

    void create(Usuario usuario);

    void edit(Usuario usuario);

    void remove(Usuario usuario);

    boolean exists(Usuario usuario);

    Usuario find(Object id);

    List<Usuario> findAll();

    List<Usuario> findRange(int[] range);

    int count();
}

um user facade

/**
 *
 * @author dcunha
 */
@Stateless
public class UsuarioFacade extends AbstractFacade<Usuario> implements UsuarioFacadeLocal {

    @PersistenceContext(unitName = "wspurchaseorder-ejbPU")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public UsuarioFacade() {
        super(Usuario.class);
    }
}

e um abstract facade

package br.com.wspurchaseorder.facade;

import br.com.wspurchaseorder.entity.Usuario;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;

/**
 *
 * @author dcunha
 */
public abstract class AbstractFacade<T> {

    private Class<T> entityClass;

    public AbstractFacade(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    protected abstract EntityManager getEntityManager();

    public void create(T entity) {
        getEntityManager().persist(entity);
    }

    public void edit(T entity) {
        getEntityManager().merge(entity);
    }

    public void remove(T entity) {
        getEntityManager().remove(getEntityManager().merge(entity));
    }

    public T find(Object id) {
        return getEntityManager().find(entityClass, id);
    }

    public List<T> findAll() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        return getEntityManager().createQuery(cq).getResultList();
    }

    public List<T> findRange(int[] range) {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        q.setMaxResults(range[1] - range[0]);
        q.setFirstResult(range[0]);
        return q.getResultList();
    }

    public int count() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
        cq.select(getEntityManager().getCriteriaBuilder().count(rt));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        return ((Long) q.getSingleResult()).intValue();
    }

    /**
     * <b>Verifica se o usuário existe no banco de dados.</b>
     *
     * @param usuario
     * @return
     */
    public boolean exists(Usuario usuario) {
        boolean encontrado = false;
        try {
            Query query = getEntityManager().createQuery("SELECT u FROM Usuario u WHERE u.login = :uLogin and u.senha = :uSenha");
            query.setParameter("uLogin", usuario.getLogin());
            query.setParameter("uSenha", usuario.getSenha());
            encontrado = !query.getResultList().isEmpty();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return encontrado;
    }
}