Spring数据休息 - 处理实体验证

时间:2018-03-14 09:02:27

标签: java spring spring-boot spring-data spring-data-rest

这是代码

Person.java

@Entity
class Person {
   @Id private Long Id;
   @NotNull private String name;
   //getter setters
}

PersonRepository.java

@RepositoryRestResource(collectionResourceRel = "person", path="person" )
interface PersonRepository extends CrudRepository<Person,Long>{
}

现在,当我针对name属性发送null时,验证器会正确验证它,但是抛出的实际异常是TransactionRollbackExecption。

喜欢这个

{
    "timestamp": "2018-03-14T09:01:08.533+0000",
    "status": 500,
    "error": "Internal Server Error",
    "message": "Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction",
    "path": "/peron"
}

如何获得实际的ConstraintViolation异常。我确实在日志中看到了异常。但它没有被抛出。

2 个答案:

答案 0 :(得分:1)

原因是Spring的TransactionInterceptor覆盖了你的例外。

根据Spring's documentation,实现存储库实体验证的惯用方法是使用Spring Data Rest Events。您可能希望使用BeforeSaveEventBeforeCreateEvent

您可以为实体创建自定义类型安全处理程序(请参阅提供的链接以获取详细信息),其类似于:

@RepositoryEventHandler 
public class PersonEventHandler {

  @HandleBeforeSave
  public void handlePersonSave(Person p) {
    // … you can now deal with Person in a type-safe way
  }
}

另一种方法是注册扩展AbstractRepositoryEventListener的Repository Listener,也在文档中描述。

答案 1 :(得分:1)

配置LocalValidatorFactoryBean时,您可以将ValidatingRepositoryEventListener添加到RepositoryRestConfigurerAdapter,如下所示:

@Configuration
public class RepoRestConfig extends RepositoryRestConfigurerAdapter {

    private final LocalValidatorFactoryBean beanValidator;

    public RepoRestConfig(LocalValidatorFactoryBean beanValidator) {
        this.beanValidator = beanValidator;
    }

    @Override
    public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener v) {
        v.addValidator("beforeCreate", beanValidator);
        v.addValidator("beforeSave", beanValidator);
        super.configureValidatingRepositoryEventListener(v);
    }
}