Skip to content

Apply '@Valid' to properties with "existingJavaType"#1781

Open
unkish wants to merge 4 commits intojoelittlejohn:masterfrom
unkish:issues/apply_valid_to_existingJavaType_properties
Open

Apply '@Valid' to properties with "existingJavaType"#1781
unkish wants to merge 4 commits intojoelittlejohn:masterfrom
unkish:issues/apply_valid_to_existingJavaType_properties

Conversation

@unkish
Copy link
Collaborator

@unkish unkish commented Feb 14, 2026

No description provided.

@unkish unkish requested a review from joelittlejohn February 14, 2026 16:28
@unkish
Copy link
Collaborator Author

unkish commented Feb 14, 2026

Idea of applying @Valid also to properties with "existingJavaType" was in the air during #1778 development.

This little POC is for the case if a non elegant approach could be considered for properties having "existingJavaType".

@joelittlejohn
Copy link
Owner

Looks good to me. I think we should merge this in 1.3.4 to avoid losing @Valid on fields that use existingJavaType.

@unkish
Copy link
Collaborator Author

unkish commented Feb 15, 2026

Unrelated to this commit:
org.jsonschema2pojo.cli.Arguments

@Parameter(names = { "-tv", "--target-version" }, description = "The target version for generated source files.")
private String targetVersion = "1.6";
has default value 1.6 - perhaps that should be changed to 8

@joelittlejohn joelittlejohn added this to the 1.3.4 milestone Feb 15, 2026
@unkish unkish marked this pull request as ready for review February 15, 2026 17:11
@unkish
Copy link
Collaborator Author

unkish commented Feb 15, 2026

It looks like there's one cornercase.

{
  "type": "object",
  "javaType": "com.example.ExistingJavaTypeProperties",
  "additionalProperties": false,
  "properties": {
    "itemOfExistingClassFqcn": {
      "type": "object",
      "existingJavaType": "com.example.ClassWithSizeAnnotation"
    },
    "itemOfExistingClass": {
      "type": "object",
      "existingJavaType": "ClassWithSizeAnnotation"
    }
  }
}

Generates a code that is compiling (note the placement of @Valid on itemOfExistingClassFqcn field)

    @JsonProperty("itemOfExistingClassFqcn")
    private com.example.@Valid ClassWithSizeAnnotation itemOfExistingClassFqcn;
    @JsonProperty("itemOfExistingClass")
    private @Valid ClassWithSizeAnnotation itemOfExistingClass;

but fails validation:

        instance = createInstanceWithPropertyValue(clazz, "itemOfExistingClassFqcn", new ClassWithSizeAnnotation());
        assertNumberOfConstraintViolationsOn(instance, is(1));

Prefix is added in JAnnotatedClass

        if (!isImported(f, rawType) && !prefix.isEmpty()) {
            f.p(prefix);
        }

Since generated type and existingJavaType both belong to same package, then !isImported(f, rawType) is true and since existingJavaType had fqcn then !prefix.isEmpty() also resolves to true

I have not yet figured out how to fix this.

@joelittlejohn
Copy link
Owner

Is the problem just aesthetic @unkish? i.e. com.example is printed for ClassWithSizeAnnotation even though it is not needed. Or is the validation not working?

@unkish
Copy link
Collaborator Author

unkish commented Feb 16, 2026

Is the problem just aesthetic @unkish? i.e. com.example is printed for ClassWithSizeAnnotation even though it is not needed. Or is the validation not working?

Validation is not working as @Valid is absent on field when queried through reflection.
Issue can be observed if schema file would contain a mix of non fully qualified class names with fullyqualified class names (JCodeModel::ref(Class) produce fully qualified class name references)

* removed unused imports
@unkish
Copy link
Collaborator Author

unkish commented Feb 17, 2026

@joelittlejohn I haven't been able to think of any better solution than either

  • declaring that a mix of fqcn and non-fqcn would not be supported at least for @Valid annotation
    or
  • roll back a bit changes to TypeRule and let ValidRule either annotate the field itself or add annotation inside container😞

@joelittlejohn
Copy link
Owner

@unkish Sorry, I'm being dense here. Could you add a failing test?

I don't see why this is a problem:

    @JsonProperty("itemOfExistingClassFqcn")
    private com.example.@Valid ClassWithSizeAnnotation itemOfExistingClassFqcn;
    @JsonProperty("itemOfExistingClass")
    private @Valid ClassWithSizeAnnotation itemOfExistingClass;

and I don't understand why it leads to this:

Validation is not working as @Valid is absent on field when queried through reflection.

The annotation placement on itemOfExistingClassFqcn looks correct to me.

Yes, it's using a fully qualified name for the class even though it does not have to, but the annotation is in the right place, isn't it?

If you add a failing test here I will see if I can think of a way to fix it.

@joelittlejohn
Copy link
Owner

@unkish Never mind, I have created a failing test now based on the schema you provided. Now to fixing...

@unkish
Copy link
Collaborator Author

unkish commented Feb 22, 2026

My understanding is that in case of private com.example.@Valid ClassWithSizeAnnotation itemOfExistingClassFqcn; hibernate skips validation as @Valid is a type and not a filed annotation.
As annotations are applied in TypeRule then either JAnnotatedClass::generate would somehow need to know/track where it is being invoked to print annotations correctly, or JAnnotatedClass would need to be applied only on container's types.

@unkish
Copy link
Collaborator Author

unkish commented Feb 24, 2026

Two options on my table atm:

  1. remove potential "type-use context" before creating field
  2. apply ValidRule on JFieldVar instead of JType

@joelittlejohn when you have some spare time, I would appreciate if you could have a look and share your thoughts on proposed solutions or any alternative approaches that might solve the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants