Spring 数据 JPA 删除不是我预期的
Spring Data JPA deletions not what I expected
我认为直到最近我对 Spring Data JPA(删除)有了更好的理解。
无论如何,我有两个 类 与 OneToMany
和 ManyToOne
关系:
@Entity
@Table(name = "COMPANIES")
public class Company implements Serializable {
...
@OneToMany(mappedBy = "company",
fetch = FetchType.EAGER,
orphanRemoval = true,
cascade = CascadeType.ALL)
private Set<Commodity> commodities = new HashSet<>();
}
....
@Entity
@Table(name = "COMMODITIES")
public class Commodity implements Serializable {
...
@ManyToOne(optional = false)
@JoinColumn(name = "COMPANY_ID", referencedColumnName = "ID", nullable = false)
private Company company;
}
我想删除一条 Commodity
记录,所以我的服务层中有这个:
@Transactional
public void delete(Commodity commodity) {
repo.delete(commodity);
}
当我 运行 代码时,它会执行所有 SELECT 但它从未真正执行删除。没有错误消息...没有在日志中删除等
所以我发现我有两个选择:
1) 删除 CascadeType.ALL
2) 将我的删除方法更改为:
@Transactional
public void delete(Commodity commodity) {
Company company = commodity.getCompany();
company.getCommodities().remove(commodity);
companyRepo.save(company);
}
3) 编写自定义@Query 方法来执行删除(而不是)。
我对级联的理解是,如果我们要删除像公司这样的主记录,那么它的所有子对象都会被自动删除。这对我来说很有意义。
所以,我的问题是,为什么那个 CascadeType 会阻止我手动删除子记录?
谢谢
编辑
我不是很清楚。使用上面的选项 1 或选项 2 执行删除。
您的数据库可能阻止您删除记录。
检查你的 table 定义,看看你有哪种约束,或者尝试直接在 SQL 控制台中删除一些记录,看看你是否有任何错误。
要不,看看question 306144;希望能帮助到你。
更多信息:here
这是设计使然。
当您尝试自行删除商品时,拥有实体仍有记录表明该商品的实例仍应存在于数据库中。
这是来自休眠 doc 的确切引用:
Conversely, if an entity is removed from a collection (a one-to-many
or many-to-many association), it will not be deleted by default. This
behavior is completely consistent; a change to the internal state of
another entity should not cause the associated entity to vanish.
Likewise, adding an entity to a collection does not cause that entity
to become persistent, by default.
我认为直到最近我对 Spring Data JPA(删除)有了更好的理解。
无论如何,我有两个 类 与 OneToMany
和 ManyToOne
关系:
@Entity
@Table(name = "COMPANIES")
public class Company implements Serializable {
...
@OneToMany(mappedBy = "company",
fetch = FetchType.EAGER,
orphanRemoval = true,
cascade = CascadeType.ALL)
private Set<Commodity> commodities = new HashSet<>();
}
....
@Entity
@Table(name = "COMMODITIES")
public class Commodity implements Serializable {
...
@ManyToOne(optional = false)
@JoinColumn(name = "COMPANY_ID", referencedColumnName = "ID", nullable = false)
private Company company;
}
我想删除一条 Commodity
记录,所以我的服务层中有这个:
@Transactional
public void delete(Commodity commodity) {
repo.delete(commodity);
}
当我 运行 代码时,它会执行所有 SELECT 但它从未真正执行删除。没有错误消息...没有在日志中删除等
所以我发现我有两个选择:
1) 删除 CascadeType.ALL
2) 将我的删除方法更改为:
@Transactional
public void delete(Commodity commodity) {
Company company = commodity.getCompany();
company.getCommodities().remove(commodity);
companyRepo.save(company);
}
3) 编写自定义@Query 方法来执行删除(而不是)。
我对级联的理解是,如果我们要删除像公司这样的主记录,那么它的所有子对象都会被自动删除。这对我来说很有意义。
所以,我的问题是,为什么那个 CascadeType 会阻止我手动删除子记录?
谢谢
编辑
我不是很清楚。使用上面的选项 1 或选项 2 执行删除。
您的数据库可能阻止您删除记录。 检查你的 table 定义,看看你有哪种约束,或者尝试直接在 SQL 控制台中删除一些记录,看看你是否有任何错误。
要不,看看question 306144;希望能帮助到你。 更多信息:here
这是设计使然。
当您尝试自行删除商品时,拥有实体仍有记录表明该商品的实例仍应存在于数据库中。
这是来自休眠 doc 的确切引用:
Conversely, if an entity is removed from a collection (a one-to-many or many-to-many association), it will not be deleted by default. This behavior is completely consistent; a change to the internal state of another entity should not cause the associated entity to vanish. Likewise, adding an entity to a collection does not cause that entity to become persistent, by default.