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

Java 如何向需要查询实体以执行验证的JPA实体添加验证,java,validation,spring-boot,spring-data-jpa,spring-data-rest,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

假设我有以下实体:

@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> {}
@存储库
公共接口MyModelRepository扩展了JpaRepository{}
问题: 我想在save上添加某些验证,在这里我需要查询模型

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

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

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


理想情况下,我想要的是定制一些部件,同时保持其余部分的魔力。

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

方法1:原始方式 方法2: 显然,问题是关于更好的方法。 正如@Alan Hay建议使用
验证程序
,但仍然使用控制器。文档不清楚如何在没有控制器覆盖的情况下将
验证程序
绑定到
存储库

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
   }
}
方法三:最后是如何做到的。
有趣的是,safari online上的spring boot书籍都没有涉及模型对象的验证。甚至不是使用验证器的简单验证。也不是虚拟字段。如果你是一名技术作者,请加入。目前,你与一个rest控制器生活在一起,它覆盖了JpaRepository使用的路径。但是这并不强制JpaRepository用户进行验证。那么Spring数据Rest手册呢?您可以使用标准的Spring MVC验证机制,即JSR303/310注释,或者通过创建自定义验证程序:@AlanHay这与我的工作方法不同。我必须将自定义验证器添加到自定义控制器中,然后为所需的REST方法添加映射。附言:我敢肯定,以下标准将有其优点。您的问题是什么?w.r.t.:configureValidatingRepositoryEventListener不推荐使用。实际上
configureValidatingRepositoryEventListener
RepositoryRestMVCCConfiguration
中不推荐使用,但被添加到
RepositoryRestConfigurerAdapter
中。通过将其扩展到应用程序上下文中并实现
configureValidatingRepositoryEventListener
,您可以取消答案中所述的自定义控制器。
@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
   }
}
@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());
    }
}