immutables / immutables

Annotation processor to create immutable objects and builders. Feels like Guava's immutable collections but for regular value objects. JSON, Jackson, Gson, JAX-RS integrations included
http://immutables.org
Apache License 2.0
3.43k stars 274 forks source link

[Enhancement] Support different validation for Modifiables vs Immutables #1483

Open symposion opened 1 year ago

symposion commented 1 year ago

We make quite heavy use of Modifiables to handle binding from the web requests. In this scenario, it's important to be able to have partially-populated objects that don't explode when you call unset properties in order to cope with e.g. partial pre-population of a form etc.

On the other hand, it's also very nice to be able to convert a Modifiable into its Immutable version before sending it down into a service layer, and to know that it will be guaranteed to satisfy all the expected integrity constraints from that point forward.

As things stand, you can only get one of these to work at once. You can turn off validation to have Modifiables that will work for web data-binding; but that turns off validation for the Immutable version as well. I've tried creating sub-interfaces and putting my @Immutable and @Modifiable annotations on those instead, but then you lose all the handy conversion tools like .toImmutable() because the generated types are no longer directly related.

Some sort of more fine-grained control with @Style seems like it shouldn't break any important assumptions and hopefully wouldn't be that hard to achieve....

elucash commented 1 year ago

I hear you, we can figure some simple solutions for these. Quick questions. Are *IsSet() methods (on Modifiables) are useful for anything (like checking if smth was set). What would be the values attributes which are not set: default uninitialized values, null for refs, 0, false etc for primitives ?

symposion commented 1 year ago

Yeah, so I think to do this nicely you probably would want isSet methods and then have the toImmutable method use those to ignore properties that weren't set explicitly when populating the immutable. I think the JVM default values for uninitialised primitives are fine (0/false). If it's important to distinguish whether they've been set or are just returning the default you call the isSet methods. If you really need a default then use the standard immutables default mechanism. And if you need a tri-state Boolean or a numeric that can be "unset" (eg to back a list of numbers with a placeholder value in a web ui) then just use the object versions of the primitives instead. It will effectively be nullable on the unvalidated Modifiable but will be guaranteed not-null by the validated Immutable

What do you think?