当前位置: 首页 > 面试题库 >

REST控制器中具有一对多关系的实体的递归JSON视图

赫连泰宁
2023-03-14
问题内容

我正在使用SpringBoot和JPA构建REST接口。

现在,对于从数据库中获取的产品列表,我返回了一个奇怪的JSON。假设我有:

@Entity
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @JoinColumn(name = "categoryId", nullable = false, updatable = false)
    private Category category;

    ...
}

@Entity
public class Category implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToMany(mappedBy = "category", cascade = CascadeType.DETACH)
    @OrderBy("name ASC")
    private List<Product> products = Collections.emptyList();

    ...
}

的JPA存储库Product定义为:

public interface ProductRepository extends JpaRepository<Product, Long> {
    List<Product> findAll();
}

在我的控制器中,我有:

@Autowired
private ProductRepository productRepo;

@RequestMapping("/all-products", method = RequestMethod.GET)
public Map<String,Object> home() {
    Map<String,Object> model = new HashMap<String,Object>();
    model.put("products", productRepo.findAll());
    return model;
}

使我发疯的是,如果我尝试按以下方式致电此服务:

$ curl localhost:8080/all-products

由于表product和之间的关系,我得到了递归输出category,例如:

{"products":[{"id":1,"name":"Product1","category":
{"id":1,"name":"Cat1","products":[{"id":6,"name":"Product6","category":
{"id":1,"name":"Cat1","products":[{"id":6,"name":"Product6","category":
{"id":1,...

我究竟做错了什么?


问题答案:

您没有做错任何事情(至少在代码级别上是概念上的)-json序列化器如下所示:

  1. 产品-对其进行序列化,但是请稍候-有一个类别字段,因此序列化程序必须对类别字段进行序列化
  2. 类别-对其进行序列化,但是请稍候-有一个product字段,因此序列化程序必须序列化列表中的每个产品
  3. 产品-由于您的收藏包含产品和产品包含类别,因此它会不断循环直到超时。

您必须使用视图或只是跳过它。

  1. @JsonView

  2. 将视图用作new ProductView具有产品的所有字段和对new CategoryView(您可以在此处结束)具有(产品)集合的引用(类别)的POJO Return ,new ProductViewWithoutReferences依此类推

  3. 用于@JsonIgnore一系列产品

另外请注意-
如果是,@RestController并且您正在调用“所有产品”,则返回除列表以外的其他内容有点不寻常。将响应包装在映射中是多余的。许多其他客户端在调用list()方法时都希望有一个列表。



 类似资料:
  • 当我有用户并且他们有其他用户作为朋友时,我想让应用程序类似于facebook。因此,我创建了一个实体

  • 问题内容: 另一个hibernate问题…:P 使用Hibernate的Annotations框架,我有一个实体。每个人都可以有一个朋友的集合:其他的集合。但是,我还无法弄清楚如何在由s 列表组成的类中创建多对多关联(使用用户友好中间表)。 这是User类及其注释: 用户- 朋友映射表只有两列,这两列都是该表列的外键。两列是(应映射到当前用户)和(指定当前用户的朋友的ID)。 问题是,即使我已经预

  • 我的两个实体有一对一的关系 我尝试通过此方法删除我的用户实体 PasswordResetTokenRepository类,我在服务方法中调用了该类,用于删除用户,我使用了常规Hibernate方法deleteById(Long id) 但是当我尝试通过此方法删除时,出现此错误:not-null 属性引用 null 或瞬态值:kpi.diploma.ovcharenko.entity.user.Pa

  • 我有一个JPA实体(人)与其他实体(地址)有多对一的关系。在一个对象可以被系统使用之前,这个对象必须得到主管的批准。我将原始实体存储为byte[]并对“工作”实体进行更改,并将其存储在数据库中。如果这些更改不被批准,我必须恢复原始状态。因此,我将存储的原始数据从byte[]中转换出来,并使用实体管理器将其合并到数据库中。所有的工作都很好,但是如果一个新的地址实体已经添加到“工作”的人,在合并还原的

  • 我有一个实体: 要创建上述实体并将其保存到JPA存储库中,我将执行以下操作: 由于DB中的表存储了候选对象的FK,我认为设置一个id就足够了。但JPA希望我设置候选对象。这迫使我查询候选存储库。 是否需要从候选库中查询候选人以保存,或者如果我有可用的候选人id,我不能直接设置它?

  • 我有问题与复制实体与多对多的关系。我有三个实体公司,角色和用户定义如下: 我使用迁移在db中创建表,显然EF创建了TUserRole表(到目前为止一切都很好)。 现在,我想创建company和users的副本,但不复制角色(所以我想在TCompany、TUser和TUserRole表中创建新记录,但在TRole中不创建新记录)。 我以为这样的方法会奏效,但我遇到了例外: 我用的是EF 6.1.3。