我有一个实体A
,其中包含一系列基本类型(例如String
)。我使用这样的映射,因为与A
的每个实例关联的字符串取决于A
的生命周期。如果我想从数据库中删除A
的实例,我还希望删除其关联的String
。
我的映射如下:
@Entity
public class A {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "name", nullable = false, unique = true)
private String name;
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "AStrings", joinColumns = @JoinColumn(name = "id"))
@Column(name = "strings", nullable = false)
private Set<String> strings;
}
如果我创建A
的实例并添加一些字符串,那么我可以使用Session.save(myInstance)
来保存实例。 <{1}}的实例及其关联的A
都是持久的。
但是,如果我想使用String
从数据库中删除相同的实例,我会收到外键约束错误:
无法删除或更新父行:外键约束失败
但是,我希望在删除Session.createQuery("delete A a where a.name = ?").setString(0, name).executeUpdate()
的实例之前自动删除关联的String
,但似乎并非如此。我也没有找到指定级联规则的方法。
我的配置有问题吗?
由于
编辑:我也尝试在A
字段上使用@Cascade(CascadeType.DELETE)
,但它仍无效。通过查看数据库,我没有看到相关外键的任何strings
策略。
有同样问题的人开了一个JIRA:https://hibernate.onjira.com/browse/HHH-4301。必须存在解决方案(或解决方法),我不能是唯一使用ON DELETE
的人。
我已经解决了这个问题。我认为使用Session.delete()或使用HQL查询进行删除是等效的,但似乎没有。使用HQL查询,不会自动删除依赖对象,因此我得到外键约束错误。使用Session.delete()解决了这个问题。此外,Hibernate似乎没有使用数据库的级联功能,因为我仍然没有在生成的DDL中看到任何CASCADE策略,它在内部处理它。
答案 0 :(得分:7)
我已经解决了这个问题。
我认为使用Session.delete()
或使用HQL
查询删除实体是等效的,但似乎没有。使用HQL
查询,依赖对象不会被自动删除,因此我得到了一个外键约束错误,如问题中所述。
使用Session.delete()
解决了这个问题。此外,Hibernate似乎没有使用数据库的级联功能,因为我仍然没有在生成的DDL中看到任何CASCADE策略,它在内部处理它。
对于版主:
我已经在过去添加了我对这个问题的回答(正如你的要求),但由于这是解决问题的答案,并且没有回复(来自其他用户),我想我应该在这里发布作为答案。
答案 1 :(得分:0)
如何添加orphanRemoval
配置?
或在删除一个A实例之前手动调用A.strings().clear()
?
如果上述两项都不起作用,可能是ElementCollection
答案 2 :(得分:0)
测试力删除孤儿:
@Cascade( { org.hibernate.annotations.CascadeType.ALL,
org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
答案 3 :(得分:-1)
添加“@Cascade”(org.hibernate.annotations.Cascade)
例如:
@Entity
public class A {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "AStrings", joinColumns = @JoinColumn(name = "id"))
@Column(name = "strings", nullable = false)
@Cascade(value=org.hibernate.annotations.CascadeType.ALL)
private Set<String> strings;
}