Hibernate Envers - 不为 createQuery(...).executeUpdate() 写入审核记录,仅为 .persist() 和 .merge()

问题描述 投票:0回答:4

我有 3 种将内容写入数据库的方法

public void create(T object) {
    entityManager.persist(object);
}

public void update(T object) {
    object = entityManager.merge(object);
}

public int updateStatus(String id, String status) {

    final int changes =
                entityManager.createQuery("update item set state = :newState," +
                        " last_modified = current_timestamp" +
                        " where id = : id ")
                    .setParameter("newState", status)
                    .setParameter("id", id)
                    .executeUpdate();

            return changes;
}

我遇到的问题是为了让 Hibernate Envers 将审计记录实际写入相应的 x_aud 和 revinfo DB 表。它仅适用于“.persist()”或“.merge()”。我无法让它为 'createQuery(...).executeUpdate()'

工作

我是否遗漏了什么,或者它对此不起作用。问题是,我的很多代码都是使用 .executeUpdate 编写的,而不是合并,所以我真的需要它来与现有代码一起使用。

有人可以帮忙吗?

java spring hibernate jboss hibernate-envers
4个回答
10
投票

不,如果您使用executeUpdate,Envers 将无法工作。那是因为更新没有通过 Hibernate 的事件机制,所以 Envers 没有机会拦截更改并编写审计。


3
投票

看起来 Avinash T. 是对的 - 如果你想创建原生 SQL 查询,请使用

createNativeQuery(String sqlString)
EntityManager
方法。仅当您使用 EJB QL 时才可以使用
createQuery(String ejbqlString)
。希望它会有所帮助。


3
投票

试试这个 -

    public int updateStatus(String id, String status) {

    final int changes =
                entityManager.createQuery("Update Item set state = :newState," +
                        " lastModified = CURRENT_TIMESTAMP" +
                        " where id = : id ")
                    .setParameter("newState", status)
                    .setParameter("id", id)
                    .executeUpdate();

            return changes;
}

以下链接将帮助您了解有关 JPQL 的更多信息 -

http://docs.oracle.com/javaee/6/tutorial/doc/bnbtg.html


0
投票

我还需要更新实体的单个字段。如果您不需要直接使用

EntityManager
,在我的例子中,Envers 意识到实体状态更改的解决方案是用
@Entity
注释我的
@DynamicUpdate
类,并用
@Transactional
包装设置我想要更新的字段的方法。

看到这个答案:使用 spring data jpa 更新单个字段

检查

@DynamicUpdate
注释的 Hibernate 代码: org.hibernate.persister.entity.mutation.UpdateCoordinatorStandard#coordinateUpdate

但请注意,使用

@DynamicUpate
可能会产生一些性能成本:

指定带注释的实体的 SQL 更新语句是 动态生成,并且只包含实际的列 正在更新。如果是的话,这可能会提高性能 通常仅更改实体的某些属性。然而, 在运行时生成 SQL 会产生相关成本

© www.soinside.com 2019 - 2024. All rights reserved.