【发布时间】:2022-11-12 05:58:14
【问题描述】:
我有 2 个 DTO“OrderItem”和“Ingredient”,两个类都有@ManyToMany注解:
@Entity
@Table
@NoArgsConstructor
@Data
public class OrderItem {
private @Id @GeneratedValue @NotNull long id;
@ManyToOne(optional = false)
@JoinColumn(nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
private Order order;
@ManyToOne(optional = false)
@JoinColumn(nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
private Food food;
private int quantity;
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(
name = "order_item_ingredient",
joinColumns = @JoinColumn(name = "order_item_id"),
inverseJoinColumns = @JoinColumn(name = "ingredient_name")
)
private Set<Ingredient> ingredients = new HashSet<>();
}
@Entity
@Table
@Data
@NoArgsConstructor
public class Ingredient {
private @Id String ingredientName;
private float basePrice;
private boolean addable;
@ManyToMany(mappedBy = "ingredients",cascade=CascadeType.ALL)
private Set<Food> foods= new HashSet<>();
@ManyToMany(mappedBy = "ingredients",cascade=CascadeType.ALL)
private Set<OrderItem> orderItems= new HashSet<>();
public Ingredient(String ingredientName, float basePrice, boolean addable) {
this.ingredientName = ingredientName.toLowerCase();
this.basePrice = basePrice;
this.addable = addable;
}
}
我正在寻找使用以下 @PostMapping 控制器函数的 POST 请求添加一个新的 OrderItem:
@PostMapping("{id}/orderItem")
public ResponseEntity<OrderItem> createMenuItem(
@PathVariable(value = "id") Long orderId,
@RequestBody OrderItem orderItem) {
Order order = orderService.getOrder(orderId)
.orElseThrow(() -> new ResourceNotFoundException("order '" + orderId + "' is not found"));
orderItem.setOrder(order);
orderItemRepository.save(orderItem);
return new ResponseEntity<>(orderItem, HttpStatus.CREATED);
}
当我向本地主机:8080/1/orderItem具有以下主体:
{
"order":"1",
"food":"burger",
"quantity":"1"
}
它工作正常并创建了一个新的 order_item 数据库记录,但是当我使用以下正文发送相同的请求时:
{
"order":"1",
"food":"burger",
"quantity":"1",
"ingredients": [{"ingredientName":"leaf"}]
}
它失败并给出以下 SQL 错误:
java.sql.SQLIntegrityConstraintViolationException: Duplicate entry 'leaf' for key 'ingredient.PRIMARY'
我知道这条记录已经存在,但是我如何告诉 Spring Boot 我希望它寻找现有的成分而不是尝试创建新的成分?
我有一个丑陋的解决方案,那就是发送订单项对象旁边的字符串列表,其中每个元素代表一个主键成分类,然后通过调用存储库的元素逐个遍历该列表元素以获取成分对象然后手动将其添加到OrderItem.ingredients,但我确信这不是最好的解决方案。
【问题讨论】:
标签: java spring-boot jpa many-to-many