有沒有任何方法可以在約束違反異常被拋出後繼續使用線程綁定的hibernate會話?我給一個簡單的例子在這裏:ConstraintViolationException後Hibernate會話失效
Parent other=service.load(33); // loads a new parent
try {
Parent p=new Parent();
p.setName("A name");
service.save(p); // a @Transactional spring service class, throws ConstraintViolationException - name should be at least 15 characters long
} catch (ConstraintViolationException e){
// i would like to handle validation errors and proceed normally
// but the session is allready closed here
}
System.out.println("Children: " + other.getChildren()); // lazy initialization exception, even when using opensessioninview
從現在開始Hibernate的Session是完全無用的,甚至是隻讀喜歡用OpenSessionInView模式鑑於渲染延遲集合操作。
這可能是正確的答案,但多麼令人不滿!在使用JPA(Hibernate 3)和Spring的應用程序中,我注意到當我們在合併之後顯式刷新實體管理器時拋出了'ConstraintViolationException異常,但如果我們移除了flush,則拋出了一個更通用的Spring'TransactionSystemException',其中包含嵌套的'RollbackException',它又包含根'ConstraintViolationException'。但是,在捕獲'TransactionSystemException'後,實體管理器(hibernate會話)仍然可用。沒有更多的懶惰初始化錯誤! – 2013-10-18 22:34:12
@Brice:考慮到文檔明確指出在引發異常之後不使用Session,找到一個解決方法仍然使用它並不會降低危險性。它可能適用於某些情況而不適用於其他情況,導致不確定的行爲。但是,如果它對你沒有任何問題,那麼好!儘管如此,個人而言,我寧願不使用任何這樣的「噱頭」,而是首先解決交易中的問題(例如,在這個問題中,例如,以某種其他方式驗證輸入,而不是對數據庫進行驗證)。 – esaj 2013-10-19 11:57:41
我同意。更清楚的是,這個問題與bean驗證(JSR 303)異常('javax.validation.ConstraintViolationException'而不是數據庫約束異常)有關,導致會話/實體管理器拋出一個異常使其本身無用。在pre-persist/pre-update/pre-remove驗證失敗後,仍然可以將會話用於只讀查詢將會很好。在這種情況下,在數據庫級別上沒有任何事情會使會話變得危險(據我所知),這僅僅是使某個實體無效的業務規則。 – 2013-10-21 20:24:43