2017-07-14 32 views
1

我在我服務的方法:春 - 無法趕上ConstraintViolationException

@Transactional 
    public MyResponse create(UserCredentials cred) { 
     User user = new User(cred); 
     try { 
      final User created = userRepository.save(user); 
      return new MyResponse(user, "Created"); 
     } catch (TransactionSystemException e) { 
      return new MyResponse(null, "Cannot create"); 
     } catch (ConstraintViolationException e) { 
      return new MyResponse(null, "Cannot create"); 
     } 
    } 

用戶等級:

@Entity 
@Table(name = "users") 
public class User { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(
      name = "id", 
      updatable = false, 
      nullable = false 
    ) 
    private Long id; 

    @NotBlank 
    @Column(
      nullable = false, 
      unique = true 
    ) 
    private String username; 

    @NotBlank 
    @Column(
      nullable = false, 
      unique = true 
    ) 
    private String email; 

    @NotBlank 
    @Column(nullable = false) 
    private String password; 

而且問題是,當我在JSON空的用戶名或空的郵件發送。當調試應用程序,我得到ConstraintViolationExcpetion,但在JSON響應,我得到:

{ 
    "timestamp": 1500026388864, 
    "status": 500, 
    "error": "Internal Server Error", 
    "exception": "org.springframework.transaction.TransactionSystemException", 
    "message": "Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly", 
    "path": "/register" 
} 

調試器是在抓(ConstraintViolationException E)停止,但最後我得到SystemTransactionException,爲什麼呢?

+0

可能的複製(https://stackoverflow.com/questions/13777666/no-rollback-for-constraintviolationexception-in-transactional-service) – xyz

回答

0

抓住上面的例外。用@Transactional註解的方法。

在你的情況下,你攔截異常併吞下但DB狀態仍然不正確。所以在嘗試在註釋方法退出後提交失敗。

或者添加一個ExceptionHandler來捕獲這個異常並返回正確的響應。

+1

我刪除了註釋@Transactional,現在它工作。爲什麼? – user

1

調試程序正在停止catch(ConstraintViolationException e),但最後我得到SystemTransactionException,爲什麼?

這是由於Spring的異常轉換機制,使春天在它自己的RuntimeException類的一個包裝了任何潛在的異常。

一開始似乎很奇怪,但對底層JPA提供程序或甚至更改數據庫的更改可能(通常)針對相同的故障條件拋出不同的異常類型。

  • 你只需要擔心處理Spring例外,而不是例外的是底層的技術可能會引發
  • 經過例外的範圍被映射到unchecked異常,所以你不必辣椒你的代碼試戴抓塊。
  • 更容易將異常轉換爲服務器響應代碼(在您的情況下,自動轉換爲500)。

希望這會有所幫助。

[事後]值得一提,那春天將後執行該轉換它調用你的交易方法,這就是爲什麼你永遠追不上[在事務服務沒有回退的ConstraintViolationException]的TransactionSystemException