[英]Spring Data - Cannot catch DataIntegrityViolationException in Service Layer
[英]Catch DataIntegrityViolationException in @Transactional service method
我有一個帶有 Hibernate 的 REST Spring 啟動應用程序。 為簡單起見,我們假設此工作流程:
@Transactional
,做一些業務邏輯並調用 Persistence 方法 數據庫對username
的用戶username
有unique
約束。 我現在的工作方式是這樣的:
DataViolationException
,Service 返回自定義異常偽代碼是這樣的:
public class UserController {
@RequestMapping("/user")
public User createUser(...){
try{
return userService.createUser(...);
} catch (UserAlreadyExistsException e){
// Do some processing and return error message to client
}
}
}
public class UserService {
@Transactional
public User createUser(...){
(...)
try{
userDAO.save(newUserObject);
} catch(DataIntegrityViolationException e){
throw new UserAlreadyExistsException(username);
}
}
}
但是,這樣我在嘗試創建重復用戶時會收到錯誤消息。
javax.persistence.RollbackException: Transaction marked as rollbackOnly
解決此問題的一種方法似乎是讓DataIntegrityViolationException
從事務中“冒泡”(而不是在服務中捕獲它)。 但這意味着控制器必須處理持久性異常,我不喜歡那樣。
我更喜歡服務拋出“可理解”的異常以供控制器處理。 該服務知道預期什么持久性異常以及何時發生,並且能夠將廣泛的DataIntegrityViolationException
“轉換”為有意義的DataIntegrityViolationException
。
有沒有辦法以這種方式處理異常? 我不是特別喜歡使用“2 層服務層”來實現這一點的想法。
編輯:我想拋出自定義異常的另一個原因是編譯器需要捕獲它。 我想強制控制器處理所有可能發生的異常。
您的存儲庫需要擴展 JpaRepository,當您這樣做時。 您可以使用該存儲庫中的 saveAndFlush 方法。 這意味着,您的代碼將立即在數據庫上執行,並在完成事務之前拋出異常,您將能夠在 Catch 塊中捕獲它。 我還添加了用於刪除操作的示例。
存儲庫:
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserDAO extends JpaRepository<User, Long> {
}
服務:
public class UserService {
private UserDAO userDAO;
(...)
@Transactional
public User createUser(...){
(...)
try{
userDAO.saveAndFlush(newUserObject);
} catch(DataIntegrityViolationException e){
throw new UserAlreadyExistsException(username);
}
}
@Transactional
public void deleteUser(...){
(...)
try{
userDAO.delete(deletingUserObject);
userDAO.flush();
} catch(DataIntegrityViolationException e){
throw new UserException(username);
}
}
}
注釋您的服務方法
@Transactional(rollbackFor = UserAlreadyExistsException.class)
如果拋出異常,它會告訴 spring 不要提交事務,這樣你就可以在控制器中捕獲它
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.