如何编写实体并发布带有外键的表的请求(按ID)

问题描述 投票:0回答:2

我有一个带有两个FK制造商和类别的“产品”表。我想编写一个查询,以便在添加产品时不会每次都创建制造商,而是从可用的产品中按ID选择它。uml diagram for tables我现在有:我的产品实体:

    @ManyToOne(fetch = FetchType.EAGER, optional = false)
    @JoinColumn(name="manufactor",  referencedColumnName = "id")
    private Manufactor manufactor;

    public void setManufactor(Manufactor manufactor) {
        this.manufactor = manufactor;  }

    public Manufactor getManufactor() {
        return manufactor;  }

我的控制器:

    @RequestMapping(value = "/addProduct", method = RequestMethod.POST)
    public Product addNewProduct (@RequestBody Product product ) {
        return productRepository.save(product);
    }

我的请求应如下所示:

{   "name": "Alakazai",
    "quantity": 1,
    "price": 58,
    "manufactor": 2,
    "category": 3
}

但是当我使用邮递员时出现错误:

    "status": 400,
    "error": "Bad Request",
    "message": "Invalid JSON input: Cannot construct instance of `com.store.Entity.Manufactor` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (1); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.store.Entity.Manufactor` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (1)\n at [Source: (PushbackInputStream); line: 5, column: 16] (through reference chain: com.store.Entity.Product[\"manufactor\"])",

我犯了什么错误?在产品实体中还是其他地方?我很乐意提供任何解释

如果需要,我在github上的项目:Project

java mysql maven http
2个回答
1
投票

您不应尝试保留在控制器层中。

更好的做法是拥有一个与json主体匹配的ProductForm类。接下来,您可以对其进行检查(示例为正价),然后使用实体将其转换为Product实例以映射您的工厂,然后将其持久化。

例如:

Controller:

@RequestMapping(value = "/addProduct", method = RequestMethod.POST)
public Product addNewProduct (@RequestBody ProductForm product ) {
    return productservice.register(product);
}

[ProductForm:

public class ProductForm{

    private String name;
    private int price;
    private int quantity;
    private int manufactor;
    private int category;

    //Add getters & setters here
    //...

}

服务:

public Product register(ProductForm form) {
    checkForm(form); //business checks goes here, should raise exception if failure
    Product product = new Product();
    product.setPrice(form.getPrice());
    product.setName(form.getName());
    product.setQuantity(form.getQuantity());
    product.setCategory(categoryRepository.findById(form.getCategory()));
    product.setManufactor(manufactorRepository.findById(form.getManufactor()));
    return productRepository.save(product);
}

0
投票

您在工厂中有一个@OneToMany to Product类吗?像这样:

@OneToMany(
        mappedBy = "manufactor",
        cascade = CascadeType.ALL,
        orphanRemoval = true
    )
List<Product> products = new ArrayList<>() 

我要做的是:

  • 在工厂中添加一个@OneToMany
  • 创建一个DTO层(您不应使用持久化对象来发出REST请求)。在该层中,创建一个类似于Product的DTO对象,但是添加一个生产商ID。或者只是创建Product类的副本,然后在帖子中添加一个路径变量,在其中放置生产商ID。
  • 在控制器中,从dto或pathpath变量中获取制造商ID,在db上进行查找,将制造商对象放在要存储的产品上并进行保存。
© www.soinside.com 2019 - 2024. All rights reserved.