Java Hibernate会话删除对象

时间:2013-06-29 19:31:58

标签: java hibernate

我真的在与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。

2 个答案:

答案 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将被删除。

那么如何解决它?

  1. 进行两笔交易。第一个将改变iObject的数量。第二个将删除所有零数量的实体。
  2. 如果您必须在同一事务中进行两项操作,则可以在删除所有其他零数量实体之前/之后显式删除iObject。请记住,您知道它的ID。

  3. 1 即使你这样做,Hibernate也无法知道它,因为其他iObject可能刚刚插入了查询也应该选择的新实体

    修改

    另一种选择是Session session.flush()数量的变化......实际上我认为这个就是问题所在。在iObject内,更改数量并致电DAOMyObject.getInstance().update(iSession,iObject)后,您应致电iSession.save()。这会将更改写入数据库,以便后续查询可以看到它。 这是正确的方法。

答案 1 :(得分:0)

你必须做session.flush()

您的对象更改仅在内存中,并且只有在刷新后它们才会在数据库中持久存在。或者,您可以将FlushMode设置为COMMIT,每次提交也会刷新。不过,我建议每次都手动刷新。