【问题标题】:JSON calls object recursively when posting itJSON在发布时递归调用对象
【发布时间】:2017-09-07 08:51:00
【问题描述】:

我正在通过 Swagger 测试我的应用程序,当尝试发布包含其他对象列表的对象时,我收到错误 java.lang.StackOverflowError。基本上,我正在尝试编写一张发票,以 Swagger 形式表示为 JSON,在填写发票数据时,我注意到发票项目包含发票的重复字段。

{
  "date": "2017-08-27",
  "counterparty": {
    "address": {
      "houseNumber": "string",
      "streetName": "string",
      "townName": "string",
      "zipCode": "string"
    },
    "bankName": "string",
    "bankNumber": "string",
    "companyName": "string",
    "nip": "string",
    "phoneNumber": "string"
  },
  "invoiceItems": [
    {
      "amount": 0,
      "description": "string",
      "id": 0,
      "invoice": { //SHOULD NOT BE HERE
        "id": 0,
        "date": "2017-09-07",
        "counterparty": {
          "address": {
            "houseNumber": "string",
            "streetName": "string",
            "townName": "string",
            "zipCode": "string"
          },
          "bankName": "string",
          "bankNumber": "string",
          "companyName": "string",
          "nip": "string",
          "phoneNumber": "string"
        },
        "invoiceItems": [
          {}
        ]
      },
      "numberOfItems": 0,
      "vat": "VAT_23",
      "vatAmount": 0
    }
  ]
}

@Entity
@Table(name = "invoices")
public class Invoice implements Comparable<Invoice> {

      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      @Column(name = "invoice_id")
      private int id;
      @Column(name = "date")
      private LocalDate date = LocalDate.now();
      @OneToOne(mappedBy = "invoice", cascade = {CascadeType.DETACH, CascadeType.MERGE,
          CascadeType.PERSIST, CascadeType.REFRESH})
      private Counterparty counterparty;

      @OneToMany(mappedBy = "invoice", cascade = {CascadeType.PERSIST, CascadeType.MERGE,
          CascadeType.DETACH, CascadeType.REFRESH})
      private List<InvoiceItem> invoiceItems = new ArrayList<>();

@Entity
@Table(name = "items")
public class InvoiceItem {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "item_id")
  private int id;
  private String description;
  private int numberOfItems;
  private BigDecimal amount;
  private BigDecimal vatAmount;

  @JoinColumn(name = "vat_code")
  @Enumerated(EnumType.ORDINAL)
  private Vat vat;

  @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST,
      CascadeType.REFRESH})
  @JoinColumn(name = "invoice_id")
  private Invoice invoice;

我与 Counterparty 有相同的映射,但它没有以 JSON 格式显示发票数据:

@Id
  private String nip;
  private String companyName;
  private String phoneNumber;
  private String bankName;
  private String bankNumber;

  @OneToOne(fetch = FetchType.LAZY, mappedBy = "counterparty", cascade = CascadeType.ALL)
  private Address address;

  @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST,
      CascadeType.REFRESH})
  @JoinColumn(name = "invoice_id")
  private Invoice invoice;

也许我的注释存在一些问题,即递归调用发票?

【问题讨论】:

    标签: java hibernate jpa spring-boot persistence


    【解决方案1】:

    您应该使用 @JsonIgnore 注释在 InvoiceItems 上标记您的 Invoice 属性,这意味着当 InvoiceItems 被序列化时它不会被序列化为 JSON,这应该可以防止您的无限递归 JSON 问题:

     @Entity
     @Table(name = "items")
     public class InvoiceItem {
    
     ...
    
         @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST,
          CascadeType.REFRESH})
         @JoinColumn(name = "invoice_id")
         @JsonIgnore
         private Invoice invoice;
    

    【讨论】:

      猜你喜欢
      • 2014-11-08
      • 2013-12-02
      • 2017-03-26
      • 1970-01-01
      • 2021-10-10
      • 1970-01-01
      • 2019-09-03
      • 2016-10-17
      • 2015-06-04
      相关资源
      最近更新 更多