Immutability versus defaults

44 views
Skip to first unread message

Benson Margulies

unread,
Nov 6, 2014, 8:47:50 PM11/6/14
to jackso...@googlegroups.com
Is there any way to indicate suppressible default values in a class where the fields are all final and set in a non-zero-arg ctor?

Benson Margulies

unread,
Nov 6, 2014, 9:12:04 PM11/6/14
to jackso...@googlegroups.com
This gets sadder.

This mixin class:

@JsonInclude(JsonInclude.Include.NON_DEFAULT)
public abstract class NameMixin {
String text = "";
ISO15924 script = ISO15924.Zyyy;
LanguageCode languageOfUse = LanguageCode.UNKNOWN;
LanguageCode languageOfOrigin = LanguageCode.UNKNOWN;

@JsonCreator
public NameMixin() {
//
}

@JsonCreator
public NameMixin(@JsonProperty("text") String text,
@JsonProperty("script") ISO15924 script,
@JsonProperty("languageOfOrigin") LanguageCode
languageOfOrigin,
@JsonProperty("languageOfUse") LanguageCode languageOfUse,
@JsonProperty("extendedProperties") Map<String,
Object> extendedProperties) {
//
}

}

results in:

com.fasterxml.jackson.databind.JsonMappingException: Class
com.basistech.rosette.dm.Name has no default constructor; can not
instantiate default bean value to support
'properties=JsonSerialize.Inclusion.NON_DEFAULT' annotation (through
reference chain: java.util.ArrayList[0])
at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1042)
at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:445)
at com.fasterxml.jackson.databind.ser.impl.PropertySerializerMap.findAndAddSecondarySerializer(PropertySerializerMap.java:95)

So it got the Inclusion property, but it won't use the provided
default constructor?

Tatu Saloranta

unread,
Nov 7, 2014, 2:08:03 PM11/7/14
to jackso...@googlegroups.com
Mix-in classes are just used for associating annotations: no code generation occurs, it's not a proxy.
Name class itself needs to have a default constructor if (but only if) you want to avoid inclusion of NON_DEFAULT. Otherwise it is impossible to figure out what a "default" value would look like, and to use it to find values equal to it.

You can solve that problem either by adding default constructor (may be private or protected), or by changing inclusion strategy for Name-valued properties to do NON_NULL.

-+ Tatu +-


--
You received this message because you are subscribed to the Google Groups "jackson-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jackson-user...@googlegroups.com.
To post to this group, send email to jackso...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Tatu Saloranta

unread,
Nov 7, 2014, 2:14:32 PM11/7/14
to jackso...@googlegroups.com
So, definition of default value does not depend on whether creators are used: default value is what you get when constructing value with no-arguments constructor.
Unfortunately Java annotations are very limited in kinds of values they take; so it is difficult to offer annotation-based overrides for defining alternative default values.
Conversely, trying to use Jackson itself to construct default values seems both like an overkill, and difficult to make work (what value would be fed? "{ }" only works for POJOs, not scalars)

Now... given that this limits possibilities of suppression, it would perhaps be possible to register "default values" explicitly, via Module interface. This would allow use of this feature for types that are singletons (say, Enums).

Alternatively, it would be possible to add a method in JsonSerializer (.getDefaultValue()?) that would also allow use of value constructed using some other mechanism.

-+ Tatu +-


On Thu, Nov 6, 2014 at 5:47 PM, Benson Margulies <ben...@basistech.com> wrote:
Is there any way to indicate suppressible default values in a class where the fields are all final and set in a non-zero-arg ctor?

--
Reply all
Reply to author
Forward
0 new messages