休眠:刷新分离的对象-怪异的行为

Wendannor

我一直在将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进行刷新操作后会有不同的行为?这是正常现象吗?如果是,有人可以解释其中的区别吗?

谢谢您的帮助。

帕维尔·霍拉尔(Pavel Horal)

答案很简单:

  • 使用查询会导致会话刷新修改。evict您发起请求时,更改已被保留。
  • 另一方面,通过其标识符获取实体不会强制刷新会话。

所有这三种情况都在结束后显示了数据库的价值refresh仅在第一种情况下,数据库中的值为修改后的值


如果您想要这种行为背后的原因:

  • Hibernate不能确定脏实体是否与查询无关。例如,对于修改后的foo属性和查询SELECT entity FROM Entity entity WHERE entity.foo = 'BAR',如果在执行查询之前未刷新更改,则可能会得到错误的结果。
  • 当通过其标识符获取实体时,Hibernate能够在会话内部进行简单的查找并获取正确的实体。无需刷新任何非持久性更改。

希望它清除。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章