On demand lazy loading via dynamic @JsonIgnore annotation

hibernate, jackson, json, lazy-loading

Solution

You can use Jackson views. Please, see my below example:

import java.io.IOException;
import java.util.Arrays;

import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonProgram {

    public static void main(String[] args) throws IOException {
        Entity entity = new Entity();
        entity.setId(100);
        entity.setContent(new byte[] { 1, 2, 3, 4, 5, 6 });

        ObjectMapper objectMapper = new ObjectMapper();

        System.out.println("Generate JSON with basic properties: ");
        System.out.println(objectMapper.writerWithView(View.BasicView.class).writeValueAsString(entity));
        System.out.println("Generate JSON with all properties: ");
        System.out.println(objectMapper.writerWithView(View.ExtendedView.class).writeValueAsString(entity));
    }
}

interface View {

    interface BasicView {
    }

    interface ExtendedView extends BasicView {
    }
}

class Entity {

    @JsonView(View.BasicView.class)
    private int id;

    @JsonView(View.ExtendedView.class)
    private byte[] content;

    public byte[] getContent() {
        System.out.println("Get content: " + Arrays.toString(content));
        return content;
    }

    public void setContent(byte[] content) {
        this.content = content;
    }

    public int getId() {
        System.out.println("Get ID: " + id);
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Entity [id=" + id + ", content=" + Arrays.toString(content) + "]";
    }
}

Above program prints:

Generate JSON with basic properties: 
Get ID: 100
{"id":100}
Generate JSON with all properties: 
Get ID: 100
Get content: [1, 2, 3, 4, 5, 6]
{"id":100,"content":"AQIDBAUG"}

As you can see, with basic view Jackson doesn't read `content` properties.

Problem

I have something like: ``` @Entity @Table(name = "myEntity") public class MyEntity { //.... @Column(name = "content") private byte[] content; //.... } ``` PROBLEM: I pass MyEntity to the client as JSON string. But the problem is that I have two types of client's requests: - I need to pass MyEntity with byte[] content array - I need to pass MyEntity without byte[] content array In first case I needn't @JsonIgnore annotation, in second - do need. QUESTIONS: - How to achive dynamical @JsonIgnore annotation? Is it possible at all? - Any alternatives to achieve lazy loading? P.S. As I understand, even if I mark my byte[] content array with lazy-load annotation, it will be loaded anyway when Jackson will parse MyEntity to JSON-string. Thank you in advance!

Original source