我有一些由Hibernate管理的表,有各种外键约束。 Cascade on delete目前仅由Hibernate管理。为了解决测试数据,我经常手动创建和删除一些行。如果我可以将ON DELETE CASCADE添加到外键约束中,那将对我有很大的帮助,但我不知道Hibernate是否因为数据库在Hibernate之前删除了东西而绊倒了。
很多人似乎都专注于DDL。我的意图是不来指示Hibernate使用SQL DELETE CASCADES创建DDL。我只是想知道如果我在数据库中添加>>指定ON DELETE CASCADE以使JPA cascade = CascadeType.REMOVE
在参考注释上,例如@ManyToOne
,是否会造成任何伤害。
答案 0 :(得分:2)
您可以使用CascadeType.DELETE
,但此注释仅适用于EntityManager
中的对象,而不适用于数据库。您希望确保将ON DELETE CASCADE
添加到数据库约束中。要进行验证,您可以配置JPA以生成ddl文件。看一下ddl
文件,您会注意到ON DELETE CASCADE
不是约束的一部分。将ON DELETE CASCADE
添加到ddl
文件中的实际SQL,然后从ddl更新数据库模式。这将解决您的问题。
此link显示了如何在MySQL中ON DELETE CASCADE
使用CONSTRAINT
。您可以在约束上执行此操作。您也可以在CREATE TABLE
或ALTER TABLE
语句中执行此操作。 JPA可能会在ALTER TABLE
语句中创建约束。只需将ON DELETE CASCADE
添加到该语句中即可。
请注意,某些JPA实现者确实提供了此功能的方法。
Hibernate使用@OnDelete
注释提供此功能,因此如果您希望坚持使用标准JPA功能,则首选使用此功能或仅更新ddl文件。
答案 1 :(得分:2)
我发现了两个潜在的问题:
在某些情况下可能存在其他一些可能存在问题的情况,因此我建议不来执行此操作。
答案 2 :(得分:0)
您可以使用本机数据库功能在删除父记录时删除子记录。
请注意双向关系,并确保您只需指定级联插入和更新(更安全的一面)。
答案 3 :(得分:0)
您提及测试目的。我猜测,执行一些测试,删除数据,重播测试...
使用二级缓存或查询缓存时,如果直接从数据库中删除数据,缓存将会过时。 这可能会导致意外的测试结果。
所以是的,如果您使用二级/查询缓存,这将与Hibernate冲突,因为实体不会从缓存中逐出。确保在直接删除任何数据后清除所有缓存。 See this question on how to clear cache.
官方Hibernate docs也提到了这个:
请注意,缓存不了解其他应用程序对持久性存储所做的更改。但是,它们可以配置为定期使缓存的数据到期。
答案 4 :(得分:0)
在orphanRemoval = true
关系中使用@OneToMany
子句。然后,当主实体(ParameterGroup)被删除时,每个相关记录(参数)将首先被删除。只需通过entityManager删除ParameterGroup实体。还记得将cascade
子句设置为CascadeType.ALL
(支持所有级联操作)或CascadeType.REMOVE
(仅支持级联删除)。
@Entity
@Table(name = "PARAMETER_GROUP")
public class ParameterGroup {
@Id
private Long id;
@OneToMany(mappedBy = "parameterGroup", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<Parameter> parameters = new LinkedList<>();
}
@Entity
@Table(name = "PARAMETER")
public class Parameter {
@Id
private Long id;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
@JoinColumn(name = "PARAMETER_GROUP_ID")
private ParameterGroup parameterGroup;
}
来自文档:
public abstract boolean orphanRemoval (Optional)
是否将删除操作应用于已经存在的实体 从关系中删除并将删除操作级联到 那些实体。
答案 5 :(得分:0)
只要您没有启用ON DELETE CASCADE
或CascadeType.REMOVE
来防止实体移除事件的传播,就可以安全地使用orphanRemoval
。
在您的关系上拥有@OnDelete(action = OnDeleteAction.CASCADE)
将迫使Hibernate为相关外键生成ON DELETE CASCADE
。但是,您的Dialect
必须通过在true
方法中返回supportsCascadeDelete
来表明支持这种关系。
答案 6 :(得分:-1)
请勿使用cascade = CascadeType.REMOVE Documentation here
因为你的db可能会被破坏。您可以使用正式订单。删除子稳定 然后删除主表