3

I need to serialize an entity with only two column when it's called by a foreign key. I'am working in Wildfly, so I'am searching for a jackson solutions.

Suppose I have entity class A

public class A{
   private Long id;
   private String name;
   private String anotherinfo;
   private String foo;
   ...
}

and another class B:

public class B{
   private Long id;
   private String name;
   private A parent;
}

I want to serialize A with all his field when i search for A, but when i need to retrieve an istance of B, i need only two field (an ID and a label)

If I use annotations:

@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
@JsonIdentityReference(alwaysAsId=true)
private A parent;

i'll return only the id.

The result i want will be like:

B: {
  "id" : 1,
  "name" : "test",
  "parent" : {
     "id" : 1,
     "name" : 2
  }
}
Daniele Licitra
  • 1,520
  • 21
  • 45

3 Answers3

2

You can use the JsonIgnoreProperties annotation, to disable specific fields for serialization (and deserialization):

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

public class B {
    private Long id;
    private String name;

    @JsonIgnoreProperties({"anotherinfo", "foo"})
    private A parent;
Meiko Rachimow
  • 4,664
  • 2
  • 25
  • 43
  • 2
    This is fine if the set of ignored properties doesn't change over time. If, however, one expects there might be more properties to ignore, this might be problematic, because adding a new field in A means extending the ignored lists in other files. I find the solutions declaring the explicit list of fields to be serialized better because of that. But again: if the set of properties is fixed, this is okay. – Piohen Feb 15 '17 at 09:17
1

Have A extend another class, say C:

class C {
   Long id;
   String name;
}

class A extends C {
   String anotherinfo;
   String foo;
   ...
}

Then, in B:

class B {
   Long id;
   String name;
   @JsonSerialize(as=C.class)
   A parent;
}

When you serialize B, its parent field will have just the fields from C, but everywhere else that you serialize an A object you will see all the fields from both A and C.

For more information, take a look at https://github.com/FasterXML/jackson-annotations#annotations-for-choosing-moreless-specific-types

Sam
  • 8,330
  • 2
  • 26
  • 51
  • I cannot use this solution because I have a well defined inheritance strategy for using abstract class and standardized methods – Daniele Licitra Jun 03 '16 at 15:43
  • @DanieleLicitra C can also be an interface with getProperty() Bean-style methods and implemented by A. (There's no limit on implemented interfaces.) So if you have source control over A, I find this solution much easier and less boilerplate than a custom serializer. – Piohen Feb 15 '17 at 09:12
1

Solved adding a Json Serializer.

I have created an NationJsonSerializer for the parent class:

public class NationJsonSerializer extends JsonSerializer<TNation> {

@Override
public void serialize(TNation value, JsonGenerator jgen, SerializerProvider provider) 
  throws IOException, JsonProcessingException {
    jgen.writeStartObject();
    jgen.writeNumberField("id", value.getId());
    jgen.writeStringField("name", value.getComune());
    jgen.writeStringField("iso", value.getCap());
    jgen.writeEndObject();
}
}

Then,in the city class, i put the annotation

@JoinColumn(name = "idtnation",referencedColumnName = "id",nullable = true)
@ManyToOne(targetEntity = TNation.class, fetch = FetchType.EAGER)
@JsonSerialize(using = NationJsonSerializer.class)
private TNation nation;

So, if I use a method Nation n = getNation(long id); i'll receive all columns, but if i use getCity(), I'll receive a simplified version.

Daniele Licitra
  • 1,520
  • 21
  • 45