Issue
I'm trying to write a simple application with a One-to-Many association. When I fetch the Author, I repated data multiple times in the Postman response. Below are my entities and mapping.
@Entity
public class Books extends AbstractEntity implements Serializable{
// properties
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "auther_number", referencedColumnName="auther_id")
private Author author;
// get/set goes here.
}
@Entity
public class Author extends AbstractEntity implements Serializable{
// properties for autherID, name etc.
@OneToMany(mappedBy = "author",cascade = CascadeType.ALL,orphanRemoval = true, fetch = FetchType.LAZY)
private List<Books> bookList;
// to avoid synchronization issues. in 1-M Bi-direactional
public void addBooks(Books book) {
booklist.add(book);
book.setAuther(this);
}
// to avoid synchronization issues. in 1-M Bi-direactional
public void removeBooks(Books book) {
booklist.remove(book);
book.setAuthor(null);
}
// equals and hashcode methods
}
AutherserviceImpl.java
@Override
public List<Author> getAllAuthors() {
List<Author> authorList = (list<Author>) authorRepo.findAll();
return authorList ;
}
RestController
@GetMapping("/api/authors")
public ResponseEntity<Object> findAllAuthors(){
return new ResponseEntity<>(autherserviceImpl.getAllAuthors(),
HttpStatus.OK);
}
Below is the output in postman. Why is it duplicating? I have followed the samples given by this.
"authorNo": 4575600302,
"balance": 4458.0,
"books": [
{
"bookID": 3522,
"price": 458.0,
"ISBN": "1234",
"author": {
"authorNo": 4575600302,
"balance": 4458.0,
"books": [
{
"bookID": 3522,
"price": 458.0,
"ISBN": "1234",
"author": {
"authorNo": 4575600302,
"balance": 4458.0,
"books": [
{
"bookID": 3522,
"price": 458.0,
"ISBN": "1234",
"author": {
"authorNo": 4575600302,
"balance": 4458.0,
"books": [
{
Some questions in StackOverflow have suggested using Set instead of the list. But when I use Set, I get a casting error between Set and List. Not sure where is it throuwing exactly to fix the casting error. as I do not see any stack trace but only in the postman response I get that error.
How can I resolve this duplicate data showing issue? Note that in the Database has no duplicate records.
Solution
The problem is not JPA but the serialization of the author instance by Jackson. You have a bidirectional relationship between the authors and the books, i.e. Jackson serializes all books of an author and when it serializes a book, it will start the process of serializing the respective author again.
The simplest solution is to annotate the field author
of Books
with @JsonIgnore
. Alternatively, you can annotate author
with @JsonManagedReference
and the field bookList
of Author
with @JsonBackReference
. Then, the deserialization circle should be broken.
For a detailed guide, please have a look here: https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion
Answered By - Henning