【问题标题】:Spring data rest - Handle entity validationSpring data rest - 处理实体验证
【发布时间】:2018-08-22 17:28:26
【问题描述】:

这是代码

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 异常。我确实在日志中看到了异常。但它不会被抛出。

【问题讨论】:

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


    【解决方案1】:

    在配置RepositoryRestConfigurerAdapter时可以将LocalValidatorFactoryBean添加到ValidatingRepositoryEventListener中,像这样:

    @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);
        }
    }
    

    【讨论】:

    • 使用处理程序是一种稍微方便的方式,因为它允许您以类型安全的方式处理对象(例如,Person,而不是 Object - 使用 Validator 时就是这种情况)。跨度>
    • @hovanessyan 问题是关于“如何获得 ConstraintViolation”而不是关于“如何验证我的实体”...
    【解决方案2】:

    原因是 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 的存储库监听器,文档中也有描述。

    【讨论】:

    • 谢谢。但我一直在寻找通用的东西。以上答案解决了它
    猜你喜欢
    • 2016-03-02
    • 2014-08-10
    • 2021-09-06
    • 2016-05-21
    • 2016-01-08
    • 1970-01-01
    • 2019-09-30
    • 2020-05-13
    相关资源
    最近更新 更多