I am having an error with the fetch type and I dont know how to fix it! I retried to solve with similar issue solutions, but didn't work. Using java 11, Spring boot 2.6.5, gradle
MenuController:
package com.magsad.msnav.controller;
import com.magsad.msnav.entity.Menu;
import com.magsad.msnav.service.MenuService;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@RestController
@RequestMapping("menu")
@RequiredArgsConstructor
@FieldDefaults(makeFinal = true,level = AccessLevel.PRIVATE)
public class MenuController {
MenuService menuService;
@GetMapping
public List<Menu> getAllNodes(){
return menuService.getAll();
}
@GetMapping("{nodeId}")
public Menu getNodeById(@PathVariable Long nodeId){
return menuService.getById(nodeId);
}
@GetMapping("query")
public Menu getNodeByIdQuery(@RequestParam Long nodeId){
return menuService.getById(nodeId);
}
@PostMapping
public Menu create(@RequestBody Menu menu){
return menuService.create(menu);
}
@PutMapping
public Menu update(@RequestBody Menu menu){
return menuService.update(menu);
}
@DeleteMapping("{id}")
public void delete(@PathVariable Long nodeId){
menuService.delete(nodeId);
}
}
Menu entity
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import lombok.*;
import javax.persistence.*;
import java.util.List;
import java.util.Set;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Menu implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "url", nullable = false)
private String url;
@Column(name = "name")
private String name;
@JsonManagedReference
@OneToMany(mappedBy="parent")
private Set<Menu> children = new HashSet<>();
@ManyToOne
@JsonBackReference
private Menu parent;
}
When I remove @JsonManagedReference and @JsonBackReference and add @JsonIgnore to private Set<Menu> children = new HashSet<>() it works.
// @JsonManagedReference
@OneToMany(mappedBy="parent")
@JsonIgnore
private Set<Menu> children = new HashSet<>();
@ManyToOne
// @JsonBackReference
private Menu parent;
MenuRepository
import com.magsad.msnav.entity.Menu;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface MenuRepository extends JpaRepository<Menu,Long> {
}
MenuService
import com.magsad.msnav.entity.Menu;
import com.magsad.msnav.repository.MenuRepository;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
@Service
@RequiredArgsConstructor
@FieldDefaults(makeFinal = true,level = AccessLevel.PRIVATE)
@Transactional
public class MenuService {
MenuRepository menuRepository;
public List<Menu> getAll() {
return menuRepository.findAll();
/* .stream()
.filter(menu-> Objects.isNull(menu.getParent()))
.collect(Collectors.toList());*/
}
public Menu getById(Long nodeId){
return menuRepository.findById(nodeId).get();
}
public Menu create(Menu menu){
return menuRepository.save(menu);
}
public Menu update(Menu menu){
Menu menuForUpdate = menuRepository.findById(menu.getId()).get();
menuForUpdate.setId(menu.getId());
menuForUpdate.setName(menu.getName());
menuForUpdate.setUrl(menu.getUrl());
return menuRepository.save(menuForUpdate);
}
public void delete(Long nodeId) {
menuRepository.deleteById(nodeId);
}
}
I tried similar issue solutions again and again but failed to solve.
entityGraph, Eager Lazy, config
Could not write JSON: failed to lazily initialize a collection of role:
https://github.com/FasterXML/jackson-core/issues/469
CodePudding user response:
When creating the Json objects, if you don't specify a @JsonIgnore
and/or @JsonBackReference
property on a relationship attribut
. This is done so that one Object doesn't generate the other one over and over, it could easely become an infinite loop and you will never get the response
to your query.
@JsonIgnore
tell jpa to not put the children list into the Json to stop the infinite loop from happening.
CodePudding user response:
I just removed @Data
annotation, instead of it I wrote @Getter @Setter @ToString @EqualsAndHashCode
, added @OneToMany(mappedBy = "parent",fetch = FetchType.EAGER)
and worked !