Skip to content

Rearranging of props when property-based generator is in use leads to incorrect output #2759

@oshatrk

Description

@oshatrk

When these annotations:

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

are used on a link to a parent inside a child, and id is not the first field of the parent class,
then JSON output is incorrect.

With example code I got this:

{"name":"main hive","bees":[{"id":1,"hiveId":100500}],"bees":[{"id":1,"hiveId":100500}]}

Expected this:

{"name":"main hive","bees":[{"id":1,"hiveId":100500}],"id":100500}

Notice that private Long id; is not the first field of the Hive class.

A possible bug is in BeanSerializerBase.createContextual(), near this line:

// Let's force it to be the first property to output

Example:

import java.util.ArrayList;
import java.util.List;

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

public class Main {

    public static class Hive {

        private String name;

        private List<Bee> bees = new ArrayList<>();

        private Long id;

        public Hive() {
        }

        public Hive(Long id, String name) {
            this.id = id;
            this.name = name;
        }

        public void addBee(Bee bee) {
            bees.add(bee);
        }

        public Long getId() {
            return id;
        }

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

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public List<Bee> getBees() {
            return bees;
        }

        public void setBees(List<Bee> bees) {
            this.bees = bees;
        }
    }

    public static class Bee {

        private Long id;

        @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
        @JsonIdentityReference(alwaysAsId = true)
        @JsonProperty("hiveId")
        private Hive hive;

        public Bee() {
        }

        public Bee(Long id, Hive hive) {
            this.id = id;
            this.hive = hive;
        }

        public Long getId() {
            return id;
        }

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

        public Hive getHive() {
            return hive;
        }

        public void setHive(Hive hive) {
            this.hive = hive;
        }
    }

    public static void main(String[] args) throws JsonProcessingException {

        Hive hive = new Hive(100500L, "main hive");
        hive.addBee(new Bee(1L, hive));

        ObjectMapper mapper = new ObjectMapper();
        System.out.println(mapper.writeValueAsString(hive));
    }

}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions