【问题标题】:EntityManager not injected in Stateless Session BeanEntityManager 未注入无状态会话 Bean
【发布时间】:2015-05-06 14:53:22
【问题描述】:

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

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

其中之一是我的无状态会话 bean 中的 entitymanager 没有被注入,而 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;
    }
}

【问题讨论】:

  • 我不想问这个明显的问题,但是你确定持久化上下文是在启动时成功创建的吗?日志中有错误吗?
  • 我确信在显示的日志文件中没有错误。此外,它指出我的所有数据源都已部署。我还将 org.jboss.as.jpa 设置为 TRACE 日志级别,希望能发现任何错误。会不会是不喜欢 -ds.xml 文件?
  • 除了提高 JPA 的日志级别之外,尝试设置日志级别以跟踪实现。我假设你正在使用休眠?
  • 我尝试使用 Persistence.createEntityManagerFactory 手动创建 EntityManagerFactory,但该工厂失败了,但出现了一个巨大的异常,指出没有 PersistenceContext OracleGUIDS(正如您已经假设的那样)。是的,我正在使用hibernate,或者至少我认为我是因为我没有进行其他配置,并且hibernate应该是JBoss的默认设置。我正在使用 JBoss EAP 6.4,偶然发现了standalone.xml 和standalone-full.xml 的用法。这可能是我所有麻烦的原因吗?
  • 我在家里玩过它,似乎我自己挖了一个洞。我敢肯定,这对我来说将是一种耻辱。摘要将添加到问题中。随意投反对票。 :(

标签: jakarta-ee ejb jboss7.x entitymanager


【解决方案1】:

正如 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 的可能性。

现在我启用了子系统并使用正确的语法来注入实体管理器:

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

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

而且,哦,奇怪的是,我能够访问 entitymanager 并拥有它。 感谢每一位辛勤工作来帮助我的人。 希望这篇文章能帮助您避免这个错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-26
    • 1970-01-01
    • 2011-03-31
    相关资源
    最近更新 更多