2

我一直在将 Hibernate 用于一个项目,但我对它的实际工作原理还有一些疑问。特别是对于持久/分离状态的刷新以及 createQuery、从会话中获取和加载之间的区别。

在以下示例中,“groupe”最初处于持久状态,具有尚未提交的修改值

情况1

// createQuery before evict
// g and groupe point to the same object
Groupe g = (Groupe) session.createQuery("from Groupe as g where g.idGroupe = '" + theid + "'").uniqueResult();
System.out.println("groupe=" + groupe.getTitle()); // modified value
System.out.println("g=" + g.getTitle()); // modified value

session.evict(groupe);
System.out.println("groupe=" + groupe.getTitle()); // modified value
System.out.println("g=" + g.getTitle()); // modified value

session.refresh(groupe);
System.out.println("groupe=" + groupe.getTitle()); // modified value
System.out.println("g=" + g.getTitle()); // modified value

案例#2

// get before evict
// g and groupe point to the same object
Groupe g = (Groupe) session.get(Groupe.class, theid);
System.out.println("groupe=" + groupe.getTitle()); // modified value
System.out.println("g=" + g.getTitle()); // modified value

session.evict(groupe);
System.out.println("groupe=" + groupe.getTitle()); // modified value
System.out.println("g=" + g.getTitle()); // modified value

session.refresh(groupe);
System.out.println("groupe=" + groupe.getTitle()); // value from database
System.out.println("g=" + g.getTitle()); // value from database

案例#3

// load before evict
// g and groupe point to the same object
Groupe g = (Groupe) session.get(Groupe.class, theid);
System.out.println("groupe=" + groupe.getTitle()); // modified value
System.out.println("g=" + g.getTitle()); // modified value

session.evict(groupe);
System.out.println("groupe=" + groupe.getTitle()); // modified value
System.out.println("g=" + g.getTitle()); // modified value

session.refresh(groupe);
System.out.println("groupe=" + groupe.getTitle()); // value from database

System.out.println("g=" + g.getTitle()); // value from database

为什么使用 createQuery 进行刷新操作后会有不同的行为?这是正常行为吗?如果是,有人可以解释其中的区别吗?

感谢您的帮助。

4

1 回答 1

3

答案很简单:

  • 使用查询会导致会话刷新修改。当evict您成为实体时,更改已经保留。
  • 另一方面,通过标识符获取实体不会强制刷新会话。

All three cases are showing value from database after the refresh. Only in the first case it happens that the value from database is the modified value.


If you want the reasoning behind this behavior:

  • Hibernate can not be sure whether a dirty entity is not relevant for the query. For example for modified foo property and query SELECT entity FROM Entity entity WHERE entity.foo = 'BAR' you might get incorrect results if the changes are not flushed before query execution.
  • When you are getting entity by its identifier, Hibernate is able to do a simple lookup inside the session and get the correct entity. There is no need to flush any non-persisted changes.

Hope its clear.

于 2013-10-12T15:39:35.987 回答