Hibernate 方法验证并不总是有效

Hibernate method validation NOT always working

为什么 Hibernate 的验证 - ConstraintViolationException - 没有在带有 spring-boot-starter-web 的 SpringBoot 应用程序(SpringBoot 的最新版本)的 main() 中抛出:

@Validated
@SpringBootApplication
public class Application {
public static void main(String[] args) {
   SpringApplication.run(Application.class, args);
   someService.doStuff(new Item(null);  // WHY NOT THROWN????????!!!!!! 
   // Expecting ConstraintViolationException: doStuff.item.content: must not be null
}}
// ----------------------

public class Item {
    @NotNull
    String content;  // to be validated
   //constructor, getter, setter
}

@Validated
@Service
public class SomeService {
    void doStuff(@Valid Item item) {} // should break for Item's content = null
}

奇怪的是,在其他情况下,对于相同的方法调用,Hibernate 验证按预期工作

  1. 当我将无效调用放入 控制器的构造函数:
  2. 时抛出 ConstraintViolationException
public SomeController(SomeService someService){
    this.someService = someService;
    someService.doStuff(new Item(null); // throws ConstraintViolationException  
}
  1. 同样如预期的那样,当我进行无效调用 in a constructor method 并在测试或 Postman
  2. 中调用端点时会抛出 ConstraintViolationException
@GetMapping("item")
public String item() {
    someService.doStuff(new Item(null); // throws ConstraintViolationException
    return "You never get here.";
}

不确定您如何在 Application 中获取 someService 实例,但以下代码对我有用(每个 class 在不同的文件中):

@AllArgsConstructor
@Getter
@Setter
public class Item {

  @NotNull
  String content;
}



@Validated
@Service
public class SomeService {

  public void doStuff(@Valid Item item) {
    System.out.println(format("Item.content = %s", item.getContent()));
  }
}



@SpringBootApplication
public class TestingPurposeApplication {

  public static void main(String[] args) {
    ConfigurableApplicationContext context = SpringApplication.run(TestingPurposeApplication.class, args);
    SomeService someService = context.getBean(SomeService.class);
    someService.doStuff(new Item(null));
  }
}

结果:

使用:

ConfigurableApplicationContext context = SpringApplication.run(MyApplication.class, args);
MyClass myInstance = context.getBean(MyClass.class);

是在 main 方法中获取由 Spring 管理的组件的合适方法。