#hibernate #rest #spring-data-jpa #spring-rest
#спящий режим #отдых #spring-data-jpa #spring-rest
Вопрос:
Я создаю RESTful-приложение для весенней загрузки. У меня есть две сущности: посетители:
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private String email;
private String gender;
}
и продукты
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private int qty;
private int price;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "customer_id", referencedColumnName = "id")
private Customer customer;
}
Вот как я пытаюсь вставить Json через контроллер в объект OrderRequest:
@PostMapping("/placeOrder")
public Product saveOrder(@RequestBody OrderRequest request){
return productRepository.save(request.getProduct());
}
Класс OrderRequest:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OrderRequest {
private Product product;
}
Классы репозитория являются стандартными:
public interface ProductRepository extends JpaRepository<Product, Integer> {}
public interface CustomerRepository extends JpaRepository<Customer, Integer> {}
Я хочу, чтобы json выглядел так:
{
"product":{
"name":"Mobile",
"price":10000,
"qty":1,
"idCustomer": 1
}
}
Вопрос: Как я могу сделать так, чтобы с уже существующей строкой в таблице Customer я отправлял на сервер Json, в котором я указал только параметры продукта и параметр внешнего ключа, который был бы ссылкой на строку Customer ??Спасибо
Ответ №1:
Не рекомендуется предоставлять объекты уровня сохраняемости на уровне контроллеров, потому что ваш API соединяется с внутренним представлением данных.
Распространенным способом реализации вашего требования является использование шаблона объекта передачи. То есть создать отдельные классы для использования в API. В вашем случае вы можете создать класс ProductTO со следующей структурой:
public class ProductTO {
private int id;
private String name;
private int qty;
private int price;
private int customerId;
}
Затем вы можете сопоставить поля между ProductTO и Product вручную или использовать любую библиотеку сопоставления (например: MapStruct) для автоматического копирования значений полей с одинаковыми именами в обоих классах.
Внешний ключ должен быть назначен вручную:
Customer customer = this.customerRepo.findById(productTO.getCustomerId()).orElseThrow(() -> new YourException());
product.setCustomer(customer);
Комментарии:
1. Как я могу реализовать это с помощью mapstruct? @Satiago