多对一:JSON 解析错误无法构造实例

Many-To-One : JSON parse error Cannot construct instance

我开发了一个 REST API 使用 spring 启动 我有两个具有双向 OneToMany

的实体

产品class

public class Product {

    private Long productId;
    private String name;
    private String description;
    private List<ProductList> productList;


    public Product() {
    }


    public Product(Long productId, String name, String description, List<ProductList> productList) {
        this.productId = productId;
        this.name = name;
        this.description = description;
        this.productList = productList;
    }


    public Long getProductId() {
        return productId;
    }

    public void setProductId(Long productId) {
        this.productId = productId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public List<ProductList> getProductList() {
        return productList;
    }

    public void setProductList(List<ProductList> productList) {

        this.productList = productList;
    }

产品列表class

public class ProductList {

    private Long productListId;
    private String productListName;
    private Product product;


    public ProductList(Long productListId, String productListName, Product product) {
        this.productListId = productListId;
        this.productListName = productListName;
        this.product = product;
    }


    public ProductList() {
    }


    public Long getProductListId() {
        return productListId;
    }

    public void setProductListId(Long productListId) {
        this.productListId = productListId;
    }

    public String getProductListName() {
        return productListName;
    }

    public void setProductListName(String productListName) {
        this.productListName = productListName;
    }

    public Product getProduct() {
        return product;
    }

    public void setProduct(Product product) {
        this.product = product;
    }
}

ProductEntity class:

@Entity
@Data
@Table(name = "PRODUCT")

public class ProductEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
private Integer productId;

@Column
private String name;

@Column
private String description;

@OneToMany(cascade = CascadeType.ALL, mappedBy="product", fetch = 
FetchType.EAGER)
private List<ProductListEntity> productList;
// Getters,Setters,No-ArgCOnstructor, All-ArgConstructor

ProductListEntity class:

@Table
@Entity
@Data
public class ProductListEntity {


@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long productListId;
private String productListName;


@ManyToOne(fetch = FetchType.EAGER, targetEntity = ProductEntity.class)
@JoinColumn(name = "FK_Product", referencedColumnName = "productId")
private ProductEntity product;

保存数据服务:

public void addProduct(Product product) {
    ProductEntity productEntity = new ProductEntity();
    BeanUtils.copyProperties(product, productEntity);
    productRepository.save(productEntity);
}

当我尝试 post 时出现此错误:

"message": "JSON parse error: Cannot construct instance of eteosf.hexagonal.domain.model.Product (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('string'); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of eteosf.hexagonal.domain.model.Product (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('string')\n at [Source: (PushbackInputStream); line: 9, column: 18] (through reference chain: eteosf.hexagonal.domain.model.Product["productList"]->java.util.ArrayList[0]->eteosf.hexagonal.domain.model.Product$ProductList["product"])", "path": "/product"

JSON 请求正文:

{
  "productId": 0,
  "name": "string",
  "description": "string",
  "productList": [
    {
      "productListId": 0,
      "productListName": "string",
      "product": "string"
    }
  ]
}

在您的 json_request 中,您在 productList 中将“产品”作为“字符串”发送。但是 Deserializer 不能将该字符串转换为 Product 对象。它必须作为对象 {} 发送。您可以将该对象留空 - 如果它所做的只是指向自身,则不发送它。

你基本上犯了一个混淆不同原则的错误——整个双向关系只适用于持久层。 Json 请求在 controller/view 级别发送,因此您无法以相同的方式显示双向性质。这就是为什么您不使用实体作为控制器参数而是使用 DTO 的原因。

在你的情况下,不要为控制器发送“产品”字段:

{
  "productId": 0,
  "name": "string",
  "description": "string",
  "productList": [
    {
      "productListId": 0,
      "productListName": "string",
    }
  ]
}

收到参数后直接在controller方法中添加:

//the receiving controller method which got Parameter `ProductEntity product`
product.getProductList().forEach(productList -> productList.setProduct(product);

就像我说的,你不应该在 Controller 方法中使用实体,它应该是一个 DTO class 为了避免这种问题