【问题标题】:When do I see updates on hibernate entities?我什么时候可以看到休眠实体的更新?
【发布时间】:2020-11-17 18:10:00
【问题描述】:

假设我正在使用 spring 和 hibernate,并且我在我的一种事务服务方法中执行以下操作。打印的预期结果是什么?更重要的是为什么?

// user1 perviously has some other name then x
User userInstance = userDAO.findById(1);
userInstance.setName("x");
System.out.println(userDAO.findById(1).getName());

userDAO.save(userInstance);
System.out.println(userDAO.findById(1).getName());

我是否总是希望看到我对查询的用户实体所做的更改?为什么?这究竟是如何与休眠代理和一级缓存交互的?

感谢您的任何见解!

【问题讨论】:

    标签: java spring hibernate


    【解决方案1】:

    在同一个会话中,Hibernate 会使用一级缓存来保证同一个实体(由同一个主键标识)总是由同一个对象实例表示。 这意味着在您关闭会话之前,无论您是与引用的实体 userInstance 交互还是通过 Hibernate 和 userDAO.findById(1) 进行交互,您都将始终引用完全相同的对象实例。

    所以要回答您的问题,打印结果将是: X x

    【讨论】:

    • 真的是这样吗?我一直认为hibernate肯定会缓存数据,但我不知道它实际上也总是引用下面的相同对象实例。
    • 在同一个会话中是的,在我们刷新或提交事务之前,我们总是引用同一个持久上下文存储。这将使会话查找任何脏实体并将它们同步到数据库。
    【解决方案2】:

    我假设第 2 行应该使用userInstance 而不是userInstance1。我想你会在执行第 3 行(如下)时看到刷新到数据库的更新:

    System.out.println(userDAO.findById(1).getName());
    

    原因是您在内存中有一个未保存但已更新的版本,因此它被视为“脏”。当您重新读取同一个对象(基于 ID)时,hibernate 会在重新读取之前先将更新的对象刷新到数据库中。

    【讨论】:

    • 感谢您的洞察力!但正如我在问题中提到的,这将在 @transactional 方法中。这对我来说意味着在方法返回并提交事务之前不会执行任何 db 语句,还是我错了?
    猜你喜欢
    • 1970-01-01
    • 2018-10-24
    • 2013-07-24
    • 2011-12-15
    • 2020-02-16
    • 2019-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多