注入的EntityManager不了解实体

时间:2014-10-06 14:23:59

标签: hibernate jpa ejb jta glassfish-4

我在Eclipse中定义了一个非常基本的Java EE应用程序(一个EJB,一个带有PrimeFaces的网页,一个JPA实体)。它有四个项目,一个用于EAR,一个用于EJB,一个用于JPA,一个用于Web部件。问题是我试图将Hibernate配置为JPA项目中persistence.xml中的持久性框架,并且它并没有像我期望的那样完全正常工作。在我的EJB(@Stateless)中,我可以通过两种方式检索EntityManager。我可以通过Persistence.createEntityManagerFactory()... entityManagerFactory.createEntityManager()检索它,我可以通过@PersistenceContext(unitName =“”)注释来检索它。但是,只有使用前者才能在查询时识别我的Entity类(使用@Entity注释)。

此代码有效,“Country”实体为(Hibernate)EntityManager所知,我得到了:

final EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("<unit-name>");
final EntityManager entityManager = entityManagerFactory.createEntityManager();
final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Country> criteriaQuery = criteriaBuilder.createQuery(Country.class);
final Root<Country> root = criteriaQuery.from(Country.class);

但是在同一个类中使用注释不起作用(抛出异常,见下文):

@PersistenceContext(unitName = "<unit-name>")
private EntityManager entityManager;
...
final CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
final CriteriaQuery<Country> criteriaQuery = criteriaBuilder.createQuery(Country.class);
final Root<Country> root = criteriaQuery.from(Country.class);

在最后一行抛出异常,“Country”类不是“Entity”。在检查注入的EntityManager时,我可以看到会话中的Country和持久性上下文,但是,它似乎并不知道它。这是抛出的异常:

2014-10-06T16:06:29.634+0200|Severe: java.lang.IllegalArgumentException: Not an entity: class <package>.entity.Country
at org.hibernate.jpa.internal.metamodel.MetamodelImpl.entity(MetamodelImpl.java:203)
at org.hibernate.jpa.criteria.QueryStructure.from(QueryStructure.java:139)
at org.hibernate.jpa.criteria.CriteriaQueryImpl.from(CriteriaQueryImpl.java:173)
at <package>.CountrySessionBean.getCountries(CountrySessionBean.java:35)
...

我在EAR文件中将Hibernate jar包含为“捆绑库”,我也尝试将它们添加到Glassfish的“lib”文件夹中。由于Hibernate适用于上面的第一个实现,我假设它使用正确的jar正确配置。

我的persistence.xml看起来像这样(并且在META-INF下的JPA项目中,反过来又是EAR的一部分):

<?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="<unit-name>" transaction-type="JTA">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

    <jta-data-source>MySQLResource</jta-data-source> <!-- DEFINED IN GLASSFISH -->

    <properties>
        <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.SunONETransactionManagerLookup" /> <!-- NEEDED? -->
        <property name="hibernate.transaction.jta.platform"
            value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform" />

        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />

        ...
    </properties>
</persistence-unit>
</persistence>

供参考:Hibernate v4.3.6,EJB v3.2,Glassfish v4.1,JPA v2.1。

有人能告诉我一些我错过的信息吗?需要一些额外的配置吗?如何告知应用程序Country实体所在的位置?

我认为将@Entity添加到实体会让它注册(当我调用Persistence.createEntityManagerFactory(...)时它会这样做,但是,当通过Java EE / Glassfish注入EntityManager或EntityManagerFactory时。)还尝试将类添加到persistence.xml中无效。当我检查注入的EntityManager时,我可以在其持久化上下文中找到Country类,所以它已经注册了它,但我不能使用该类在查询中。

1 个答案:

答案 0 :(得分:0)

好的,所以看起来这个问题与我以某种方式有两个Entity类的实例有关。这解释了为什么我可以使用查询语言进行查询,但不能使用Entity类本身。我已经将代码跟踪到MetamodelImpl,它在实体映射中查找,但因为它已经注册(正确)的类与criteriaQuery.from()中使用的类不同。我已经在部署了Java EE应用程序的文件夹中搜索了该类的多个实例,但我还没有找到该类本身的多个实例。所以它可能与类加载和/或应用程序包含多个子项目(jpa,web,ejb)这一事实有关,每个子项目都引用了Entity类,或者可能是由于Eclipse的部署方式或它如何构建单独的份...

在任何情况下,问题似乎都不是JPA,Hibernate,EJB等。