【问题标题】:Get original entity triggered the Hibernate Event获取触发休眠事件的原始实体
【发布时间】:2019-05-06 12:38:41
【问题描述】:

我在 Hibernate 之上使用带有 JPA 2 的 Spring Boot 2。我想记录一些审计信息,但不仅针对实际实体,还针对父实体。

例如:我有一个Employee 实体,它有一个Address 实体。因此,如果 Address 实体发生更改,我还想记录 Employee 已更改。 Employee 是即使不脏也被保存的实体。

我发现了一些类似的问题: Hibernate versioning parent entity 这仅在子实体知道父实体时才有效。

我还发现了这个:https://thoughts-on-java.org/hibernate-tips-increase-version-parent-entity-updating-child-entity/ 这个解决方案是针对一个案例的具体实现,但我想要一个通用的解决方案。

我的想法是找到原始实体,如果它的任何子实体是脏的,那么也标记原始实体。

【问题讨论】:

    标签: hibernate spring-data-jpa


    【解决方案1】:

    我几乎遇到了同样的问题。我希望拥有实体的“lastModifiedDate”和“Version”字段在子实体更改时更新。我正在使用 Spring Data JPA 审计。

    我已经测试了很多东西并实现了很多自定义代码。甚至我也在尝试实现自定义脏检查机制。我能够通过遵循此blog post 来修复父版本控制,但对审计没有任何作用。

    最后,使用 Hibernate Bytecode Enhancement Maven 插件 并启用 DirtyTracking 为我解决了父版本控制和审核的问题。现在,当我编辑孩子时,拥有实体的“lastModifiedDate”和“version”会自行更新,并且没有任何自定义代码。请记住,我只测试了 ManyToOne/OneToMany 关系,但我认为这也适用于其他关系。另外,我正在通过 JpaRepository(使用 Spring Data)从拥有方更新实体

    要启用休眠字节码增强,请将此插件添加到您的 POM 文件中:

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

    现在,当您查找“目标”文件夹时,实体现在通过使用 SelfDirtinessTracker 实现 ManagedEntity 和 SelfDirtinessTracker,实体跟踪脏字段,无需休眠检查所有实体以查找脏那些。除了为我修复父审计和版本控制之外,这还可以提高性能。希望它也能解决您的问题。

    【讨论】:

      【解决方案2】:

      我欺骗了系统。每次我更改/删除/添加一个 OneToMany 子实体时,我都会调用entity.setLastModifiedDate(myDateProvider.now())

      这使我的父实体变脏了,Hibernate 增加了版本,我从 AuditorAware 获得了新的、正确的 lastModifiedDate 和 lastModifiedBy 值。

      对于这个问题,它可能是一个简单、快速和肮脏的单行解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-27
        相关资源
        最近更新 更多