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.
CodePudding user response:
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