唯一索引或主键违规 Spring JPA

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

我收到此主键约束错误

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.dao.DataIntegrityViolationException: could not execute statement [Unique index or primary key violation: "PUBLIC.CONSTRAINT_INDEX_3 ON PUBLIC.USER_TACO_ORDER_REF(TACO_ORDER_ID NULLS FIRST) VALUES ( /* 1 */ '52aca972-aeac-4305-9021-ad17ea1a0b07' )"; SQL statement:
insert into user_taco_order_ref (user_id,taco_order_id) values (?,?) [23505-220]] [insert into user_taco_order_ref (user_id,taco_order_id) values (?,?)]; SQL [insert into user_taco_order_ref (user_id,taco_order_id) values (?,?)]; constraint ["PUBLIC.CONSTRAINT_INDEX_3 ON PUBLIC.USER_TACO_ORDER_REF(TACO_ORDER_ID NULLS FIRST) VALUES ( /* 1 */ '52aca972-aeac-4305-9021-ad17ea1a0b07' )"

我在一个会话中保存多个 TacoOrder 对象。在一阶控制器中工作正常。它保存在数据库中并且没有错误。之后,我将其添加到用户的 tacoOrder 列表集合中,并作为 Cascade.ALL 自动保存。数据库每次都会重置,因此它只是列表中的一个对象。

在第二个订单中,我重置当前会话 TacoOrder 对象,它通过相同的控制器并添加到用户列表中,并且当休眠保留用户时。该列表也被持久化,但它现在有 2 个 tacoOrders,其中之一已经被持久化,保存这给了我错误。

这些是控制器和实体

@Transactional
@PostMapping("/current")
    public String processOrder(@ModelAttribute("order") @Valid TacoOrder order, Errors errors,
                               @AuthenticationPrincipal User user) {
        if(errors.hasErrors()){
            return "orderForm";
        }


        order.setUser(user);
        order.setPlacedAt(new Date());
        user.addTacoOrder(order);

        log.info("4 {} {}", order, user);  //LOG

        TacoOrder tacoOrder  = orderRepository.save(order);
        userService.updateUserFromOrder(user, tacoOrder);
        userRepository.save(user);

        log.info("Order submitted: {}", tacoOrder);   //LOG
        return "redirect:/orders";
    }
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinTable(
            name = "User_Taco_Order_Ref",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "tacoOrder_id"))
    private List<TacoOrder> tacoOrders = new ArrayList<>();

这些是日志:- 第一订单:

4 TacoOrder(id=52aca972-aeac-4305-9021-ad17ea1a0b07, placedAt=Fri Mar 29 04:07:34 IST 2024, deliveryName=a, deliveryStreet=a, deliveryCity=a, deliveryState=a, deliveryZip=a, ccNumber=4417123456789113, ccExpiration=11/2024, ccCVV=111, tacos=[Taco(id=1, createdAt=Fri Mar 29 04:07:24 IST 2024, name=Classic Beef Taco, ingredients=[Ingredient(id=FLTO, name=Flour Tortilla, type=WRAP), Ingredient(id=GRBF, name=Ground Beef, type=PROTEIN), Ingredient(id=CHED, name=Cheddar, type=CHEESE), Ingredient(id=LETC, name=Lettuce, type=VEGGIES), Ingredient(id=SLSA, name=Salsa, type=SAUCE)])])
User(id=1, username=admin, password=$2a$10$zpjL0V253nLpa1cH0j5sNOWKrfyikWjMZcXzc1TQ5HtttSgQgGi7O, roles=[ROLE_USER, ROLE_ADMIN], fullName=null, street=null, city=null, state=null, zip=null, phoneNumber=null, tacoOrders=[TacoOrder(id=52aca972-aeac-4305-9021-ad17ea1a0b07, placedAt=Fri Mar 29 04:07:34 IST 2024, (rest is same)

第二个命令:

4 TacoOrder(id=37808e6b-ed1d-4f38-8652-8c672b88d5e5, placedAt=Fri Mar 29 04:07:52 IST 2024, deliveryName=1, deliveryStreet=1, deliveryCity=1, deliveryState=1, deliveryZip=1, ccNumber=4417123456789113, ccExpiration=11/2024, ccCVV=111, tacos=[Taco(id=2, createdAt=Fri Mar 29 04:07:39 IST 2024, name=Spicy Carnitas Delight, ingredients=[Ingredient(id=COTO, name=Corn Tortilla, type=WRAP), Ingredient(id=CARN, name=Carnitas, type=PROTEIN), Ingredient(id=JALA, name=Jalapeños, type=VEGGIES), Ingredient(id=LETC, name=Lettuce, type=VEGGIES), Ingredient(id=SLSA, name=Salsa, type=SAUCE)])])
User(id=1, username=admin, password=$2a$10$zpjL0V253nLpa1cH0j5sNOWKrfyikWjMZcXzc1TQ5HtttSgQgGi7O, roles=[ROLE_USER, ROLE_ADMIN], fullName=null, street=a, city=a, state=a, zip=a, phoneNumber=null, tacoOrders=[TacoOrder(id=52aca972-aeac-4305-9021-ad17ea1a0b07, placedAt=Fri Mar 29 04:07:34 IST 2024,

, TacoOrder(id=37808e6b-ed1d-4f38-8652-8c672b88d5e5, placedAt=Fri Mar 29 04:07:52 IST 2024,

根据日志,第一顺序@id是

52aca972-aeac-4305-9021-ad17ea1a0b07

第二阶@id是

37808e6b-ed1d-4f38-8652-8c672b88d5e5

现在在第二个订单中,用户同时拥有第一个订单(已保存在 User_Taco_Order_Ref 表中)和尚未添加到 User_Taco_Order_Ref 表中的第二个新订单。 Hibernate 再次保存整个集合,并在保存已经持久保存的 taco 订单实例时给出此错误。 我该如何解决它?

java spring spring-boot hibernate jpa
1个回答
0
投票

错误是由于 USER 实体中 tacoOrder 列表上的 @JoinTable 注释造成的。 通过使用mappedBy,我们删除了这个额外的表,因为在OneToMany关系上使用joinTable是相当不常见的,并且hibernate不会再次添加已经持久化的实体。

© www.soinside.com 2019 - 2024. All rights reserved.