一对多和删除级联表约束



我在账户和交易之间有一个双向的一对多:

@Entity
public class Account {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "account", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private List<Transaction> transactions = new ArrayList<>();
...
}
@Entity
public class Transaction {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@ManyToOne
@JoinColumn(name = "ACCOUNT_ID")
private Account account;
...
}

外键定义了 ON DELETE CASCADE 约束:

alter table transaction
add constraint FK6
foreign key (account_id)
references account(id) on delete cascade;

但是,在删除"帐户"记录时,为什么休眠会逐个删除相关的"交易"记录:

acidTest(entityManager -> {
Account _account = entityManager.find(Account.class, pk);
assertThat(_account.getTransactions().size(), is(2));
});
acidTest(entityManager -> {
Account account = entityManager.find(Account.class, 1L);
entityManager.remove(account);
});

日志:

09:17:56.216 [main] DEBUG c.l.hibernate.JPATxBoundedTest - [TX: begin -->
Hibernate: 
select
account0_.id as id1_0_0_,
...
from
account account0_ 
where
account0_.id=?
09:17:56.223 [main] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [BIGINT] - [5]
Hibernate: 
select
transactio0_.account_id as account_4_14_0_,
transactio0_.id as id1_14_0_,
... 
from
transaction transactio0_ 
where
transactio0_.account_id=?
09:17:56.230 [main] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [BIGINT] - [5]
Hibernate: 
delete from transaction where id=?
09:17:56.241 [main] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [BIGINT] - [14]
Hibernate: 
delete from transaction where id=?
09:17:56.245 [main] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [BIGINT] - [16]
Hibernate: 
delete from account where id=?
09:17:56.249 [main] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [BIGINT] - [5]
09:17:56.260 [main] DEBUG c.l.hibernate.JPATxBoundedTest - <-- end: TX]

我希望休眠跳过删除"事务",因为我没有在帐户>事务关系上指定CascadeType.DELETE。什么给?

(添加CascadeType.MOVE也触发了同一组SQL(

  1. 对关系启用休眠特定@OnDelete
@OneToMany(mappedBy = "account", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@org.hibernate.annotations.OnDelete(
action = org.hibernate.annotations.OnDeleteAction.CASCADE)
private List<Transaction> transactions = new ArrayList<>();
    @OnDelete 仍然是必需的,即使
  1. 休眠不管理我的 DDL:
spring.jpa.hibernate.ddl-auto=none
  1. 如果您使用的是MySQL(我愿意!(,请确保您的存储引擎是InnoDB,它支持外键上的ON DELETE CASCADE。

最新更新