jsonb-api
jsonb-api copied to clipboard
private constructors for deserialization
Some use cases of a POJO demand that there is neither a public nor protected default constructor. For example, "effectively immutable" classes (i. e. classes being immutable by applications but are deserialized by JSON-P) will have no setters but just can be filled with values using a custom constructor. When deserializing this instance it should be enough to have a package-private
or private
constructor. Unfortunately JSON-P explicitly requests public
/ protected
.
Proposal: A future release of the spec should allow to use such constructors when annotated with @JsonbConstructor
(even when the constructor has no parameters). This would be similar to the existing behavior that JSON-P can write private
fields annotated by @JsonbProperty
when having no setter method.
@mkarg this would actually be @JsonbCreator but this is the same for factory methods (jsonbcreator can be on a method too). That said I'm not sure I get the goal. Spec should stick to the programming model of POJO IMHO. This is what is done today. Only exception is on fields because it is common to not have to map both getter and setter most of the time. It also enables to use libraries like lombok wich do not enable to map on getters/setters. This is not the case for constructors/factory methods so not sure it would be good to enable something java platform discourages since v9 and other specs (like CDI) will need to adjust at some point - ie we should stick to the bean contract, not internals for me.
What we like to reach is that we can have an immutable read-only POJO. In contrast to typical mutbable POJOs those are needed in many real-world applications to do product design guidelines (such guidelines will even lead to not using JSON-B).
This is impossible in JSON-B as of today, due to the following combination of limitations:
-
@JsonbCreator
is impossible with no-argument constructors. - No-argument constructors are needed if some arguments MUST be given but othere are optional.
So you currently end up with either writing a deserializer (ugly as you need to deal with algorithmic syntax while you actually want to use declarative annotations instead), or you end up with making the constructor public (ugly as the application would be able to produce inconsistent POJOs as it bypasses the with-arguments-constructor which actually would run business rules to prevent this situation), or you end up with public setters which completely foil the idea of immutability.