2013-06-29 104 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連接的狀態,無論這可能意味着什麼。 –