我想實現Rest API的註冊控制器。我已經閱讀了很多關於@Transactional的地方。 (不是在DAO級別,而是在可能協調的服務)。在我的用例中,我不僅需要服務,而且還希望使用相同的事務進行hibernate驗證。休眠驗證和彈簧控制器的一個事務
這是控制器的代碼:
@Autowired
private UserService userService;
@RequestMapping(method = RequestMethod.GET)
@ResponseBody
@Transactional
public DefaultResponse register(@Valid RegisterIO registerIO, BindingResult errors) {
DefaultResponse result = new DefaultResponse();
if (errors.hasErrors()) {
result.addErrors(errors);
} else {
userService.register(registerIO);
}
return result;
}
我寫了定製contraint註解,這驗證了參數registerIO的屬性。這兩個驗證器和userService.register(registerIO);訪問數據庫(檢查電子郵件地址是否已被使用)。
因此我希望這兩種方法都使用相同的Hibernate會話和事務。
這種做法的結果是以下異常:
org.hibernate.HibernateException: No Session found for current thread
org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:941)
的問題是@Transactional註解。當我將這個註解放在所有可以找到的數據庫的方法中時,只有兩個事務是startet。我懷疑,當我將它放在註冊方法中時,在@Transactional啓動此方法的事務之前執行hibernate驗證。
我開發了以下功能解決方法,但我不滿意。這個代碼不使用@Valid註解,但是調用驗證本身:
@RequestMapping(method = RequestMethod.GET)
@ResponseBody
@Transactional
public DefaultResponse register(RegisterIO registerIO, BindingResult errors) {
DefaultResponse result = new DefaultResponse();
ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
Validator validator = vf.getValidator();
Set<ConstraintViolation<RegisterIO>> valResult = validator.validate(registerIO);
我試着總結一下我的問題: 使用Spring MVC和Hibernate驗證與@Valid和@Transactional在一起,怎麼可能將整個請求封裝到一個事務中?
謝謝:)
您使用的是JSR 330驗證嗎? –
JSR 330:Java的依賴注入:我使用Spring進行依賴注入。 @Autowire在這種情況下工作正常。我不確定你的意思是JSR 303:Bean驗證:這裏我使用Hibernate-Validator 4.3.1實現 – Sebastian
回答這個問題。 Hibernate Validator是Bean Validation(JSR 330)規範的參考實現。 – Hardy