2016-10-03 18 views
0

我在Spring的事務服務類中做了很少的hibernate保存操作。 我的期望是,當方法執行完成時,hibernate應該將數據寫入數據庫。 但是,只有當控制器即將返回響應時,hibernate纔會實際執行這些查詢。直到響應被提交後,Hibernate才執行查詢

我的示例代碼如下。

@Controller 
public class TestController { 
    @Autowired 
    private SaveService saveService; 

    @RequestMapping(value = "saveData", method = RequestMethod.POST) 
    public String saveData(HttpServletRequest request, Model model) { 
     try {  
     saveService.saveData(object1, object2, object3); // LINE 1 
     sendEmail();          // LINE 2 
     //some code here     // LINE 3 
     } catch(Exception e) { 
      //log exception 
      //return error message  
     } 
    } 
} 


@Service("saveService") 
@Transactional 
public class SaveServiceImpl implements SaveService { 
    @Autowired 
    private SaveDAO saveDAO; 

    public void saveData(Object objec1, Object objec2, Object objec3) { 
     saveDAO.save(object1); 
     saveDAO.save(object2); 
     saveDAO.save(object3); 
    } 
} 

在上面的代碼中,我從控制器調用SaveService.saveData()方法。如果保存成功,我想繼續併發送電子郵件。但如果由於某種原因SaveService.saveData()拋出一個異常,我不想 發送電子郵件。
當我執行一些測試時,發現即使SaveService.saveData()拋出異常,它也不會拋出 ,直到從控制器發送電子郵件。
我希望如果在控制器 的'LINE 1'處調用saveService.saveData()時引發異常,則不應執行發送電子郵件的下一行。
我想知道這是否是預期的休眠行爲,以及是否可以在退出服務方法之前告訴hibernate執行 查詢。
謝謝。

+1

對不起,我不明白爲什麼它不起作用。但我可以建議你使用'@ TransactionalEventListener' [(Details here)](https://spring.io/blog/2015/02/11/better-application-events-in-spring-framework-4-2#事務綁定事件)在事務提交或回滾後立即執行一些操作 – Dekart

+0

拋出哪個異常?我猜它的NullPointerException。 –

+0

謝謝@Dekart。瀏覽你分享的鏈接。 – ivish

回答

0

這裏的問題是,當發生異常時,您的變量/對象沒有在catch塊中初始化,並且您正在訪問它。

由於看起來您剛剛添加了代碼片段,因此我猜想變量object1, object2, object3需要初始化爲null
例如:object1=null

+0

感謝您的回覆Rohit。我發佈的代碼不是實際的代碼,只是一個示例來展示我面臨的問題。對象是像我的代碼中的用戶,角色等實體,它們在傳遞給服務方法之前完全初始化。 – ivish

1

這種現象是由於冬眠優化。 Hibernate將等待最後一次執行句子。

您可以通過session.flush()來避免這種情況,刷新會話迫使Hibernate將會話的內存中狀態與數據庫同步(即將更改寫入數據庫)。

+0

是的,我知道調用session.flush()會迫使hibernate立即提交事務。但是我想避免這種情況,以免錯過任何可能在沒有session.flush()的情況下執行hibernate的優化​​。 – ivish

+0

會議。flush()不提交事務,只在當前會話中將數據保存到數據庫。你有沒有證明s​​endEmail()方法被激發,而不管它執行的好還是錯?我認爲這是不可能的。 – reos

+0

我通過生成主鍵違例db異常測試了幾次代碼。在執行發送電子郵件的行之前不會拋出異常。最後,我使用@TransactionalEventListener在[@Dekart](http://stackoverflow.com/users/1851902/dekart)建議的事務提交之後發送電子郵件。 – ivish