我拥有的:
我已将状态模式集成到我的应用程序中。这意味着当我改变某个实体的状态时,可能会引起链式 react 。意味着相关实体的状态也可能发生变化,并且比相关实体的状态到那些实体的状态等等。
我还使用 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)
方法上对数据库进行。
我需要在 changeState(session)
方法中使用 session.createQuery
方法。但我看不到实际的实体状态!因为所有更改都存储在未刷新的 session 中,并且 session.createQuery
与 session 上下文无关。
问题:
如何让session.createQuery
考虑 session 缓存
?
一个小例子:
例如,我有 Person
- Job
关系(一对多
)。当我将一项工作的状态更改为全职
时,我需要更新所有其他相关工作(因为一个人只能从事一项全职工作)。
所以,我愿意(在人更新请求内)
job1.changeState('全职')
- [第一个方法内]
session.createQuery("from Job where person.id = (:id) state in (:states)")
。
问题是第二个查询不正确,因为它没有考虑 job1
已更改的状态
请您参考如下方法:
这里有几个选择,但是这个问题没有简单的改变。
1) 使用FlushMode.AUTO
。通过自动刷新,Hibernate 在执行查询之前进行刷新以避免此问题。自动刷新和您正在使用的模式之间不应该有任何冲突,但自动刷新还存在其他问题。通常在高度并发的环境中,您可能会遇到问题,因为它将保留较长的数据库事务。
2) 当您进行这样的查询时,请离开根对象并在内存中查询。在此示例中,这类似于获取人员并迭代其 Job 集合。
3) 创建一个 ThreadLocal 缓存来跟踪您可能查询的内容。这是所有选项中最糟糕的,但有时是必要的。