更改实体字段时如何使 HSQL 不自动更新实体

Posted

技术标签:

【中文标题】更改实体字段时如何使 HSQL 不自动更新实体【英文标题】:How to make HSQL not auto update entity when change entity's field 【发布时间】:2018-11-02 00:44:06 【问题描述】:

我有一个实体,每当我编辑它的字段时,HSQL 会立即更新该实体。

下面的代码

System.out.println(userService.findById(user.getId()).getPassword());

user.setPassword("password");

System.out.println(userService.findById(user.getId()).getPassword());

userService.update(user);

System.out.println(userService.findById(user.getId()).getPassword());

在控制台中打印出来

qwerty
password
password

这意味着即使在我使用update() 之前,实体已经更新了。

我该如何阻止它?因此,该实体只能在调用该方法时更新,而不能在您更改其字段时更新。

休眠配置:

jdbc.driverClassName=org.hsqldb.jdbc.JDBCDriver
jdbc.url=jdbc:hsqldb:mem:myDb
jdbc.username=sa
jdbc.password=sa
hibernate.dialect=org.hibernate.dialect.HSQLDialect
hibernate.hbm2ddl.auto=create

【问题讨论】:

【参考方案1】:

我假设您围绕以下代码打开了一个事务:

System.out.println(userService.findById(user.getId()).getPassword());
user.setPassword("password");
System.out.println(userService.findById(user.getId()).getPassword());
userService.update(user);
System.out.println(userService.findById(user.getId()).getPassword());

发生的情况是 Hibernate 获取实体,并且由于它仍在事务中,因此实体是休眠托管实体,因此对实体的任何更改(例如 user.setPassword(...) 将导致这些更改被刷新到数据库.

如果您只是将 userService 设为事务性(即从示例代码中删除事务并将 userService 注释为 @Transactional(假设您使用的是 Spring)),那么当您执行 user.setPassword(...) 时,它将在事务,更改不会持续。

或者,您可以通过调用 EntityManager::detach 方法强制实体分离(使其不再受管理)。

有关其他上下文,请阅读以下链接中的第 3.5 节:https://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/objectstate.html

【讨论】:

是的,你是对的。我的 UserService 用@Transactional 注释,而我使用我展示的代码的类也用@Transactional 注释。在第二堂课中删除注释对我有帮助。谢谢!

以上是关于更改实体字段时如何使 HSQL 不自动更新实体的主要内容,如果未能解决你的问题,请参考以下文章

核心数据-后台线程中的更新实体会自动更改主线程中的 NSManagedObject 而无需合并-为啥?

RESTful API:更新实体产生副作用时返回的内容

EF-实体更新

使用T4模板为EF框架添加实体根据数据库自动生成字段注释的功能

如何解决mybatis-plus调用update方法时,自动填充字段不生效问题

如何使用更新的 JPA 时间戳字段升级数据库?