1

i really don't know what actually my problem is.

I have two models in my Project.

model-package

  • Ansprechpartner
  • Lieferant

Ansprechpartner.java

@Entity
@Table(name = "ANSPRECHPARTNER")
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(value = {"anlageAm", "updatedAt"}, allowGetters = true)
public class Ansprechpartner {

...

@NotNull
@ManyToOne
@JoinColumn(name = "lief_code", foreignKey=@ForeignKey(name = "APART_LIEF_FK"))
private Lieferanten liefCode;

public Lieferanten getLiefCode() {
    return liefCode;
}

public void setLiefCode(Lieferanten liefCode) {
    this.liefCode = liefCode;
}

...

}

Lieferant.java

@Entity
@Table(name = "LIEFERANTEN")
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(value = {"anlageAm"}, allowGetters = true)
public class Lieferanten {

...

@Id
private String code;

@OneToMany(mappedBy = "liefCode")
private Set<Ansprechpartner> apart;


public String getCode() {
    return code;
}


public void setCode(String code) {
    this.code = code;
}

public Set<Ansprechpartner> getApart() {
    return apart;
}


public void setApart(Set<Ansprechpartner> apart) {
    this.apart = apart;
}

...

}

My Controller:

@RestController
@RequestMapping("/apart")
public class AnsprechpartnerController {

...

@GetMapping("/all/{id}")
public Ansprechpartner getApartWithId(@PathVariable("id") long id) {

    Ansprechpartner apart = apartRepository.findOne(id);

    return apartRepository.findOne(id);
}

}

When i try to get the json data i get the following problem. Ansprechpartner gets data from Lieferant (because of that join). But then Lieferant again shows data from Ansprechpartner and so on.

Maybe better described with the following picture: Image with explanation


EDIT:

I finally solved it with the @JsonIgnoreProperties annotation:

In my Ansprechpartner.java i did it this way:

    @NotNull
    @JsonIgnoreProperties("apart")
//  @JsonManagedReference
    @ManyToOne
    @JoinColumn(
         name = "lief_code", 
         foreignKey=@ForeignKey(name = "APART_LIEF_FK")
    )
    private Lieferanten liefCode;

And in my Lieferanten.java i did it this way:

//  @JsonBackReference
    @JsonIgnoreProperties("liefCode")
    @OneToMany(mappedBy = "liefCode", fetch = FetchType.LAZY)
    private Set<Ansprechpartner> apart;
Adel
  • 88
  • 2
  • 11

3 Answers3

0

Strange behaviour. Possibly you could try:

1) Make sure in the Lieferanten entity, in the equals / hashCode you do not use the Set<Ansprechpartner> apart.

2) You can explicitly detach the entities from the persistence context:

@NotNull
@ManyToOne
@JoinColumn(name = "lief_code"
          , foreignKey=@ForeignKey(name = "APART_LIEF_FK")
          , cascade={CascadeType.DETACH})
private Lieferanten liefCode;

and then in the controller:

@GetMapping("/all/{id}")
public Ansprechpartner getApartWithId(@PathVariable("id") long id) {

    Ansprechpartner apart = apartRepository.findOne(id);
    apartRepository.detach(apart);  
    return apart;
}

you would need to implement a bit -> link, in repository in order to have that available.

3) explicitly add lazy loading: @OneToMany(mappedBy = "liefCode", fetch = FetchType.LAZY).

Maciej Kowalski
  • 25,605
  • 12
  • 54
  • 63
0

To avoid infinite recursions you can use @JsonManagedReference & @JsonBackReference Json Infinite Recursion is one of the most common problems when we serialize Java objects which having Bidirectional-Relationships.

@JsonManagedReference: a part with the annotation will be serialized normally. @JsonBackReference: a part with the annotation will be omitted from serialization.

like:

   @JsonBackReference
   private Set<Ansprechpartner> apart;

You can check details in solution-2

SF..MJ
  • 862
  • 8
  • 19
  • Is there another way to do it? Because, if I want to access all Ansprechpartner which are under Lieferanten, it is not possible. I still want that bidirectional, but not a recursion. – Adel Jan 10 '18 at 07:35
  • ya,it is bidirectional just you have to add `@JsonBackReference private Set apart` in Lieferant.java `@JsonManagedReference private Lieferanten liefCode;` in Ansprechpartner.java – SF..MJ Jan 10 '18 at 10:25
  • Hi mjsoft, i tried it...It works for Ansprechpartner. I get the data of Ansprechpartner + related data of Lieferanten (without Recursion). But if I try to get the data of Lieferanten I don't get the related data of Ansprechpartner. The field "apart" is totally ignored. It works in one direction, but not in both :/ – Adel Jan 10 '18 at 13:08
  • can you sho me your pojo – SF..MJ Jan 11 '18 at 05:34
  • I solved my problem with JsonIgnoreProperties. I commented out the JsonBackReference and JsonManagedReference, but it's still in the code. I have edited my Question above. – Adel Jan 11 '18 at 07:20
0

The root cause is jackson trying to serialize object when object has Bidirectional-Relationships. You can fixed it by this way Short way

Better way : Returning entities directly to view layer is not a good practice. You should convert entities to DTOs (Data Transfer Object) and pass the DTOs to view

  • Your first solutiuon: Is there another way to do it? Because, if I want to access all Ansprechpartner which are under Lieferanten, it is not possible. I still want that bidirectional, but not a recursion. The better approach: I will try it. – Adel Jan 10 '18 at 07:42
  • Have you tried to add @JsonIgnore to the property "liefCode" (Ansprechpartner.java) ? – Nguyen Hung Jan 11 '18 at 03:35
  • I solved my problem with JsonIgnoreProperties. Just @JsonIgnore would not help in my case – Adel Jan 11 '18 at 07:21