Hibernate 升级到 5.2.3 及更高版本的未知实体

Posted

技术标签:

【中文标题】Hibernate 升级到 5.2.3 及更高版本的未知实体【英文标题】:Unknown entity with Hibernate upgraded to 5.2.3 and above 【发布时间】:2017-07-17 12:22:20 【问题描述】:

一旦我升级到 Hibernate 5.2.3 或更高版本,Gradle 就再也找不到我的实体类了:

Caused by: java.lang.IllegalArgumentException: Unknown entity: data.model.User
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:768)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:744)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:749)
    at core.data.model.service.PersistenceService.lambda$create$0(PersistenceService.java:105)
    at core.data.model.service.PersistenceService.withTransaction(PersistenceService.java:156)

Hibernate 5.2.2 及以下版本不会发生这种情况。

这没有解决它:what is gradle missing to map hibernate?。

这是我的用户类:

@Entity
@XmlRootElement
@Table(name = "user")
public class User extends EntityBase 
    // some attributes

和我的 EntityBase 类:

@XmlRootElement
@XmlAccessorType(value = XmlAccessType.NONE)
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
public abstract class EntityBase 
    /**
     * The entity's UUID.
     */
    @Id
    @XmlAttribute
    private String uuid;

    public EntityBase() 
        uuid = UUID.randomUUID().toString();
    

测试有自己的persistence.xml,看起来像这样:

<persistence 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"
             version="2.0">
    <persistence-unit name="PersistenceUnit">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

        <class>data.model.User</class>

        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
            <property name="hibernate.connection.url" value="jdbc:h2:mem:exerciseHandlerTest;DB_CLOSE_DELAY=-1"/>

            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>

            <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>

            <property name="hibernate.transaction.jta.platform"
                      value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>

            <property name="hibernate.show_sql" value="false"/>
            <property name="hibernate.format_sql" value="true"/>
        </properties>
    </persistence-unit>
</persistence>

我在运行测试时也遇到了这个异常:

java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Difficulty is not mapped [select count(difficulty)
from Difficulty difficulty]

这很奇怪,因为只有在运行 Gradle 时才会发生这种情况,没有它一切都很好

更新 1

显然问题与 Gradle 无关,因为我刚刚意识到在 IntellIJ 中运行测试时遇到了这些异常:

java.lang.ExceptionInInitializerError
    at core.test.BaseTest.<init>(NablaTest.java:55)
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
    ...
Caused by: org.hibernate.engine.jndi.JndiException: Error parsing JNDI name [java:comp/env/jdbc/foobar]
    ... 37 more
Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
    ... 47 more

这让我意识到问题是 由于 Hibernate 5.2.3 使用第二个 persistence.xml,仅用于单元测试不起作用

所以我有一个 src/main/resources/META-INF/persistence.xml 和一个 src/test/resources/META-INF/persistence.xml,但它一直从 src/main/... 读取persistence.xml,从版本 5.2.3 开始:(

更新 2

好的,我知道如何重现问题,只是不知道为什么会发生或如何解决。

我有一个使用最新 Gradle 版本的多模块设置。我有一个包含休眠依赖项的 build.gradle 核心模块:

compile "org.hibernate:hibernate-core:5.2.3.Final"

然后是我的单元测试失败的模块:

dependencies 
    // core functionalities
    compile project(":core")
    testCompile project(":core")

    testCompile project(":core").sourceSets.test.output

如果我注释掉最后一行 ("testCompile project(":core").sourceSets.test.output") 它工作正常。

这是为什么呢?

【问题讨论】:

如果您发布您的 User 类及其注释以及您如何注册这些类以供 Hibernate 获取,将会很有帮助;无论是persistence.xml还是一些spring配置等 我假设您只是创建一个User 实例,设置值,然后调用session.save( userInstance ) 我记得我以前遇到过你的问题,但我不确定,无论如何你能告诉我这是否发生在你的 IDE 中,或者当你尝试在 windows 的 cmd 或 linux 的终端中使用命令时? (我的意思是当你构建你的项目时,请使用命令而不是你的 IDE)最后一件事你也可以尝试使用 false 而不是 data.model。用户并检查会发生什么 Naros:或多或少,是的。就像我说的:在以前的 Hibernate 版本中,一切都很好。 @mibrahim.iti:Windows,使用 Gradle(gradlew 检查)发生,在使用 IntelliJ 运行测试时不会发生。这也可能是从 Hibernate 5.2.3 开始出现的 Hibernate 中的错误,但我无法弄清楚可能引入了哪些更改:github.com/hibernate/hibernate-orm/blob/5.2.3/changelog.txt 使用 exclude-unlisted-classes 也不起作用。 有机会定义要扫描的包吗?像 @EntityScan(basePackageClasses=City.class) 注释或通过会话工厂属性一样? 【参考方案1】:

尝试上传到 Hibernate 5.2.9.Final,例如使用 maven,并遵循这个持久性示例:

@Entity
public class Customer 

    @Id
    private Integer id;

    private String name;

    @Basic( fetch = FetchType.LAZY )
    private UUID accountsPayableXrefId;

    @Lob
    @Basic( fetch = FetchType.LAZY )
    @LazyGroup( "lobs" )
    private Blob image;

    public Integer getId() 
        return id;
    

    public void setId(Integer id) 
        this.id = id;
    

    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

    public UUID getAccountsPayableXrefId() 
        return accountsPayableXrefId;
    

    public void setAccountsPayableXrefId(UUID accountsPayableXrefId) 
        this.accountsPayableXrefId = accountsPayableXrefId;
    

    public Blob getImage() 
        return image;
    

    public void setImage(Blob image) 
        this.image = image;
    

【讨论】:

【参考方案2】:

我遇到了同样的情况,但不是同样的错误。测试资源(类、conf 文件等)不应存储在core 的测试部分中,而应存储在独立项目中。

我的解决方案:

    创建一个单独的core-test 项目 将存储在coresrc/test 部分中的可重用代码插入其中(在src/main 中) 在您的模块中,将 testCompile project(":core").sourceSets.test.output 替换为 testCompile project(":core-test")

它应该可以解决您的问题。

【讨论】:

以上是关于Hibernate 升级到 5.2.3 及更高版本的未知实体的主要内容,如果未能解决你的问题,请参考以下文章

centos6.8上PHP5.3升级到PHP5.4及更高版本方法

SASS-LOADER 版本 8.0.0 及更高版本

Fody 仅在 MSBuild 16 及更高版本上受支持。当前版本:15

phpunit 8 及更高版本中设置套件的问题

如何在 Xcode 7 Beta 5 中安装 iOS 7 及更高版本的模拟器?

iOS 7 及更高版本 (8.4) 中不推荐使用 SegmentedControlStyle | Xcode 6.4