实际上,Chris Landry 的“解释”博客错过了 SQLQuery 的 3 个重要 API 方法,这就是他遇到这些问题的原因。具体来说,(1) addSynchronizedQuerySpace,(2) addSynchronizedEntityName 和 (3) addSynchronizedEntityClass
正如 partenon 所指出的,仅仅基于 SQL 查询字符串本身,Hibernate 无法知道查询中查询了哪些表和/或实体。因此,它不知道 Session 中排队的哪些更改需要刷新到数据库。在博客中,Chris 确实指出您可以在运行 SQL 查询之前自行执行 flush() 调用。但是,我所描述的是 Hibernate 的自动刷新功能。它实际上对 HQL 和 Criteria 查询做同样的事情。只有在那里它知道受到影响的表。无论如何,这个自动刷新过程会执行“最小刷新”,仅刷新影响查询的内容。这就是这些方法发挥作用的地方。
例如,Chirs 的 SQL 查询是
session.createSqlQuery("select name from user where name = :userName")
他真正需要做的就是说……
session.createSqlQuery("select name from user where name = :userName")
.addSynchronizedQuerySpace( "user" )
addSynchronizedQuerySpace( "user" )
告诉 Hibernate 查询使用了一个名为“user”的表。现在 Hibernate 可以自动刷新映射到该用户表的实体的所有未决更改。