16
votes

Is it possible to serialize an object with no fields in Jackson using only annotations? When I attempt to serialize such an object with no annotations I get:

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class [redacted].SubjectObjectFeatureExtractor and no properties discovered to create BeanSerializer 

I have examined the list of Jackson annotations without seeing a way to annotate the class as having no serializable data. I tried putting @JsonCreator on the empty constructor (not expecting it to work, since it's a deserialization annotation), and I got the same error. There are no accessors or fields to put @JsonProperty on. Any ideas?

Update: The reason for this is that I have a list of objects which represent transformations which can be applied to a certain type of data. Some of these transformations are defined by parameters which needs to be serialized, but some of these are parameter-less (the data-less objects in question). I'd like to be able to serialize and deserialize a sequence of these transformations. Also, I'm using DefaultTyping.NON_FINAL so that the class name will be serialized.

Update: An example class would be

class ExtractSomeFeature implements FeatureExtractor<SomeOtherType> {
    public void extractFeature(SomeOtherType obj, WeightedFeatureList output) {
          // do stuff
    }
 }

I don't particularly care how the JSON for this looks like, as long as I can deserialize List<FeatureExtractor>s properly. My impression is that using default typing, the expected JSON would be something like:

['com.mycompany.foo.ExtractSomeFeature', {}]

Other sub-classes of FeatureExtractor would have real parameters, so they would presumably look something like:

[`com.mycompany.foo.SomeParameterizedFeature', {some actual JSON stuff in here}]

I think I could use @JsonValue on some toJSONString() method to return {}, but if possible I'd like to hide such hackery from end-users who will be creating FeatureExtractor sub-classes.

4
So you just want an empty {}? What purpose does that have? - Sotirios Delimanolis
@SotiriosDelimanolis: I've updated the question in response to your questions. - Ryan Gabbard
Please give an example of the type of object you'd want to serialize and what you'd expect the generated JSON to be. - Sotirios Delimanolis
@SotiriosDelimanolis: Question updated. - Ryan Gabbard
There is a relevant issue in Jackon's JIRA: jira.codehaus.org/browse/…, which seems to indicate the issue was fixed, so that POJOs with other Jackson annotations (e.g. @JsonCreator on the empty constructor, I assume) should not throw an exception. However, this does not seem to be the case. - Ryan Gabbard

4 Answers

12
votes

You have to configure your object mapper to support this case.

ObjectMapper objectMapper = ...
  objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

The documentation of this feature can be found here : Fail on empty beans

Feature that determines what happens when no accessors are found for a type (and there are no annotations to indicate it is meant to be serialized). If enabled (default), an exception is thrown to indicate these as non-serializable types; if disabled, they are serialized as empty Objects, i.e. without any properties.

8
votes

The answer to disable SerializationFeature.FAIL_ON_EMPTY_BEANS is global, and you therefore might not wish to apply it.

The answer to add any serialisation annotation showed the correct (as in: the Javadoc of SerializationFeature.FAIL_ON_EMPTY_BEANS suggests it) way to fix it, but only with a hackish or an unrelated annotation.

By merely adding…

@JsonSerialize

… to my class (not even parenthesēs after it, lest alone arguments!) I was able to produce the same effect (as, again, indicated by the Javadoc of SerializationFeature.FAIL_ON_EMPTY_BEANS).

7
votes

Adding the following annotation onto the class seems to solve the problem:

@JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.NONE)

Adding an unrelated annotated like

@JsonRootName("fred")

also seems to fix it. This seems to match the claim in the JIRA ticket that adding any Jackson annotation to the class will prevent the exception. However, it appears adding annotations within the class does not.