我已经找到了很多资源,比如这个 - Infinite Recursion with Jackson JSON and Hibernate JPA issue。我已经尝试来实现那里描述的所有各种建议(包括基本的@JsonIgnore),但无济于事。无论我尝试什么,我都无法得到除无限递归错误之外的任何东西。我认为我有一个非常相似/典型的设置,但显然有一些错误,因为尽管使用@JsonManagedReference,@ JsonBackReferencere和@JsonIdentityInfo注释,我仍然得到错误。
我的桌子是“交换”和“股票”,它们之间有很多很多,我一直在通过ExchangeEndpoint进行测试。我已经确认,如果我从“交换”实体中完全删除“股票”,该服务工作正常,但由于某种原因,json注释似乎没有任何影响。以下是我认为是基于上述Infinite Recursion with Jackson JSON and Hibernate JPA issue中第二个(但更受欢迎)答案的解决方案。
Exchange.java
@Entity
@Table(name = "exchange", schema = "public")
@XmlRootElement
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id")
public class Exchange implements java.io.Serializable {
...
@OneToMany(fetch = FetchType.LAZY, mappedBy = "exchange")
@JsonManagedReference
public Set<Stock> getStocks() {
return this.stocks;
}
...
Stock.java
@Entity
@Table(name = "stock", schema = "public")
@XmlRootElement
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id")
public class Stock implements java.io.Serializable {
...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "exchangeid", nullable = false)
@JsonBackReference
@JsonIgnore
public Exchange getExchange() {
return this.exchange;
}
...
ExchangeEndpoint.java
@Stateless
@Path("/exchanges")
public class ExchangeEndpoint {
@PersistenceContext(unitName = "postgresql-ss4")
private EntityManager em;
...
@GET
@Produces("application/json")
public List<Exchange> listAll(@QueryParam("start") Integer startPosition,
@QueryParam("max") Integer maxResult) {
TypedQuery<Exchange> findAllQuery = em
.createQuery(
"SELECT DISTINCT e "
+ "FROM Exchange e "
+ "LEFT JOIN FETCH e.stocks "
+ "ORDER BY e.exchangeid",
Exchange.class);
if (startPosition != null) {
findAllQuery.setFirstResult(startPosition);
}
if (maxResult != null) {
findAllQuery.setMaxResults(maxResult);
}
final List<Exchange> results = findAllQuery.getResultList();
return results;
}
编辑:
一些错误输出,以确保我没有误解一些东西;
15:35:16,406错误[org.jboss.resteasy.resteasy_jaxrs.i18n] (http- / 0.0.0.0:8080-1)RESTEASY000100:执行GET失败 / exchange /:org.jboss.resteasy.spi.WriterException: org.codehaus.jackson.map.JsonMappingException:无限递归 (StackOverflowError)(通过参考链: net.hb.forge2RestServices.model.Exchange [ “股票”] - &GT; org.hibernate.collection.internal.PersistentSet [0] - &GT; net.hb.forge2RestServices.model.Stock [ “交换”] - &GT;净.hb.forge2RestServices.model.Exchange [ “股票”] - &GT; org.hibe ... ... 交换[ “股票”] - &GT; org.hibernate.collection.internal.PersistentSet [0] - &GT; net.hb.forge2RestServices.model.Stock [ “交换”] - &GT; net.hb.forge2RestServices.model.Exchange [ “股票”]) 在org.jboss.resteasy.core.ServerResponse.writeTo(ServerResponse.java:262)
请让我知道我可以提供哪些其他信息来帮助解释我的崩溃。 TIY。
答案 0 :(得分:3)
如果您不通过REST公开您的JPA实体,则更容易避免此类问题。
您应该考虑在REST端使用DTO并将实体映射到DTO,反之则是手动编码映射器或使用MapStruct生成映射器。
作为奖励,您将避免安全问题。
答案 1 :(得分:1)
似乎问题出在进口上。我不确定原因,但com.fasterxml.jackson.annotation.JsonIgnore
对我有用,function sayHello(name) {
return "Hello " + name;
}
alert(sayHello( "Mr. Park" ));
没有。
答案 2 :(得分:1)
使用@JsonManagedReference,@ JsonBackReference
public class User {
public int id;
public String name;
@JsonBackReference
public List<Item> userItems;
}
public class Item {
public int id;
public String itemName;
@JsonManagedReference
public User owner;
}
请注意:
@JsonManagedReference是引用的前向部分 - 正常序列化的部分。 @JsonBackReference是引用的后半部分 - 它将从序列化中省略。
http://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion
答案 3 :(得分:0)
问题是,您参考了Stock
,并且从[{1}}返回您引用Stock
。因此,JSON转为库存,返回Exchange
,然后转换为Exchange
,它将生成所有Exchange
,依此类推。
为了打破周期,最好将JsonIgnore
注释放到引用父对象的字段 - ManyToOne - 在这种情况下它是Stock.exchange字段(或者是getter for the that )。