Book.java
@Entity @Data
public class Book {
@Id
private Long id;
@Column(unique = true, nullable = false)
private String title;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "book")
@JsonManagedReference
private List<Note> notes;
}
Note.java
@Entity @Data
public class Note {
@Id
private Long id;
@Column(nullable = false)
private String title;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "book_id", nullable = false)
@JsonBackReference
private Book book;
}
When I call my BookRestController, it returns a JSON containing all the properties I need:
{
"id": 15,
"title": "A fé explicada",
"author": "Leo J. Trese",
"notes": [{
"id": 10,
"title": "Sobre o pecado mortal"
}]
}
But when I call NoteRestController, the Book attribute is missing:
{
"id": 10,
"title": "Sobre o pecado mortal"
// missing "book" property here...
}
What am I doing wrong?
I'm using @OneToMany and @ManyToOne annotations to declare that it's a 1-N relationship; @JsonBackReference and @JsonManagedReference have the simple purpose to avoid infinite recursion.
Of course Book
is omitted, that is what literally @JsonBackReference
is for
@JsonBackReference is the back part of reference – it will be omitted from serialization.
(https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion)
The solution is as simple as it sounds: Instead of returning a Note
entity in your REST controller (which I try to avoid as far as possible anyway to keep entities as entities that don't have any use in the REST context anyway) you can create a explicit transport object called e. g. NoteDTO
which contains a reference to a book (that omits the notes of the book to not have infinite recursion):
public class NoteDTO {
private Long id;
private String title;
private BookReferenceDTO book;
// getters and setters
}
public class BookReferenceDTO {
private Long id;
private String title;
// getters and setters
}