Java 可嵌入对象的级联删除';收集

Java 可嵌入对象的级联删除';收集,java,hibernate,cascading-deletes,Java,Hibernate,Cascading Deletes,我有一个实体A,它有一组基本类型(例如String)。我使用这种映射是因为与a的每个实例相关联的字符串取决于a的生命周期。如果我想从数据库中删除A的实例,我还想删除其关联的字符串 我的映射如下: @Entity public class A { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column(name = "name", nullable = false,

我有一个实体
A
,它有一组基本类型(例如
String
)。我使用这种映射是因为与
a
的每个实例相关联的字符串取决于
a
的生命周期。如果我想从数据库中删除
A
的实例,我还想删除其关联的
字符串

我的映射如下:

@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类{
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
私人长id;
@列(name=“name”,nullable=false,unique=true)
私有字符串名称;
@ElementCollection(fetch=FetchType.EAGER)
@CollectionTable(name=“AStrings”,joinColumns=@JoinColumn(name=“id”))
@列(name=“strings”,null=false)
私有集字符串;
}
如果我创建了
A
的一个实例并添加了一些字符串,那么我可以使用
Session.save(myInstance)
持久化该实例。
A
的实例及其关联的
String
s都将被持久化

但是,如果我想使用
Session.createQuery(“delete A where A.name=?”).setString(0,name).executeUpdate()
从数据库中删除同一实例,我会得到一个外键约束错误:

无法删除或更新父行:外键约束失败

但是,我希望在删除
A
的实例之前自动删除关联的
字符串
,但情况似乎并非如此。我也没有找到指定级联规则的方法

我的配置有问题吗

谢谢


编辑:我还尝试在
字符串
字段上使用
@Cascade(CascadeType.DELETE)
,但仍然无济于事。通过查看数据库,我没有看到任何有关外键的
删除策略

有人有同样的问题打开了一个JIRA:。必须存在解决方案(或解决方法),我不能是唯一使用
@ElementCollection
的人

我已经解决了这个问题。我认为使用Session.delete()或使用HQL查询进行删除是等效的,但似乎不是。使用HQL查询,依赖对象不会自动删除,因此我得到一个外键约束错误。使用Session.delete()解决了这个问题。另外,Hibernate似乎没有使用DB的级联功能,因为我在生成的DDL中仍然没有看到任何级联策略,它在内部处理这个问题。

添加“@cascade”(org.Hibernate.annotations.cascade)

例:

@实体
公共A类{
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
私人长id;
@ElementCollection(fetch=FetchType.EAGER)
@CollectionTable(name=“AStrings”,joinColumns=@JoinColumn(name=“id”))
@列(name=“strings”,null=false)
@级联(value=org.hibernate.annotations.CascadeType.ALL)
私有集字符串;
}
  • 添加
    删除
    配置如何

  • 或者在删除一个实例之前手动调用
    A.strings().clear()


如果以上两种方法都不起作用,则可能是
ElementCollection

测试强制删除孤立项存在一些错误:

@Cascade( { org.hibernate.annotations.CascadeType.ALL, 
    org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
我已经解决了这个问题

我认为使用
Session.delete()
或使用
HQL
查询删除实体是等效的,但似乎不是。使用
HQL
query,依赖对象不会自动删除,因此我得到了一个外键约束错误,如问题中所述

使用
Session.delete()
解决了这个问题。另外,Hibernate似乎没有使用DB的级联功能,因为我在生成的DDL中仍然没有看到任何级联策略,它在内部处理这个问题


版主:


我在过去(如您所问)已经添加了我对该问题的答案,但由于这是解决问题的答案,而且(其他用户)没有给出任何答案,我想我应该将其作为答案发布在这里。

@Cascade
针对实体
@OneToMany
s,不适用于
@ElementCollection
s。
@Cascade
适用于实体
@OneToMany
s,不适用于
@ElementCollection
s。这真的很有效!问题是使用HQL的速度要慢得多。。。
@Cascade( { org.hibernate.annotations.CascadeType.ALL, 
    org.hibernate.annotations.CascadeType.DELETE_ORPHAN })