La convalida del metodo di ibernazione NON funziona sempre

Aug 23 2020

Perché la convalida di Hibernate - ConstraintViolationException - NON viene lanciata in main () di un'app SpringBoot (l'ultima versione di SpringBoot) con spring-boot-starter-web:

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

Stranamente, in altri casi la convalida di Hibernate funziona come previsto per la stessa chiamata di metodo:

  1. ConstraintViolationException viene generata quando inserisco la chiamata non valida nel costruttore di un controller :
public SomeController(SomeService someService){
    this.someService = someService;
    someService.doStuff(new Item(null); // throws ConstraintViolationException  
}
  1. Inoltre, come previsto, viene generata ConstraintViolationException quando inserisco la chiamata non valida in a constructor methode chiamo l'endpoint in un test o Postman
@GetMapping("item")
public String item() {
    someService.doStuff(new Item(null); // throws ConstraintViolationException
    return "You never get here.";
}

Risposte

2 doctore Aug 23 2020 at 17:54

Non sono sicuro di come stai ottenendo l' someServiceistanza Application, ma il seguente codice funziona per me (ogni classe in un file diverso):

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

Il risultato:

Uso:

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

È il modo adatto per ottenere un componente gestito dal mainmetodo Spring in .