Spring Data JPA 按 id 检索时无限递归

问题描述 投票:0回答:1

我遇到了通过 id 检索对象的问题。 我得到了一个模型“Playground”和一个“PlaygroundComment”。其中 Playground 包含 PlaygroundComments 列表并具有 OneToMany 关系。我可以创建新的 PlaygroundComments,但是一旦我尝试 getById,我就会得到无限递归。 这是代码:

游乐场评论控制器:

    @GetMapping(value = "/{id}")
    public ResponseEntity<?> getById(@PathVariable("id") Long id) {
        if (id == null) {
            logger.error(LogBuilder.parameterNotSet(ParameterEnum.ID.name()));
            return ResponseEntity.badRequest().body(
                    LogBuilder.parameterNotSet(
                            ParameterEnum.ID.name()
                    ));
        }

        logger.info(LogBuilder.attemptToGet(PlaygroundComment.class.getSimpleName(), id));

        PlaygroundComment result = playgroundCommentService.getById(id);

        if (result == null) {
            logger.error(LogBuilder.NO_CONTENT);
            return ResponseEntity.noContent().build();
        } else {
            logger.info(LogBuilder.objectGetSuccess(result));
            return ResponseEntity.ok(result);
        }
    }

游乐场:

@Entity
@Table(name = "playgrounds")
public class Playground {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String street;
    private String city;
    @OneToMany(mappedBy = "playground", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<PlaygroundComment> playgroundComments;
    @OneToMany(mappedBy = "playground", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<ReturnVisit> returnVisits;

    public Playground() {
    }

    public Playground(Long id, String street, String city, List<PlaygroundComment> playgroundComments, List<ReturnVisit> returnVisits) {
        this.id = id;
        this.street = street;
        this.city = city;
        this.playgroundComments = playgroundComments;
        this.returnVisits = returnVisits;
    }

    public Long getId() {
        return id;
    }

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

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public List<PlaygroundComment> getPlaygroundComments() {
        return playgroundComments;
    }

    public void setPlaygroundComments(List<PlaygroundComment> playgroundComments) {
        this.playgroundComments = playgroundComments;
    }

    public List<ReturnVisit> getReturnVisits() {
        return returnVisits;
    }

    public void setReturnVisits(List<ReturnVisit> returnVisits) {
        this.returnVisits = returnVisits;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }
}

游乐场评论:

@Entity
@Table(name = "playground_comments")
public class PlaygroundComment {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String content;
    @Temporal(TemporalType.TIMESTAMP)
    private Date timestamp;
    @ManyToOne
    @JoinColumn(name = "user_id", nullable = false)
    private User user;
    @ManyToOne
    @JoinColumn(name = "playground_id", nullable = false)
    private Playground playground;

    public PlaygroundComment() {
    }

    public PlaygroundComment(Long id, String content, Date timestamp, User user, Playground playground) {
        this.id = id;
        this.content = content;
        this.timestamp = timestamp;
        this.user = user;
        this.playground = playground;
    }

    public Long getId() {
        return id;
    }

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

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public Date getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(Date timestamp) {
        this.timestamp = timestamp;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Playground getPlayground() {
        return playground;
    }

    public void setPlayground(Playground playground) {
        this.playground = playground;
    }
}

游乐场评论服务:

    @Override
    public PlaygroundComment getById(Long id) {
        if (id == null) {
            logger.error(LogBuilder.parameterNotSet(ParameterEnum.ID.name()));
            return null;
        }
        logger.info(LogBuilder.attemptToGet(PlaygroundComment.class.getSimpleName(), id));

        Optional<PlaygroundComment> optionalResult = playgroundCommentRepository.findById(id);

        if (optionalResult.isPresent()) {
            PlaygroundComment result = optionalResult.get();

            logger.info(LogBuilder.objectGetSuccess(result));

            return result;
        } else {
            logger.error(LogBuilder.objectGetFail(PlaygroundComment.class.getSimpleName(), id));
            return null;
        }
    }

有人能明白为什么会发生这种情况吗? 预先感谢!

有问题的代码是我尝试过的。

java spring spring-data-jpa spring-data
1个回答
0
投票

问题在于,当 @ManyToOne 和 @OneToMany 以 JSON 返回时,它们最终会无限地互相调用。请在一侧添加@JsonIgnore。

此外,一个根本的解决方案是将其作为 DTO 类返回。

一个原因是,如果实体按原样返回,则实体中的任何更改都会导致 API 规范发生更改。

希望对您有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.