You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot电商项目:商品存购物清单后未从购物车删除问题排查

问题描述

我正在开发基于Java Spring Boot的电商应用,用户商品存储在购物车表中。需求是商品完成配送时,将该商品从购物车表移除并存入购物清单表。目前遇到异常:传入商品ID和用户认证密钥后,成功返回'商品已移除'提示,商品也已存入购物清单表,但未从购物车表中删除。

相关代码

Cart 实体类

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Cart {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private Date createdDate;
    @ManyToOne
    @JoinColumn(name = "product_id")
    private Product product;
    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;
    private int quantity;
}

ShoppingList 实体类

@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
public class ShoppingList {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private Date createdDate;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "cart_id")
    private Cart cart;
    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "user_id")
    private User user;
    private String status;
}

CartRepository

@Repository
public interface CartRepository extends JpaRepository<Cart,Integer> {
    List<Cart> findAllByUserOrderByCreatedDateDesc(User user);
}

ShoppingListRepository

@Repository
public interface ShoppingListRepository extends JpaRepository<ShoppingList,Integer> {
    List<ShoppingList> findAllByUserOrderByCreatedDateDesc(User user);
}

CartService

@Service
public class CartService {
    @Autowired
    private CartRepository cartRepository;

    @Autowired
    private ProductService productService;
    @Autowired
    private ShoppingListService shoppingListService;

    public void addToCart(AddToCartDto addToCartDto, User user) throws DataNotFoundException {
        Product product = productService.findById(addToCartDto.getProductId());
        Cart cart = new Cart();
        cart.setCreatedDate(new Date());
        cart.setProduct(product);
        cart.setUser(user);
        cart.setQuantity(addToCartDto.getQuantity());
        cartRepository.save(cart);
    }

    public void deleteCartItemByAdmin(Integer cartItemId, User user) throws DataNotFoundException {
        Optional<Cart> optionalCart = cartRepository.findById(cartItemId);
        if (optionalCart.isEmpty()){
            throw new DataNotFoundException("Item Id Not Found");
        }
        Cart cart = optionalCart.get();
        if (cart.getUser()!=user){
            throw new DataNotFoundException("The Item doesn't belongs to this user");
        }
        ShoppingList shoppingList = new ShoppingList();
        shoppingList.setCart(cart);
        shoppingList.setCreatedDate(new Date());
        shoppingList.setUser(cart.getUser());
        shoppingList.setStatus("Delivered");
        shoppingListService.addToShoppingList(shoppingList);
        cartRepository.delete(cart);
    }
}

ShoppingListService

@Service
public class ShoppingListService {
    @Autowired
    private ShoppingListRepository shoppingListRepository;

    public void addToShoppingList(ShoppingList shoppingList){
        shoppingListRepository.save(shoppingList);
    }
}

CartController

@DeleteMapping("/delete/by/admin/{itemId}")
public ResponseEntity<ApiResponse> deleteItemByAdmin(@PathVariable("itemId")Integer itemId,
                                                     @RequestParam("token") String token) throws DataNotFoundException {
    authenticationTokenService.authenticateToken(token);
    User user = authenticationTokenService.getUserByToken(token);
    cartService.deleteCartItemByAdmin(itemId,user);
    return new ResponseEntity<>(new ApiResponse(true,"Item deleted Successfully from the Cart"),HttpStatus.OK);
}
问题原因与修复方案

核心原因

ShoppingList实体中@ManyToOne(cascade = CascadeType.ALL)注解引发级联操作冲突:
调用shoppingListRepository.save(shoppingList)时,CascadeType.ALL会触发对关联Cart对象的全量级联操作,包括重新持久化/更新。这导致原本要删除的Cart对象被JPA重新写入数据库,覆盖了后续的删除操作。

修复步骤

  1. 调整ShoppingList的级联策略
    将Cart字段的级联类型从CascadeType.ALL改为仅保留必要的操作,或直接移除不必要的级联(因为Cart已是持久化状态,无需级联持久化,更不需要级联更新):

    @ManyToOne
    @JoinColumn(name = "cart_id")
    private Cart cart;
    // 若需保留基础级联,可改为:@ManyToOne(cascade = CascadeType.PERSIST)
    
  2. 添加事务控制确保操作原子性
    在CartService的deleteCartItemByAdmin方法上添加@Transactional注解,确保存入购物清单和删除购物车的操作在同一个事务中执行,避免部分提交:

    @Transactional
    public void deleteCartItemByAdmin(Integer cartItemId, User user) throws DataNotFoundException {
        // 原方法逻辑不变
    }
    
  3. 优化用户关联校验逻辑
    原代码中cart.getUser()!=user是对象引用比较,存在空指针或引用不一致风险,建议改为ID值比较:

    if (!cart.getUser().getId().equals(user.getId())) {
        throw new DataNotFoundException("The Item doesn't belongs to this user");
    }
    

内容的提问来源于stack exchange,提问作者Ukeme Elijah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 12:03:24