0

I am trying to create a handler method in controller class in spring boot to handle post request coming with json in body. I am trying to deserialize this incoming json to object of a class using @RequestBody attribute in spring boot and then trying to save it in my database. I have used @manytomany bidirectional relationship between Account and Customer class. Account.java

@Entity
@Table(name = "Account")
public class Account {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public int accountNumber;
    public String accountType;
    public int balance;

    @ManyToMany(cascade = CascadeType.ALL)
    @JsonManagedReference
    
    private List<Customer> customers;
}
//skipped setters and getters and constructor

Customer.java

@Entity
@Table(name = "Customer")
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public int customerId;
    public String firstName;
    public String lastName;
    public String email;

    @ManyToMany(mappedBy = "customers")
    @JsonBackReference
    
    private List<Account> accounts;
//skipped constructors , getters and setters.
}

Handler method in controller class

 // post method to add record in account table
    @PostMapping("/accounts")
    public ResponseEntity<Account> postAccount(@RequestBody Account account) {
        System.out.println(account);//trying to print incoming account class object
        Account ac = this.accountServices.addAccount(account);

        return new ResponseEntity<>(ac, HttpStatus.OK);
    }

Postrequest in Postman enter image description here

Error on console is

I have started !!!!
2021-08-03 22:52:37.011  INFO 17508 --- [nio-8081-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2021-08-03 22:52:37.012  INFO 17508 --- [nio-8081-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2021-08-03 22:52:37.015  INFO 17508 --- [nio-8081-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms
2021-08-03 22:52:37.021  WARN 17508 --- [nio-8081-exec-2] .c.j.MappingJackson2HttpMessageConverter : Failed to evaluate Jackson deserialization for type [[simple type, class ma20099449.foundation.bank.ma20099449_bank.Entities.Account]]: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot handle managed/back reference 'defaultReference': back reference type (`java.util.List<ma20099449.foundation.bank.ma20099449_bank.Entities.Account>`) not compatible with managed type (ma20099449.foundation.bank.ma20099449_bank.Entities.Account)
2021-08-03 22:52:37.029  WARN 17508 --- [nio-8081-exec-2] .c.j.MappingJackson2HttpMessageConverter : Failed to evaluate Jackson deserialization for type [[simple type, class ma20099449.foundation.bank.ma20099449_bank.Entities.Account]]: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot handle managed/back reference 'defaultReference': back reference type (`java.util.List<ma20099449.foundation.bank.ma20099449_bank.Entities.Account>`) not compatible with managed type (ma20099449.foundation.bank.ma20099449_bank.Entities.Account)
2021-08-03 22:52:37.031  WARN 17508 --- [nio-8081-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported]

There is some problem for deserializing the incoming json to Account class object but I don't know the error. Someone please help me with code.

Mayank Kumar Thakur
  • 588
  • 1
  • 8
  • 23
  • As per the payload (that you have shown in postman), you have many customers for a single account. But the model is saying that for any given customer, there are a list of (many) accounts. Which is true? – aksappy Aug 03 '21 at 17:52
  • Hi @aksappy, one account can have many customers but here I am sending only 1 customer detail. – Mayank Kumar Thakur Aug 03 '21 at 17:55
  • Okay, so in that reference you have OneToMany relationship between Account and Customer, don't you? – aksappy Aug 03 '21 at 17:57

2 Answers2

1

Based on that issue, you can't use your @JsonManagedReference and @JsonBackReference in with @ManyToMany relationship.

You have many other alternatives:

  • for general-purpose handling of (possibly) cyclic dependencies, @JsonIdentityInfo may be used,
  • you can also use the @JsonIgnore annotation on your accounts list in Customer class,
  • another solution is to use dedicated Data Transport Objects (DTOs) to transfer JSONs. Here is interesting discussion, when you should use it and when shouldn't,

However, first of all I would consider if you really need a many-to-many relationship - in most cases a one-to-many relationship or a unidirectional relationship is enought, which will greatly simplify mapping.

M. Dudek
  • 978
  • 7
  • 28
  • Hi @M. Dudek, I am actually solving an exercise for bidirectional many to many relationship for my tutorials. – Mayank Kumar Thakur Aug 03 '21 at 18:21
  • So maybe `@JsonIgnore` should be enough for you. I honestly do not know how they worked in practice, because I have always used DTOs for that complex cases. – M. Dudek Aug 03 '21 at 18:30
0

First of all I think that you don't need to include your ID into the POST request in Postman, because it is generated by Hibernate in your database.

And for the other hand, try to delte any @JsonManagedReference

RodriESM
  • 1
  • 3