首页 > 解决方案 > 使用 Spring Data 时外键约束失败

问题描述

我正在使用 Spring Data 通过以下实体访问我的 MySQL 数据库

@Entity
@Table(name = "tbl_product")
public class Product implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)    private Long id;


    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn
    private Category category;
}

@Entity
@Table(name = "tbl_category")
public class Category implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true)
    private String name;
}

现在我尝试使用我Controller的删除Product

@RequestMapping(path="/remove/{id}", method=RequestMethod.DELETE)
    @ResponseBody
    public String removeProduct(@PathVariable Long id) {
        return productService.removeProduct(id);
    }

public String removeProduct(Long productID) {
        try {
            productRepository.delete(productID);
            return "OK";
        } catch (Exception e) {
            logger.info(e.getMessage());
            return "Error";
        }
    }

现在,例如,如果有 3 个ProductsCategoryA 和 1 个带CategoryB,我可以删除带 B 的那个Category。但是如果我尝试删除任何其他的,我得到了

无法删除或更新父行:外键约束失败 ( product_db. tbl_product, CONSTRAINT FKfq7110lh85cseoy13cgni7pet FOREIGN KEY ( category_id) REFERENCES tbl_category( id))

标签: mysqlspringspring-data

解决方案


这是因为您正在申请的级联cascade = CascadeType.ALL

因此,每当您删除任何产品时,JPA 也会删除类别 ID。如果该类别不与任何其他产品相关联(这是在您的第二种情况下发生的情况),它会很好地工作。但是,如果该类别与任何其他产品相关联,则外键约束将失败,说明您尝试删除的类别与其他产品相关联。

提到级联类型时应该非常小心。默认情况下,级联模式为 NONE,但您可以根据您的要求提供不同的策略,如 UPDATE、PERSIST 等


推荐阅读