Hibernate:session.createQuery和会话缓存

时间:2013-11-25 11:46:58

标签: java hibernate

我拥有的内容:

我在我的应用中集成了State Pattern。这意味着当我改变某个实体的状态时,它可能会引起连锁反应。意味着相关实体的状态也可能发生变化,并且相关实体的状态也会发生变化等等。

我也使用Hibernate conversatetion,这意味着我使用MANUL刷新模式。

public void handler() {
  session = beginHibernateConversation(); //open new transaction and new session (if it's needed)
  entity.changeState(session); //call chain reaction
  finishhibernateConversation(session); //manual flush, commit, and if it's needed - close session
}

出了什么问题:

当我使用手动刷新模式时,所有更改仅在finishhibernateConversation(session)方法上对数据库进行。

我需要在session.createQuery方法中使用changeState(session)方法。但我看不到实际的实体状态!因为所有更改都存储在未刷新的会话中,并且因为session.createQuery与会话上下文无关。

问题:

如何让session.createQuery考虑session cache

一个小例子:

例如,我有Person - Job关系(one-to-many)。当我将一个作业的状态更改为full time时,我需要更新所有其他相关作业(因为此人只能在一个全职工作中工作)。

所以,我做(在UPDATE请求内)

  1. job1.changeState('full time')
  2. [第一种方法内部] session.createQuery("from Job where person.id = (:id) state in (:states)")
  3. 问题是第二个查询不正确,因为它没有考虑job1已经改变的状态

1 个答案:

答案 0 :(得分:1)

这里有几个选项,但这个问题没有简单的改变。

1)使用FlushMode.AUTO。使用自动刷新,Hibernate会在执行查询之前刷新以避免此问题。自动刷新和您正在使用的模式之间不应该有任何冲突,但自动刷新还有其他问题。通常在高度并发的环境中,您可能会遇到此问题,因为它会保留长时间的数据库事务。

2)当您进行这样的查询时,请关闭根对象并在内存中查询。在这个例子中,这就像获取人并迭代其Job集合一样。

3)创建一个ThreadLocal缓存,跟踪您可能查询的内容。这是所有选项中最糟糕的,但有时是必要的。