簡體   English   中英

如何為具有外鍵的表編寫實體和發布請求(按 id)

[英]How to write entity and post request for a table with a foreign key (by id)

我有一個帶有兩個 FK 制造商和類別的表“產品”。 我想寫一個查詢,這樣當你添加一個產品時,你不會每次都創建一個制造商,而是 select 它是通過可用產品中的 id 來創建的。 表的uml圖 現在我有: 我的產品實體:

    @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;  }

我的 Controller:

    @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
}

但是當我使用 postman 我有錯誤:

    "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 上的項目:項目

您不應該嘗試堅持 controller 層。

更好的做法是使用與 json 主體匹配的 class ProductForm。 接下來,您可以對其進行檢查(例如正價),然后使用實體將其轉換為 Product 實例到您的制造商 map,然后將其持久化。

舉例:

Controller:

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

產品形式:

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);
}

您在制造商中有 @OneToMany 到產品 class 嗎? 像這樣:

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

我要做的是:

  • 在 Manufactor 中添加 @OneToMany
  • 創建一個 DTO 層(您不應使用持久化的 object 來發出 REST 請求)。 在該層中,像 Product 一樣創建 DTO object,但添加制造商 ID。 或者只是創建產品 class 的副本,然后在帖子中添加一個路徑變量,在其中放置制造商 ID。
  • 在 controller 中,從 dto 或路徑變量中獲取制造商 ID,在 db 上查找,將制造商 object 放在要存儲的產品上並保存。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM