如何将@RestController (Spring) 与对象的子列表一起使用
How to use @RestController (Spring) with a child List of object
我正在尝试使用 Spring 创建 REST 服务。
一切正常,直到我尝试将对象列表 (CartItem) 添加到我的主要对象 (Cart)。
这是我的主要对象
@Entity
@Table(name="cart")
public class Cart implements Serializable{
...
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Id
@Column(name="id")
private Integer id;
/*when I add this I get the error. If I remove this, the
REST service works*/
@OneToMany(mappedBy="cart", fetch = FetchType.EAGER)
private List<CartItem> cartItems;
//getter, setter, constructors, other fields ecc.
}
这是列表中的对象:
@Entity
@Table(name="cart_item")
public class CartItem implements Serializable{
...
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Id
@Column(name="id")
private Integer id;
@OneToOne(targetEntity = Product.class, cascade = CascadeType.ALL)
@JoinColumn(referencedColumnName="productId", name="product_id" )
private Product product;
@ManyToOne
@JoinColumn(name="cart_id", nullable=false)
private Cart cart;
//getter, setter, constructors, other fields ecc.
}
这是我的控制器
@RestController
@RequestMapping(value="rest/cart")
public class CartRestController {
...
@RequestMapping(value = "/", method = RequestMethod.GET)
public List<Cart> readAll() {
return cartService.read();
}
...
}
我收到这个错误:
SEVERE: Servlet.service() for servlet [dispatcher] in context with path
[/webstore] threw exception [Request processing failed; nested exception
is org.springframework.http.converter.HttpMessageNotWritableException:
Could not write JSON: Infinite recursion (WhosebugError); nested
exception is com.fasterxml.jackson.databind.JsonMappingException:
Infinite recursion (WhosebugError) (through reference chain:...
我想我必须以特定方式管理 Cart 对象中的 List,可能是因为我使用的是 JPA,但我仍然没有在 Internet 上找到解决方案。
谁能帮帮我?
永无止境的清单?您是指 Whosebug 异常吗?
如果情况就像我说的那样,那么你应该检查一些东西,比如获取类型和实体的 toString() 或 equal() 方法或类似的东西。
比如有实体A和B,它们是一对多的关系(A就是一个),如果你把它们的fetchType都配置为Eager,那么jpa查询A的时候,就会查询B too.But B也包含A,所以jpa会查询A again.This 那种循环会导致Whosebug。
顺便问一下,能否提供更多关于你的问题的信息,比如异常名称?我很难给你一个具体的解决方案,我只能告诉你一些我以前遇到的经验。
嗯,我用SpringBoot 2.1.0和MySql创建了一个小项目。
这是我的购物车商品
public class CartItem {
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Id
@Column(name="id")
private Integer id;
@JsonIgnore
@ManyToOne
@JoinColumn(name="cart_id", nullable=false)
private Cart cart;
}
我的购物车:
public class Cart {
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Id
@Column(name="id")
private Integer id;
@OneToMany(mappedBy="cart", fetch = FetchType.EAGER)
private List<CartItem> cartItems;
}
Controller和你一样wrote.After在CartItem的cart filed中添加了一个@JsonIgnore,循环结束(在我这样做之前,程序确实有一个循环问题)。
每次在@oneToMany、@ManyToOne 或@ManyToMany 中使用 jpa 时,您都应该注意这种 problem.This 在实例化对象、打印对象或类似 this.And 当然有很多方法可以解决它,比如将获取类型更改为 LAZY,添加 @JsonIgnore,重写 toString() 和 equal() 方法。
这是一个序列化递归问题,它的发生是因为CartItem 有一个双向映射回Cart。所以发生的是
- 购物车序列化为 JSON
- 其中的所有 CartItems 都序列化为 JSON
- CartItem 中的购物车 属性 序列化为 JSON
- 购物车内的 CartItems 序列化为 json,等等
您可能希望通过使用 @JsonIgnore
注释标记 CartItem.cart 字段来将其从序列化中排除。
如果您直接在 Web 服务中使用 JPA 实体,那么很容易向外界公开过多的信息。 Jackson 实际上有一个有用的功能,称为 ,它允许您定义公开哪些属性,如果需要,您甚至可以根据网络服务调用对其进行定制。
我正在尝试使用 Spring 创建 REST 服务。 一切正常,直到我尝试将对象列表 (CartItem) 添加到我的主要对象 (Cart)。
这是我的主要对象
@Entity
@Table(name="cart")
public class Cart implements Serializable{
...
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Id
@Column(name="id")
private Integer id;
/*when I add this I get the error. If I remove this, the
REST service works*/
@OneToMany(mappedBy="cart", fetch = FetchType.EAGER)
private List<CartItem> cartItems;
//getter, setter, constructors, other fields ecc.
}
这是列表中的对象:
@Entity
@Table(name="cart_item")
public class CartItem implements Serializable{
...
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Id
@Column(name="id")
private Integer id;
@OneToOne(targetEntity = Product.class, cascade = CascadeType.ALL)
@JoinColumn(referencedColumnName="productId", name="product_id" )
private Product product;
@ManyToOne
@JoinColumn(name="cart_id", nullable=false)
private Cart cart;
//getter, setter, constructors, other fields ecc.
}
这是我的控制器
@RestController
@RequestMapping(value="rest/cart")
public class CartRestController {
...
@RequestMapping(value = "/", method = RequestMethod.GET)
public List<Cart> readAll() {
return cartService.read();
}
...
}
我收到这个错误:
SEVERE: Servlet.service() for servlet [dispatcher] in context with path
[/webstore] threw exception [Request processing failed; nested exception
is org.springframework.http.converter.HttpMessageNotWritableException:
Could not write JSON: Infinite recursion (WhosebugError); nested
exception is com.fasterxml.jackson.databind.JsonMappingException:
Infinite recursion (WhosebugError) (through reference chain:...
我想我必须以特定方式管理 Cart 对象中的 List,可能是因为我使用的是 JPA,但我仍然没有在 Internet 上找到解决方案。 谁能帮帮我?
永无止境的清单?您是指 Whosebug 异常吗?
如果情况就像我说的那样,那么你应该检查一些东西,比如获取类型和实体的 toString() 或 equal() 方法或类似的东西。
比如有实体A和B,它们是一对多的关系(A就是一个),如果你把它们的fetchType都配置为Eager,那么jpa查询A的时候,就会查询B too.But B也包含A,所以jpa会查询A again.This 那种循环会导致Whosebug。
顺便问一下,能否提供更多关于你的问题的信息,比如异常名称?我很难给你一个具体的解决方案,我只能告诉你一些我以前遇到的经验。
嗯,我用SpringBoot 2.1.0和MySql创建了一个小项目。
这是我的购物车商品
public class CartItem {
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Id
@Column(name="id")
private Integer id;
@JsonIgnore
@ManyToOne
@JoinColumn(name="cart_id", nullable=false)
private Cart cart;
}
我的购物车:
public class Cart {
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Id
@Column(name="id")
private Integer id;
@OneToMany(mappedBy="cart", fetch = FetchType.EAGER)
private List<CartItem> cartItems;
}
Controller和你一样wrote.After在CartItem的cart filed中添加了一个@JsonIgnore,循环结束(在我这样做之前,程序确实有一个循环问题)。
每次在@oneToMany、@ManyToOne 或@ManyToMany 中使用 jpa 时,您都应该注意这种 problem.This 在实例化对象、打印对象或类似 this.And 当然有很多方法可以解决它,比如将获取类型更改为 LAZY,添加 @JsonIgnore,重写 toString() 和 equal() 方法。
这是一个序列化递归问题,它的发生是因为CartItem 有一个双向映射回Cart。所以发生的是
- 购物车序列化为 JSON
- 其中的所有 CartItems 都序列化为 JSON
- CartItem 中的购物车 属性 序列化为 JSON
- 购物车内的 CartItems 序列化为 json,等等
- CartItem 中的购物车 属性 序列化为 JSON
- 其中的所有 CartItems 都序列化为 JSON
您可能希望通过使用 @JsonIgnore
注释标记 CartItem.cart 字段来将其从序列化中排除。
如果您直接在 Web 服务中使用 JPA 实体,那么很容易向外界公开过多的信息。 Jackson 实际上有一个有用的功能,称为