Java Jackson @JsonIdentityReference Example

1. Introduction

Handling bidirectional relationships in Java can be tricky when converting objects to JSON, as they can lead to infinite loops during serialization. Jackson provides a solution with the @JsonIdentityInfo and @JsonIdentityReference annotations. In this guide, we will focus on the @JsonIdentityReference annotation, which allows representing a referenced entity with its ID rather than the full serialization.

2. Example Steps

1. Add the necessary Jackson library dependencies to your project.

2. Create Java classes representing a bidirectional relationship.

3. Annotate one side of the relationship with @JsonIdentityInfo and @JsonIdentityReference.

4. Use Jackson's ObjectMapper class to serialize the Java object.

5. Display the results.

3. Java Jackson @JsonIdentityReference Example

import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIdentityReference;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonIdentityReferenceExample {

    public static void main(String[] args) {
        // Initialize ObjectMapper instance.
        ObjectMapper objectMapper = new ObjectMapper();

        // Create objects with a bidirectional relationship.
        Book book = new Book("A Tale of Two Cities");
        Author author = new Author("Charles Dickens");
        book.setAuthor(author);
        author.setBook(book);

        try {
            // Serialize the Java object to JSON string.
            String jsonString = objectMapper.writeValueAsString(book);
            System.out.println("Serialized JSON: " + jsonString);

        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    static class Author {
        private String name;
        @JsonIdentityReference(alwaysAsId = true)
        private Book book;

        // Constructor, getters, setters, and other methods...
    }

    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "title")
    static class Book {
        private String title;
        private Author author;

        // Constructor, getters, setters, and other methods...
    }
}

Output:

Serialized JSON: {"title":"A Tale of Two Cities","author":{"name":"Charles Dickens","book":"A Tale of Two Cities"}}

4. Step By Step Explanation

1. We have two classes, Book and Author, representing a bidirectional relationship.

2. The @JsonIdentityInfo annotation on the Book class instructs Jackson to use the title property of the book as its identifier.

3. In the Author class, the @JsonIdentityReference annotation with the attribute alwaysAsId = true tells Jackson to serialize the book reference using its ID (in this case, the title) rather than the full object.

4. After setting up the bidirectional relationship between a book and its author, we serialize the book object. In the JSON output, the book property in the Author class is represented by its title, as instructed by our annotations.


Comments