有没有一种方法可以在hibernate/grails中刷新实体值,而不需要从数据库中刷新



(示例中我将使用Groovy/Grails语法)

在hibernate中,当一个实体被加载时,它们被保存在会话缓存/L1上,问题是如果在会话外更改,即使我通过GORM方法查询它们,它们也不会被引用。这就是为什么我使用refresh()。

(以下所有操作在一个会话中完成)

User.withNewTransaction {
  User user = User.findById(1L, [lock: true]) //select for update
  user.name='new name' 
  user.save()
}
//user entity gets updated on a different thread.
User.withNewTransaction {
  user = User.findById(1L, [lock: true]) //another select for update
  //at this point, the user entity is not yet filled in with the updated values from the different thread
  //so I'm forced to do a refresh so that the user will have the correct values
  user.refresh()
  //update user
}

有其他选择吗?

这意味着我必须查询两次以确保我们在第二个事务中有正确的值。

是。

直接去掉refresh:

User.withNewTransaction {
  user = User.findById(1L) //user = User.findById(1L, [lock: true]) //another select for update
  //at this point, the user entity is not yet filled in with the updated values from the different thread
  //so I'm forced to do a refresh so that the user will have the correct values
  //user.refresh()
  //update user
}

一个更好的解决方案是放弃事务!由于事务用于批处理操作:

user = User.findById(1L)

如果您希望保留事务语法,那么使用withTransaction:

将其连接到其他正在进行的事务更有意义。
User.withTransaction {
      user = User.findById(1L) //user = User.findById(1L, [lock: true]) //another select for update
      //at this point, the user entity is not yet filled in with the updated values from the different thread
      //so I'm forced to do a refresh so that the user will have the correct values
      //user.refresh()
      //update user
    }

摘要:

您应该很少使用refresh,因为它忽略了hibernate的优点,除非有特殊需要在这里指定

最新更新