3

I wanted to simplify my question. I have a parent and a child entity.

public class Parent {
  private String name;
  @OneToMany
  private List<Child> childs;
}

and

public class Child {
  private String name;
  @ManyToOne
  private Parent parent;
}

What I want to do is when I serialize these entities, it should like this.

{
  "parentList": [
    {
      "id": "1",
      "name": "parent",
      "childs": [
        {
          "id": "1",
          "name": "chiled",
          "parent" : "1"
        }
      ],
    }
  ]
}

and

{
  "childList": [
    {
      "id": "1",
      "name": "child",
      "parent": [
        {
          "id": "1",
          "name": "parent",
          "childs": [
            {
              "id": "1",
            }
        }
      ],
    }
  ]
}

Like this:

Parent -> Child -> parentID
Child -> Parent -> childID

If I update my entities like as you can see below.

public class Parent {
  private String name;
  @JsonIdentityReference(alwaysAsId = true)
  @OneToMany
  private List<Child> childs;
}

and

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Child {
  private String name;
  @JsonIdentityReference(alwaysAsId = true)
  @ManyToOne
  private Parent parent;
}

With this setup I get almost what I want.

Child -> Parent -> ChildID (good)
Parent -> ChildID (bad)

I need Parent to have whole Child entity and that Child entity should only have parentID. If I add @JsonIdentityInfo to both entities, then result looks like this:

Child -> parentID (bad)
Parent -> childID (bad)

If I remove @JsonIdentityInfo from both, then I have recursive problem again.

Don't know how to get what I want.

gozluklu_marti
  • 79
  • 1
  • 7
  • 26
  • You can start from [Jackson/Hibernate, meta get methods and serialization](https://stackoverflow.com/questions/55383889/jackson-hibernate-meta-get-methods-and-serialization/55386877#55386877) question. Take a look at `JsonManagedReference`, `JsonBackReference` and `JsonIdentityInfo` annotations. See also: [Jackson - serialization of entities with birectional relationships (avoiding cycles)](https://stackoverflow.com/questions/10065002/jackson-serialization-of-entities-with-birectional-relationships-avoiding-cyc) – Michał Ziober Sep 23 '19 at 12:28
  • @MichałZiober I simplified my question, so I hope it is less confusing now :) – gozluklu_marti Sep 23 '19 at 14:41
  • following...... – oxyt Sep 23 '19 at 18:28

2 Answers2

1

Try to add "JsonIgnore" annotation to prevent the unwanted data comes from the parant entity into the child.

    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
    public class Child {
      private String name;
      @JsonIdentityReference(alwaysAsId = true)
      @ManyToOne
      @JsonIgnore      <- HERE
      private Parent parent;
    }
Ravi Mengar
  • 1,181
  • 1
  • 11
  • 18
0

This is the intended behavior. Normally you wouldn't want to do what you are proposing, so Jackson ships by default with that in mind.

One possibility:

However, since Jackson is nothing more than a java library, you can extend and modify it to suit your needs. My first suggestion would be to create different Scopes for the parent -> child -> parents and for the child -> parent -> child.

Why it's probably a bad idea:

Regardless of that, it's important to understand why this isn't a default behavior:

If you have Child and Parent in a relationship where a Child can only have one Parent and Parents can have multiple Childs, then:

  A         B            C
Child -> Parent -> List<ChildID>
  • A and B are different.
  • A is contained in C.
  • C can also contain other Child.

but,

  A         B                   C (missing)
Parent -> List<ChildID> ----> Parent
  • B contains multiple Child
  • Each missing C would be equal to A.

So, if your problem only appears when you approach Parent to get List<Child>, then you already have your solution. Since the Parent of each and every Child in the list would be the parent that has the list in the first place.

Therefore, you don't need the C that is missing, since it's already the element A.

Hope this helps!

ZektorH
  • 2,680
  • 1
  • 7
  • 20