EntityManager未在无状态会话Bean

时间:2015-05-06 14:53:22

标签: java-ee ejb jboss7.x entitymanager

我一直在查看很多类似的问题,这些问题并没有反映出我的确切问题。如果我忽略了某人已经解决了这个问题,请告诉我。

我目前正在JBoss 3.x上将旧的EJB 2.1应用程序迁移到JBoss 7.x上的EJB 3.x.由于应用程序客户端和服务器之间的通信发生了变化,我创建了一个小的测试客户端来检查陷阱。

其中一个是我的无状态会话bean中的实体管理器未注入,使EntityManager保持为NULL。我尝试使用EntityManagerFactory解决这个问题,但都没有注入。 引用的数据源可用,并且已针对数据库测试连接。

我希望你们中的一些人遇到过这个问题,可以想到我可以在下一步看哪,或者我可以做些什么来追踪这个问题。 附上来自服务器端的persistence.xml,RemoteInterface和Bean代码以及我的测试客户端代码。

如果我能提供更多信息,请告诉我。 (这些类大部分都是从EJB 2应用程序中保留其名称,以防您想知道)。

无状态会话Bean(GUITabUsersDao):

@Stateless
@Remote(GUITabUsersDaoRemote.class)
public class GUITabUsersDao implements GUITabUsersDaoRemote {
    Logger logger = Logger.getLogger(GUITabUsersDao.class.getName());

    @PersistenceContext(name = "OracleGUIDS", type =   PersistenceContextType.TRANSACTION)
    EntityManager entityManager;

    @Override
    public List<GUITabUsers> findAll() throws FinderException {
         List<GUITabUsers> resultList = null;
         TypedQuery<GUITabUsers> namedQuery;
         if (entityManager == null) {
             logger.severe("**** CKU: This is not going to end well. entitymanager is null. :( ****");
         } else {
            namedQuery = entityManager.createNamedQuery(GUITabUsers.FIND_ALL, GUITabUsers.class);
            resultList = namedQuery.getResultList();
        }
        return resultList;
    }
}

远程接口

public interface GUITabUsersDaoRemote {
    List<GUITabUsers> findAll() throws FinderException;
}

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="OracleGUIDS" transaction-type="JTA">
        <jta-data-source>java:jboss/datasources/OracleGUIDS</jta-data-source>
        <class>de.printcom.loginmodule.GUITabUsers</class>
        <properties>
            <!-- Properties for Hibernate  -->
            <property name="hibernate.hbm2ddl.auto" value="verify"/>
            <property name="hibernate.show_sql" value="false"/>
        </properties>
    </persistence-unit>
</persistence>

客户端代码

package de.my.test;

public class TestClient {
    public static final String URL = "localhost";
    public static final String PORT = "4447";

    private static final Logger LOGGER = Logger.getLogger(TestClient.class.getName());

    public static void main(String[] args) {
        IDPLookupRemote bean;
        LAEC_MachineControlSES bean2;
        GUITabUsersDaoRemote guiTabUsersDao;
        try {
            EJBHomeFactory factory = EJBHomeFactory.getInstance(URL, PORT);
            guiTabUsersDao = (GUITabUsersDaoRemote) lookup("GUITabUsersDao", GUITabUsersDaoRemote.class);
            LOGGER.info("Bean '" + guiTabUsersDao.toString() + "' received.");
            List<GUITabUsers> col = null;
            try {
                col = guiTabUsersDao.findAll();
            } catch (FinderException | NullPointerException e) {
                e.printStackTrace();
            }
            if (null != col) {
                LOGGER.info(col.get(0).toString());
            } else {
                LOGGER.info("Col is empty!");
            }
        } catch (NamingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static Object lookup(String jndiName, Class<?> remoteInterfaceClass) throws NamingException {
        Object object = new Object();
        try {
            Properties properties = new Properties();
            properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
            properties.put("jboss.naming.client.ejb.context", true);
            properties.put(Context.PROVIDER_URL, "remote://" + URL + ":" + PORT);
            Context context = new InitialContext(properties);
            final String appName = "appName";
            final String moduleName = "moduleName";
            final String distinctName = "";
            final String beanName = jndiName;
            final String viewClassName = remoteInterfaceClass.getName();
            LOGGER.info("Looking EJB via JNDI ");
            String jndiLookupName = appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + viewClassName;
            LOGGER.info(jndiLookupName);
            object = context.lookup(jndiLookupName);
            LOGGER.info("Calling 'context.lookup(" + jndiLookupName + ")'");
            // object = context.lookup(jndiName);
        } catch (NamingException e) {
            e.printStackTrace();
        }
        return object;
    }
}

1 个答案:

答案 0 :(得分:2)

正如BalusC和jgitter所建议的那样,这是我之前编辑的答案:

如果你遇到类似的问题,请随意为下面提到的问题愚蠢地洗澡。

在我需要从JBoss 3.x迁移到7.x的应用程序中,许多项目被抛在了一起。其中一个项目在persistence.xml中声明了两个持久性单元,而无状态会话Bean都声明为与此类似:

@Stateless
@Remote(SomeStatelessRemote.class)
public class SomeStatelessBean implements SomeStatelessRemote {

    @PersistenceContext(name = "OracleGUIDS")
    EntityManager entitymanager;
    ...
}

现在,如果您部署它,您将收到错误消息

JBAS011470: Persistence unitName was not specified

在某些论坛中有人建议禁用独立的特定子系统

<subsystem xmlns="urn:jboss:domain:jpa:1.1">
   <jpa default-datasource="" default-extended-persistence-inheritance="DEEP"/>
</subsystem>

正如您所看到的,这将禁用任何使用JPA的可能性。

现在我启用了子系统并使用了正确的语法来注入entitymanager:

@Stateless
@Remote(SomeStatelessRemote.class)
public class SomeStatelessBean implements SomeStatelessRemote {

    @PersistenceContext(unitName= "OracleGUIDS")
    EntityManager entitymanager;
    ...
}

并且,哦,我想知道,我能够访问实体经理并拥有它。 感谢大家全力以赴帮助我。 希望此条目可以帮助您避免此错误。