EntityManager在EJB中为null

时间:2018-01-11 10:59:40

标签: jpa java-ee ejb

我的客户端在Tomcat上运行,Server在Wildfly 11上运行。

EJB是:

package dao;

import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import model.User;

@Stateless
public class UserDaoImpl implements UserDao {
@PersistenceContext(unitName = "nju")
protected EntityManager em;

@Override
public String login(String userName, String password) {
    try {
        Query query = em.createQuery("from User u where u.userName='" + userName + "'");
        @SuppressWarnings("unchecked")
        List<User> list = query.getResultList();
        em.clear();
        if (list.isEmpty()) {
            return "failure";
        } else if (list.get(0).getPassword().equals(password)) {
            return "success";
        }
    } catch (Exception e) {
        e.printStackTrace();
        return "failure";
    }
    return "failure";
}
}

的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="nju">
    <description>This unit manages users.</description>
    <jta-data-source>java:/MySqlDS</jta-data-source>
    <properties>
        <property name="showSql" value="true" />
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
    </properties>
</persistence-unit>

当我运行服务器时,输出包含

18:53:38,997 INFO [org.jboss.as.clustering.infinispan] (ServerService Thread Pool -- 62) WFLYCLINF0002: Started client-mappings cache from ejb container 18:53:39,005 INFO [org.jboss.as.jpa] (ServerService Thread Pool -- 62) WFLYJPA0010: Starting Persistence Unit (phase 2 of 2) Service 'J2EEServer.war#nju'

所以persistence.xml的位置没有错。

但是,当我运行客户端并在EJB中调用该函数时。存在NullPointerException,表示未注入实体管理器。

在客户端我使用工厂来获取EJB。方法是

private static Object getEJB(String JNDIPath) {
    Hashtable<String, String> jndiProperties = new Hashtable<>();
    jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
    try {
        Context context = new InitialContext(jndiProperties);
        return context.lookup(JNDIPath);
    } catch (NamingException e) {
        e.printStackTrace();
    }
    return null;

}

异常仅在wildfly上显示,当它出现时,tomcat消息是

 org.jboss.ejb.client.EJBClient <clinit>
INFO: JBoss EJB Client version 2.1.4.Final
org.xnio.Xnio <clinit>
INFO: XNIO version 3.4.0.Final
org.xnio.nio.NioXnio <clinit>
INFO: XNIO NIO Implementation Version 3.4.0.Final
org.jboss.remoting3.EndpointImpl <clinit>
INFO: JBoss Remoting version 4.0.21.Final
org.jboss.ejb.client.remoting.VersionReceiver handleMessage
INFO: EJBCLIENT000017: Received server version 3 and marshalling strategies [river]
org.jboss.ejb.client.remoting.RemotingConnectionEJBReceiver associate
INFO: EJBCLIENT000013: Successful version handshake completed for receiver context EJBReceiverContext{clientContext=org.jboss.ejb.client.EJBClientContext@51e6ae57, receiver=Remoting connection EJB receiver [connection=org.jboss.ejb.client.remoting.ConnectionPool$PooledConnection@5281b661,channel=jboss.ejb,nodename=microwin10-115]} on channel Channel ID 8d8bb52c (outbound) of Remoting connection 3607d423 to localhost/127.0.0.1:8080 of endpoint "client-endpoint" <41cb456e>
org.jboss.ejb.client.remoting.ChannelAssociation$ResponseReceiver handleEnd
INFO: EJBCLIENT000016: Channel Channel ID 8d8bb52c (outbound) of Remoting connection 3607d423 to localhost/127.0.0.1:8080 of endpoint "client-endpoint" <41cb456e> can no longer process messages

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

我终于找到了解决方案!!

在我的项目中,我之前的服务代码是

@Stateless
public class UserServiceImpl implements UserService {

private UserDao userdao=Factory.getUserDao();

@Override
public String login(String userName, String password) {
    return userdao.login(userName, password);
}

@Override
public String register(User user) {
    return userdao.register(user);
}

}

在工厂中,我使用new UserDaoImpl()获取对象。这是个问题!

如果以这种方式使用对象,则不会注入EntityManager。

所以我删除了工厂并更改了服务中的代码

@Stateless
public class UserServiceImpl implements UserService {
/**
 * Will be injected
 */
@EJB
private UserDao userdao;

@Override
public String login(String userName, String password) {
    return userdao.login(userName, password);
}

@Override
public String register(User user) {
    return userdao.register(user);
}

}

完美无缺。