OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
20.62k stars 6.29k forks source link

[REQ] [Java] Container bean validation customisation #18757

Open Evgenikaall opened 1 month ago

Evgenikaall commented 1 month ago

Hello I've got some issues with beanValidation in latest versions of generator with containers. https://github.com/OpenAPITools/openapi-generator/blob/7bc2a660658766175a0fcde8e77c1b475bc970e6/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java#L1075-L1080 Was identified all bean validation for container are hardcoded, which is fully breaking templating for containers and arrays. Can we reuse for getBeanValidation our beanValidationCore.mustache definition ?

jpfinne commented 1 month ago

The implementation was done in #4947. It computes the value of CodegenProperty.datatypeWithEnum from the Schema. beanValidationCore.mustache use CodegenProperty. So it seems difficult to use mustache templates in getBeanValidation()

The only option to change the behaviour is useBeanValidation=false. Then you don't get contraints for list, and unfortunately you loose all the other validation annotations! That's the issue of using the same options for different purposes...

CodegenProperty.datatypeWithEnum is used everywhere in the model generation: field declarations, getters, setters...

I would be nice to obtain the datatype without the extra annotation so you could used your preferred types in your templates. For example CodegenProperty.rawDatatype or additionalProperties.rawDatatype. (I can't find a better name just now) CodegenProperty.rawDatatype = List<String> CodegenProperty.datatypeWithEnum = List<@Pattern(regexp = "^[a-z]$")@Size(min = 0)String>

I have in the pipe an implementation of JavaCodegenProperty that extends CodegenProperty. It contains new attributes to simplify the pojo generation. I'll check if I can generate such rawDatatype

Evgenikaall commented 1 month ago

Thank you for your response I've some workarounds how to fix this kind of issue without disabling hibernateValidation. In my case, I'm using custom templates for beanValidationCore, where are provided custom ConstraintValidators, disabling bean validation core wouldn't affect me. It's just a feature request, which will improve code generation.

Example:

@MyCustomPattern(pattern="something", customTag="do something")
private List<@Pattern(pattern="something") String> items;

MyCustomPattern is working with is implemented for list, string and another necessary classes, provides the same functionality as default Pattern. In this case, we'll have 2 validations:

  1. as a part of @MyCustomPattern
  2. as a part of @Pattern In cases, when we haven't the same behavior of our constraint validation, we can disable default validator:
    @Bean 
    public LocalValidatorFactoryBean validator(){
    return new LocalValidatorFactoryBean() {
        @Override
        protected void postProcessConfiguration(Configuration<?> config){
            // call super and add your custom necessary logic
            final HibernateValidatorConfiguration hibernateConfig = (HibernateValidatorConfiguration ) config;
            final ConstraintMapping mapping = hibernateConfig .createConstraintMapping();
            mapping
                .constraintDefinition(<use annotation to be replaced>)
                .includeExistingValidators(false)
                .validatedBy(<add your ConstraintValidator passing always true, bypass validator>)
           hibernateConfig.addMapping(constraintMapping);
    }
    }

    This code will replace default ConstraintValidator used for specific annotation. Example of ConstraintValidator (@Pattern)

public class ByPassPatternValidator implements ConstraintValidator<Pattern, String>{
// override methods and set true
}
jpfinne commented 1 month ago

Interresting workaround. From maven I use the maven-ant-plugin to patch the generated java classes before they are compiled. I've also used a forked version of the generator, but is is difficult to maintain