我拥有的内容:
我在我的应用中集成了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请求内)
job1.changeState('full time')
session.createQuery("from Job where person.id = (:id) state in (:states)")
。 问题是第二个查询不正确,因为它没有考虑job1
已经改变的状态
答案 0 :(得分:1)
这里有几个选项,但这个问题没有简单的改变。
1)使用FlushMode.AUTO
。使用自动刷新,Hibernate会在执行查询之前刷新以避免此问题。自动刷新和您正在使用的模式之间不应该有任何冲突,但自动刷新还有其他问题。通常在高度并发的环境中,您可能会遇到此问题,因为它会保留长时间的数据库事务。
2)当您进行这样的查询时,请关闭根对象并在内存中查询。在这个例子中,这就像获取人并迭代其Job集合一样。
3)创建一个ThreadLocal缓存,跟踪您可能查询的内容。这是所有选项中最糟糕的,但有时是必要的。