Как написать сущность и опубликовать запрос для таблицы с внешним ключом (по идентификатору) - PullRequest
0 голосов
/ 30 апреля 2020

У меня есть таблица «продукт» с двумя ФК производитель и категория. Я хочу написать запрос так, чтобы при добавлении товара вы не каждый раз создавали производство, а выбирали его по идентификатору из доступных. uml diagram for tables Теперь у меня есть: Мой объект Product:

    @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: Проект

Ответы [ 2 ]

1 голос
/ 30 апреля 2020

Не следует пытаться сохраняться на уровне контроллера.

Лучше было бы иметь класс ProductForm, который соответствует телу json. Затем вы можете проверить его (положительная цена на примере), затем преобразовать его в экземпляр продукта, используя сущности для сопоставления вашего производителя, и затем сохранить его.

Пример:

Контроллер:

@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 голосов
/ 30 апреля 2020

Есть ли у Производителя класс @OneToMany to Product? Например:

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

Я бы сделал следующее:

  • добавьте @OneToMany в Manufactor
  • создайте слой DTO (вы не должны использовать постоянный объект для выполнения запросов REST). В этом слое создайте объект DTO, такой как Product, но добавьте идентификатор производителя. Или просто создайте копию класса Product и в сообщении добавьте переменную пути, в которой вы указали идентификатор производителя.
  • в контроллере, возьмите идентификатор изготовителя из dto или из переменной пути, найдите в db, поместите объект изготовителя в продукт, который должен быть сохранен, и сохраните.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...