【问题标题】:Returning a lazy loaded entity in the JSON response在 JSON 响应中返回延迟加载的实体
【发布时间】:2023-01-08 23:46:19
【问题描述】:

我的 Club 实体有问题 - 我正在使用 LAZY 获取类型和 ModelMapper 返回我的 JSON。问题是,如果我使用LAZY而不是EAGER,我得到的GET/api/players/{id}的回复是:

Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: could not initialize proxy

和邮递员的截图:

当我调试控制器的动作时:

@GetMapping("/api/players/{id}")
    ResponseEntity<PlayerDto> getPlayer(@PathVariable String id) {
        Player foundPlayer = playerInterface.getPlayer(Long.valueOf(id));
        PlayerDto playerToDto = convertToDto(foundPlayer);

        return ResponseEntity.ok().body(playerToDto);
    }

...

 private PlayerDto convertToDto(Player player) {
        return modelMapper.map(player, PlayerDto.class);
    }

看起来 foundPlayerplayerToDto 都有这样的 Club

但是当我做foundPlayer.getClub().getName()时,我得到了一个合适的名字。我知道这可能是预期的行为,但我希望像这样在我的响应中返回 Club(如果设置了 EAGER,则响应的屏幕截图):

无需将提取类型设置为EAGER

我的Player实体:

@Entity
public class Player {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;


    private String firstName;


    private String lastName;;

    @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE }, fetch = FetchType.EAGER)
    @JsonManagedReference
    private Club club;

我的Club实体:

@Entity
public class Club {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @OneToMany(mappedBy = "club", cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    @JsonBackReference
    private List<Player> players;

来自 PlayerServicegetPlayer 方法(控制器调用的方法):

 @Override
    public Player getPlayer(Long id) {
        Optional<Player> foundPlayer = playerRepository.findById(id);
        return foundPlayer.orElseThrow(PlayerNotFoundException::new);
    }

PlayerToDto:

package pl.ug.kchelstowski.ap.lab06.dto;

import pl.ug.kchelstowski.ap.lab06.domain.Club;

public class PlayerDto {
    private Long id;
    private String firstName;
    private String lastName;

    private Club club;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Club getClub() {
        return club;
    }

    public void setClub(Club club) {
        this.club = club;
    }



}

【问题讨论】:

    标签: java spring spring-boot jpa


    【解决方案1】:

    伙计们,我有一个解决方案,但我想听听您是否可以通过这种方式完成,或者它是某种反模式。 我只是简单地将playerToDto的俱乐部设置为全新获取的Club,ID为foundPlayer

    @GetMapping("/api/players/{id}")
        ResponseEntity<PlayerDto> getPlayer(@PathVariable String id) {
            Player foundPlayer = playerInterface.getPlayer(Long.valueOf(id));
            PlayerDto playerToDto = convertToDto(foundPlayer);
            playerToDto.setClub(clubInterface.getClub(foundPlayer.getClub().getId()));
    
            return ResponseEntity.ok().body(playerToDto);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-14
      • 2013-09-25
      • 2015-09-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多