如何向JPA实体添加验证,它需要查询实体以执行验证

时间:2017-01-14 09:52:57

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

假设我关注实体:

@Entity
public class MyModel {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private Integer counter;
    private Integer someVal;
}

我希望在此实体上拥有CRUD操作和一些其他方法, 因此我有一个存储库,如

@Repository
public interface MyModelRepository extends JpaRepository<MyModel, Long> {}

问题: 我想在保存时添加一些验证,我需要查询模型。

例如:在保存时,检查someVal的值是否大于MyModel的someVal,其计数器比当前保存对象小1。

PS:它也可能是跨实体验证。 PS:我仍然需要使用JpaRepository生成的自动crud。

否则,我将实现DAO并编写自定义实现,然后将其映射到RestController。

我理想的是在保留其余魔力的同时定制某些部分。

1 个答案:

答案 0 :(得分:1)

如果有人想知道,我是如何解决的:

方法1:原始方式

@RestController
public class MyModelController {
   // autowired MyModelRepository & other models repositories

   @RequestMapping(method = {RequestMethod.POST, RequestMethod.PUT})
   public long save(MyModel model){
       // added validation here (which involves queries to both repositories
       // returned saved entity.id or failed with 0
   }
}

方法2:

显然,问题是关于更好的方法。 正如@Alan Hay建议使用Validator,但仍然使用Controller。如果没有控制器覆盖,文档不清楚如何将Validator绑定到Repository

public class MyModelValidator implements Validator{
   // Autowired MyModel repository and others
   // override both supports() and validate()
   // PS: moved validation logic from Controller in method 1 to validate()
}

现在将控制器更改为:

@RestController
public class MyModelController {
   // autowired MyModelRepository & other models repositories
   // autowire MyModelValidator as mymodelValidator

   @RequestMapping(method = {RequestMethod.POST, RequestMethod.PUT})
   public long save(@ModelAttribute("myModel") MyModel model, BindingResult result){
       mymodelValidator.validate(model, result);

       if(result.hasErrors()){
        // return 0
       }
       // save & return saved entity's id
   }
}

方法3:最后如何完成。

@SpringBootApplication
public class MyApplication extends RepositoryRestConfigurerAdapter{
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

    @Override
    public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) {
        validatingListener.addValidator("beforeCreate", new MyModelValidator());
        validatingListener.addValidator("beforeSave", new MyModelValidator());
    }
}