级联删除可嵌入对象的集合

时间:2012-08-29 07:36:46

标签: java hibernate cascading-deletes

我有一个实体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策略,它在内部处理它。

4 个答案:

答案 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;
}
相关问题