首页 > 解决方案 > Hibernate Interceptor 映射表数据不正确

问题描述

我有一个使用连接表的多对多映射。

@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "access_management")
public class AccessMgmt
    extends CommonColumns
    implements Serializable {

@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
@JoinTable(
        name = "access_management_role_mapping",
        joinColumns = @JoinColumn(name = "access_management_id"),
        inverseJoinColumns = @JoinColumn(name = "roles_id"))
@CsvBindByName(column = "roles")
private List<Role> roles = new ArrayList<>();

}

当数据更新(onFlushDirty)时,previousState 和 currentState 包含完全相同的数据,用于 ManyToMany 字段(这应该只在 currentState 中)。我认为连接映射表发生了一些事情,因为我没有该表的实体(access_management_role_mapping)它正在更新并且没有命中拦截器,然后父对象(access_management)在之后命中拦截器更新。只是一个怀疑,但它是这样的,因为非审计日志表中的所有数据都是正确的。

public class AuditLogInterceptor extends EmptyInterceptor {

@Override
public boolean onFlushDirty(
        final Object entity, final Serializable id,
        final Object[] currentState, final Object[] previousState,
        final String[] propertyNames, final Type[] types) {
... }
}

第二个问题是我真的只希望“父”实体命中拦截器,并让它们的 previousState 和 currentState 是“正确”的对象命中自定义拦截器。正确我的意思是在previousState和currentState中拥有完整的对象,currentState在当前设置中始终是正确的。目前具有 OneToMany 映射的表让每个实体单独命中拦截器,这很好,但最终父对象(用户保存/编辑的那个)最后命中拦截器,并且对于任何映射字段(OneTo),previousState 的数据都不正确..ManyTo..等)

我可以添加更多代码,但我认为其中大部分是不必要的。

我想我可以通过做一些事情来解决这个问题。

  1. 使用 envars... - (不,谢谢,这意味着完全重写这部分。)
  2. 将 ManyToMany 更改为 OneToMany 并将映射表创建为实体并在拦截器中进行处理。(如果我也有,但不能解决我的第二个问题)
  3. 添加父对象的瞬态以使用 @PreLoad 保存先前的状态,因此我始终拥有先前的状态。(这解决了这两个问题,但似乎是一件奇怪的事情,但如果这里有人没有更好的主意,我会怎么做。)(如何在不使用休眠拦截器从数据库获取的情况下获取previouseState来创建审计跟踪表? )

更新

选项 3 没有按我的预期工作,也没有得到我当时想要的数据。所以就这样了。

我还尝试使用 Hibernate Event Listeners 而不是具有相同结果的拦截器。

最终我可能需要在没有休眠的情况下实现这一点,并在控制器级别进行。

标签: javahibernatehibernate-mappinginterceptor

解决方案


推荐阅读