2

i am new in spring boot and i could not find solution for this for a day now.

@GetMapping used to retrive item gives a responce of infinite loop of foreignkey object "user".

why am i getting this infinite loop?

how to fix it?

user object in infinite loop(the problem)

user object in infinite loop(the problem)

result that i want

result that i want

item entity

@Entity
public class Item{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long ItemId;
    @ManyToOne
    @JoinColumn(name = "owner_id")
    private User user;
    private String ItemName;
    // @Column(columnDefinition="text")
    private String Description;
    private double Price;
    private int AvailableQuantity;
    private double shippingWeight;
    // @Transient
    // private MultipartFile Picture;
    @Enumerated(value = EnumType.STRING)
    private Category category;
    @OneToMany(mappedBy = "item")
    @JsonIgnore
    private List<CartItem> CartItemList;
}

user entity

@Entity
@Table(name = "Utilisateur")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long idU;
    private String username;
    private String password;
    private String firstname;
    private String lastname;
    private String gender;
    private Long phone;
    private String adress;
    @Temporal(TemporalType.DATE)
    private Date dateofbirth;
    private int rating;
    private String email;
    public Role role;
    private Integer status;
    @OneToMany(mappedBy = "user")
    private List<Item> ItemList;

}

item service

@Service
public class ItemService implements ItemServiceInterface{
    @Autowired
    ItemRepository itemrepository;

    public Optional<Item> getItemById(long id){
        return itemrepository.findById(id);
    }
}

item controller

@RestController
public class ItemControl {
    @Autowired
    ItemServiceInterface itemservice;

    @GetMapping("/getitem/{id}")
    public Optional<Item> getitembyid(@PathVariable Long id) {
        return itemservice.getItemById(id);
    }
}
Anish B.
  • 9,111
  • 3
  • 21
  • 41
Masmoudi
  • 123
  • 1
  • 9
  • It would be helpful to strip your code of all that is not relevant to the problem. Nobody wants to help if it requires reading through 4 pages of screenshots and code that is 99% not relevant. – Giszmo Apr 16 '20 at 01:55
  • okay i will edit – Masmoudi Apr 16 '20 at 02:06
  • Here is same issue solution https://stackoverflow.com/questions/61186562/jpa-many-to-many-relationship-jsonmappingexception-infinite-recursion/61187326#61187326 – Eklavya Apr 16 '20 at 08:31

2 Answers2

1

You can use combination of @JsonManagedReference and @JsonBackReference to discourage Jackson from infinite serialization.

@Entity
@Table(name = "Utilisateur")
public class User {

    // omitted

    @JsonManagedReference
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private List<Item> ItemList;
}
@Entity
public class Item{

    // omitted

    @JsonBackReference
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "owner_id")
    private User user;
}

More details could be found here https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion

Nikolai Shevchenko
  • 7,083
  • 8
  • 33
  • 42
0

You can make use of lazy loading to cut the dependency loop between user and item. However, following that approach might potentially affect other parts of your projects because other codes might use the entity with an assumption that item list in user entity is already eager fetched.

A better way is not return the entity object directly to the REST response. You can define a data model for the rest response and convert the entity to that model in your service class. This way, you can completely control what to return and not to.

Another approach if you still want to use the entity as response: https://www.baeldung.com/spring-data-jpa-named-entity-graphs. This way, you can define when to use the lazy load with each specific query.

Duy Nguyen
  • 531
  • 2
  • 5