首页 文章

注入的EntityManager不知道实体

提问于
浏览
0

我有一个在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

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

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

相关问题