2013-06-29 105 views
0

我真的在与休眠会话苦苦挣扎,我从来没有想到在修改会话对象上进行查询时的结果。我认为我所有的问题都是相关的。最后一个是以下几点:对象的Java 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。

+1

请通过内嵌的'DAOMyObject'类执行的代码。很难猜测这些自定义方法背后隐藏着什么。 – nif

回答

0

我的猜测是在DAOMyObject.getInstance().deleteObjectWithZeroQuantities(iSession)之内,您提出的查询到达数据库。但是在DB中你的iObject.getQuantity()仍然是!=0,所以它不会被删除。

为什么你的查询击中DB,而不是使用iObject实例在Session缓存?

这是因为查询必须检索所有实体为此quantity != 0,和你没有所有这些缓存。当您通过ID检索实体时,通常使用Session的一级高速缓存,其格式为select * from MyEntity where id=123456。在查询的where子句中添加更多条件迫使Hibernate命中数据库。

请注意,无论标准是select查询的一部分还是update/delete的一部分,都会发生相同的情况。休眠仍然必须击中数据库和iObject将被删除。

那么如何解决它呢?

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

即使你做,Hibernate无法知道其他一些Session可能刚刚插入新的实体,查询也应该选择

编辑:

另一种选择是session.flush()iObject的数量变化......其实我认为这个是问题所在。在DAOMyObject.getInstance().update(iSession,iObject)内部,更改数量并致电iSession.save()后,您应该致电iSession.flush()。这会将更改写入数据库,以便对随后发生的查询进行查看。 这是正确的做法。

+0

谢谢!现在更有意义。我只是认为hibernate会在会话中已经存在的内容和它需要从数据库中检索的内容之间做出区分,而不是从数据库中获取所有内容,因为会话中的信息缺失。 – user2535201

+0

OK,也只是看到我的最后一次编辑 – yair

+0

是的,看到它,这应该工作。谢谢 ! – user2535201

0

你必须做一个session.flush()

你的对象改变只在内存中,只有等到冲洗将它们在数据库持久。另外,您也可以设置FlushModeCOMMIT,和每一个承诺也将刷新。不过,我建议每次手动冲洗。

+0

冲洗模式是默认AUTO,和冲洗将作出每次提交之前自动,和其每一个可能被修改未决的影响查询之前。大多数情况下,手动冲洗是一个糟糕的主意。顺便说一句,刷新不会同步JDBS连接的状态,无论这可能意味着什么。 –