级联类型 ALL 违反参照完整性约束

Referential integrity constraint violation with Cascade type ALL

我需要你的帮助来解决以下问题:有一个 spring 引导项目,它有两个实体: Bank和CreditDetails,银行称明细为OneToMany,明细为ManyToOne。 在 Bank 实体中,级联类型是 ALL,但是当我尝试删除银行时,出现错误,可能是什么问题?

银行:

@Entity
@Table(name = "banks")
@Getter
@Setter
@NoArgsConstructor
public class Bank {

    @Id
    @Column(name = "bank_id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private UUID id;

    @OneToMany(orphanRemoval = true,cascade = CascadeType.ALL,
            mappedBy = "bank", fetch = FetchType.LAZY)
    private List<CreditDetails> creditDetails = new ArrayList<>();

    @OneToMany(orphanRemoval = true,cascade = CascadeType.ALL,
            mappedBy = "bank", fetch = FetchType.LAZY)
    private List<Client> clients = new ArrayList<>();
}

信用详情:

@Entity
@Table(name = "credit_details")
@Getter
@Setter
@NoArgsConstructor
public class CreditDetails {

    @Id
    @Column(name = "credit_details_id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private UUID id;

    @Column(name = "credit_limit")
    private BigDecimal creditLimit;

    @Column(name = "credit_percent")
    private BigDecimal creditPercent;

    @ManyToOne(targetEntity = Bank.class, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, fetch = FetchType.EAGER)
    @JoinColumn(name = "bank_id")
    private Bank bank;

    @OneToMany(cascade = CascadeType.ALL,
            mappedBy = "creditDetails")
    List<CreditOffer> creditOffers;
}

DB(H2) 中的实体

create table banks
(
    bank_id uuid primary key
);

create table credit_details
(
    credit_details_id uuid primary key,
    credit_limit      bigint,
    credit_percent    numeric(5, 2),
    bank_id           uuid references banks (bank_id),
    primary key (credit_details_id)
);

堆栈跟踪:

违反引用完整性约束:“CONSTRAINT_8:PUBLIC.CREDIT_DETAILS FOREIGN KEY(BANK_ID) REFERENCES PUBLIC.BANKS(BANK_ID) ('ae1ce5c1-b1eb-4ee7-a1a2-63d831b0fd0a' )";

我使用 spring、hibernate、H2 数据库和 Postgres 数据库重建了您的设置。对我来说,一切都按预期进行。

为了测试我使用 BankRepository 的实体:

public interface BankRepository extends CrudRepository<Bank, UUID> {}

和一个非常简单的 RestController:

private final BankRepository bankRepository;

@DeleteMapping
public void removeBank(@RequestParam String uuid) {
    bankRepository.deleteById(UUID.fromString(uuid));
}

@PostMapping("/add")
public Bank addBank() {
    var bank = new Bank();

    var creditDetails = new CreditDetails();
    creditDetails.setBank(bank);
    bank.setCreditDetails(List.of(creditDetails));

    bankRepository.save(bank);

    return bank;
}

如果您尝试通过某些 SQL 直接删除 Bank 实体,或者如果您手动将其从数据库中删除,您可能会遇到错误。你能设置

spring.jpa.show-sql: true

和 post 生成的 JPA 查询?我的看起来像这样:

Hibernate: select bank0_.bank_id as bank_id1_1_0_ from banks bank0_ where bank0_.bank_id=?
Hibernate: select creditdeta0_.bank_id as bank_id4_2_0_, creditdeta0_.credit_details_id as credit_d1_2_0_, creditdeta0_.credit_details_id as credit_d1_2_1_, creditdeta0_.bank_id as bank_id4_2_1_, creditdeta0_.credit_limit as credit_l2_2_1_, creditdeta0_.credit_percent as credit_p3_2_1_ from credit_details creditdeta0_ where creditdeta0_.bank_id=?
Hibernate: delete from credit_details where credit_details_id=?
Hibernate: delete from banks where bank_id=?