如何为字节码增强设置Hibernate Gradle插件?

9
Hibernate Gradle插件是hibernate-enhance-maven-plugin的等效物,提供构建时代码增强。官方文档没有提到apply plugin:'something'这一行。如果我按照指南所说去做,我会得到如下错误信息:

Could not find method hibernate() for arguments...

我尝试了猜测插件的名称,使用了apply plugin:'enhance'(如这个线程所建议)和apply plugin:'org.hibernate.orm'(如这个测试所建议),但都提示该id对应的插件未知。

有人成功地设置了这个插件吗?

我的build.gradle如下:

allprojects {
    group 'xxx'
    version '1.0-SNAPSHOT'
}

subprojects {
    apply plugin: 'java'

    sourceCompatibility = 1.8

    repositories {
        mavenLocal()
        mavenCentral()
    }

    dependencies {
        ...
    }
}

project(':xxx-model') {
    buildscript {
       repositories {
           mavenLocal()
           mavenCentral()
       }
       dependencies {
           classpath "org.hibernate:hibernate-gradle-plugin:5.0.7.Final"
       }
    }

    apply plugin: 'org.hibernate.orm'

    hibernate {
        enhance {}
    }
}

... more unrelated project blocks here

尝试将 buildscript{...} 移动到根目录、allprojectssubprojects 中,但没有任何有用的结果。

3个回答

16

对于Gradle

一个完整的示例看起来像这样:

apply plugin: 'java'

repositories {
    mavenLocal()
    mavenCentral()
}

buildscript {
    repositories {
        mavenLocal()
        mavenCentral()
    }
    dependencies {
        classpath "org.hibernate:hibernate-gradle-plugin:$hibernateVersion"
    }
}

apply plugin: 'org.hibernate.orm'

hibernate {
    enhance {
        enableLazyInitialization= true
        enableDirtyTracking = true
        enableAssociationManagement = true
    }
}

dependencies {
    compile 'org.hibernate:hibernate-core:$hibernateVersion'
}

对于Maven

<plugin>
    <groupId>org.hibernate.orm.tooling</groupId>
    <artifactId>hibernate-enhance-maven-plugin</artifactId>
    <version>${hibernate.version}</version>
    <executions>
        <execution>
            <configuration>
                <enableLazyInitialization>true</enableLazyInitialization>
                <enableDirtyTracking>true</enableDirtyTracking>
                <enableAssociationManagement>true</enableAssociationManagement>
                <enableExtendedEnhancement>false</enableExtendedEnhancement>
            </configuration>
            <goals>
                <goal>enhance</goal>
            </goals>
        </execution>
    </executions>
</plugin>

在设置增强插件后,Hibernate会重新编译实体类并更改字节码如此

public void setDetails(PostDetails details) {
    this.$$_hibernate_write_details(details);
}
 
public void $$_hibernate_write_details(PostDetails details) {
    if (!Objects.deepEquals(details, this.details)) {
        this.$$_hibernate_trackChange("details");
    }
 
    this.details = details;
}

public void $$_hibernate_trackChange(String property) {
    if (this.$$_hibernate_tracker == null) {
        this.$$_hibernate_tracker = new SimpleFieldTracker();
    }
 
    this.$$_hibernate_tracker.add(property);
}

$$_ 方法是特定于 Hibernate 的方法,包含实体仪表化逻辑。


嗨,使用hibernate-core,我需要以下依赖项:hibernate-entitymanagerhibernate-validatorhibernate-validator-annotation-processorhibernate-commons-annotationshibernate-jpa-2.1-apihibernate-ehcache吗? - Arash
这些依赖项就像插件一样,它们提供额外的功能。 - Vlad Mihalcea
谢谢 Vlad,我怎么知道我是否需要它们,或者 hibernate-core 就足够了? - Arash
Hibernate用户指南解释了每个模块的目标。希望您能像我写作时一样享受阅读它。 - Vlad Mihalcea
对于Gradle用户,请使用implementation代替compile,因为它已经被标记为@Depricated - stefan-dan

5
apply plugin: 'org.hibernate.orm'

插件代码表示您从测试中获得的内容是正确的。您可能缺少的是在buildScript部分内部添加一个repositories部分,以从中获取插件jar包。

我也试过这个,只是得到了“未找到ID为...的插件”。你在我的gradle.build文件中看到了任何配置错误吗?与此同时,我会再试一次。 - kaqqao
在你的 build.gradle 文件中,你把 apply plugin: 'org.hibernate.orm' 放在哪里? - RaGe
1
只有当我将整个插件配置放入子项目的build.gradle中时,它才能正常工作。如果插件配置位于根build.gradle下的project(':xxx-model')中,就像问题中所示,它会显示找不到插件。顺便说一句,我编辑了问题以展示我通常会放置apply plugin: 'org.hibernate.orm'的位置。 - kaqqao
请注意,当 https://hibernate.atlassian.net/browse/HHH-13354 得到解决时,我们可以使用更新的插件语法。 - debuglevel

4
官方文档(从5.1开始)的字节码增强实际上是用户指南。该文档仍未提及应用此插件,因为我们假设使用Gradle需要一些基本知识 ;) 但最好让用户指南部分也指定如何应用插件(我在Jira中创建了一个问题)。

同时,插件的ID名称是org.hibernate.orm,因此您需要添加:

apply: 'org.hibernate.orm'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接