2017-07-14 78 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