我有 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 编写的,而不是合并,所以我真的需要它来与现有代码一起使用。
有人可以帮忙吗?
不,如果您使用executeUpdate,Envers 将无法工作。那是因为更新没有通过 Hibernate 的事件机制,所以 Envers 没有机会拦截更改并编写审计。
看起来 Avinash T. 是对的 - 如果你想创建原生 SQL 查询,请使用
createNativeQuery(String sqlString)
的 EntityManager
方法。仅当您使用 EJB QL 时才可以使用 createQuery(String ejbqlString)
。希望它会有所帮助。
试试这个 -
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 的更多信息 -
我还需要更新实体的单个字段。如果您不需要直接使用
EntityManager
,在我的例子中,Envers 意识到实体状态更改的解决方案是用 @Entity
注释我的 @DynamicUpdate
类,并用 @Transactional
包装设置我想要更新的字段的方法。
看到这个答案:使用 spring data jpa 更新单个字段
检查
@DynamicUpdate
注释的 Hibernate 代码:
org.hibernate.persister.entity.mutation.UpdateCoordinatorStandard#coordinateUpdate
但请注意,使用
@DynamicUpate
可能会产生一些性能成本:
指定带注释的实体的 SQL 更新语句是 动态生成,并且只包含实际的列 正在更新。如果是的话,这可能会提高性能 通常仅更改实体的某些属性。然而, 在运行时生成 SQL 会产生相关成本