我真的在与hibernate会话中苦苦挣扎,在修改会话对象上进行查询时,我从未得到过我期望的结果。我认为我所有的问题都是相关的。最后一个是以下内容:
final Session iSession = AbstractDAO.getSessionFactory().openSession();
try {
iSession.beginTransaction();
MyObject iObject = DAOMyObject.getInstance().get(iSession,ObjectId);
iObject.setQuantity(0); //previously the quantity was different from zero
DAOMyObject.getInstance().update(iSession,iObject);
DAOMyObject.getInstance().deleteObjectWithZeroQuantities(iSession);
iSession.getTransaction().commit();
} catch (final Exception aException) {
iSession.getTransaction().rollback();
logger.error(aException.getMessage(), aException);
throw aException;
} finally {
iSession.close();
}
我没有得到的是为什么没有删除该对象,因为我在会话中修改了它,进行删除的查询应该找到它。我在会话中创建具有增量ID的对象时遇到了同样的问题,然后在提交之前在同一会话中创建另一个对象,并使用select max(id)+1
。但是每次会话都会得到相同数量的id。
答案 0 :(得分:0)
我的猜测是,在DAOMyObject.getInstance().deleteObjectWithZeroQuantities(iSession)
内你会查询点击数据库。但是,在数据库中,iObject.getQuantity()
仍为!=0
,因此不会删除。
为什么您的查询会点击数据库,而不是使用iObject
中缓存的Session
实例?
这是因为查询必须检索所有的{em>所有实体,并且您没有缓存所有这些实体。 quantity != 0
的第一级缓存通常在您通过ID 检索实体时使用Session
形式的查询。在查询的select * from MyEntity where id=123456
子句中添加更多条件会强制Hibernate命中DB。
请注意,无论条件是where
查询的一部分还是select
/ update
的一部分,都会发生同样的情况。 Hibernate仍然需要访问数据库,delete
将被删除。
那么如何解决它?
iObject
的数量。第二个将删除所有零数量的实体。iObject
。请记住,您知道它的ID。 1 即使你这样做,Hibernate也无法知道它,因为其他iObject
可能刚刚插入了查询也应该选择的新实体
修改强>
另一种选择是Session
session.flush()
数量的变化......实际上我认为这个就是问题所在。在iObject
内,更改数量并致电DAOMyObject.getInstance().update(iSession,iObject)
后,您应致电iSession.save()
。这会将更改写入数据库,以便后续查询可以看到它。 这是正确的方法。
答案 1 :(得分:0)
你必须做session.flush()
。
您的对象更改仅在内存中,并且只有在刷新后它们才会在数据库中持久存在。或者,您可以将FlushMode
设置为COMMIT
,每次提交也会刷新。不过,我建议每次都手动刷新。