13

在休息应用程序中,我使用带有 jpa 的 spring boot。

我有一个班级房客

谁有

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "lodger")
private List<Reference> referenceList;

在我的课堂参考中,我有

@ManyToOne
@JoinColumn(name = "lodgerId")
private Lodger lodger;

当我调用这个方法时

@RequestMapping(value = "/lodgers/{lodgerId}", method = RequestMethod.GET)
public Lodger getLogderById(@PathVariable("lodgerId") long lodgerId) {
    return lodgerService.getLodger(lodgerId);
}

我收到这个错误

org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: Infinite recursion (StackOverflowError) (through reference chain: server.bean.Lodger["referenceList"]->org.hibernate.collection.internal.PersistentBag[0]->server.bean.Reference["lodger"]->server.bean.Lodger["referenceList"]->org.hibernate.collection.internal.PersistentBag[0]->server.bean.Reference["lodger"]->server.bean.Lodger["referenceList"]...
4

7 回答 7

27

解决方案:

利用

@JsonManagedReference实例化的第一个对象的注释

@JsonBackReference实例化的第二个对象的注释

第一的:

@JsonManagedReference
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "lodger")
    private List<Reference> referenceList;

第二:

@JsonBackReference
@ManyToOne
    @JoinColumn(name = "lodgerId")
    private Lodger lodger;
于 2017-11-05T05:18:39.570 回答
6

当您在返回对象中有一个循环并且spring尝试将其序列化为其他类型时,就会发生这种情况。

尝试从返回的模型中创建没有循环的 DTO 或值对象(简单 POJO),然后将其返回。

于 2015-06-17T13:39:26.240 回答
6

如果两个表中的主键名称相同,例如:id。

添加这个

@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,property = "id")
public class User {
    ...
}

并参考类。

@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,property = "id")
public class Reference {
    ...
}
于 2018-04-12T18:53:05.033 回答
2

不要通过 REST Web 服务返回具有循环依赖关系的实体 - 创建新的 DTO 类,映射从数据库中获取的实体并将其返回到 Web 服务中。

更多信息在这里:http ://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application

当然如果你想你可以使用另一个映射库,我个人最喜欢的是 Orika ( http://orika-mapper.github.io/orika-docs/intro.html )

于 2016-06-28T07:49:53.237 回答
2

您唯一需要的是,在您有注释的类中,@ManyToOne使用要在值部分中跳过的属性实现下一个注释 @JsonIgnoreProperties(value = {"yourAttribute", "handler", "hibernateLazyInitializer"}, allowSetters = true)

我为您的代码举了一个示例->

@ManyToOne(fetch = FetchType.LAZY)
@JsonIgnoreProperties(value = {"referenceList", "handler","hibernateLazyInitializer"}, allowSetters = true)
@JoinColumn(name = "lodgerId")
private Lodger lodger;

您在 value 部分中放置的所有属性都将@JsonIgnoreProperties被忽略,这样您就可以解决无限循环并将​​其用于将来具有相同格式的其他开发。

于 2021-04-09T09:53:10.293 回答
0

让我们假设您的代码如下所示:-

Lodger.class

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "lodger")
private List<Reference> referenceList;

public List<Reference> getReferenceList() {
    return referenceList;
}

public void setReferenceList(List<Reference> referenceList) {
    this.referenceList = referenceList;
}

@Override
public String toString() {
    return "Lodger[referenceList=" + referenceList + "]";
}

参考类

@ManyToOne
@JoinColumn(name = "lodgerId")
private Lodger lodger;

public Lodger getLodger() {
    return lodger;
}

public void setLodger(Lodger lodger) {
    this.lodger = lodger;
}

@Override
public String toString() {
    return "Reference[lodger=" + lodger + "]";
}

当您注意到在两个 POJO 中编写的 toString() 方法时,您会看到我们正在从任一侧调用两个类的 toString(),这会导致无穷大。从永远不会终止的双方对 toString() 方法的调用。为避免这种情况,请从 Reference.class 的 toString() 中删除任何引用[您也可以从 Lodger 类中删除。] 所以 Reference 类的 toString() 中不会有 lodger 属性。

所以最后你的参考类看起来像: -

参考类

@ManyToOne
@JoinColumn(name = "lodgerId")
private Lodger lodger;

public Lodger getLodger() {
    return lodger;
}

public void setLodger(Lodger lodger) {
    this.lodger = lodger;
}

@Override
public String toString() {
    return "Reference[Properties other than lodger=" + properties other than lodger + "]";
}
于 2017-08-06T17:22:49.273 回答
0
@JsonIgnoreProperties({"hibernateLazyInitializer","referenceList"}) at class Level

有关参考,请参阅medium.com 上的这篇文章

在此处输入图像描述

于 2020-12-10T07:17:53.420 回答