Java JPA:单向多对一和级联删除
假设我有一个单向的Java JPA:单向多对一和级联删除,java,jpa,jpa-2.0,many-to-one,Java,Jpa,Jpa 2.0,Many To One,假设我有一个单向的@ManyToOne关系,如下所示: @Entity public class Parent implements Serializable { @Id @GeneratedValue private long id; } @Entity public class Child implements Serializable { @Id @GeneratedValue private long id; @ManyTo
@ManyToOne
关系,如下所示:
@Entity
public class Parent implements Serializable {
@Id
@GeneratedValue
private long id;
}
@Entity
public class Child implements Serializable {
@Id
@GeneratedValue
private long id;
@ManyToOne
@JoinColumn
private Parent parent;
}
如果我有一个父级p和子级C1…Cn引用回p,那么在JPA中是否有一种干净而漂亮的方法在p被删除时自动删除子级C1…Cn(即entityManager.remove(p)
)
我要寻找的是一种类似于SQL中删除级联的功能。JPA中的关系总是单向的,除非您在两个方向上都将父对象与子对象关联。从父级到子级的级联删除操作需要父级到子级的关系(而不仅仅是相反的关系) 因此,您需要执行以下操作:
- 或者,将单向
关系更改为双向@ManyToOne
,或者更改为单向@ManyToOne
。然后可以级联删除操作,以便删除父级和子级。您还可以指定为true,以在父集合中的子实体设置为null时删除任何孤立子实体,即在任何父集合中不存在子实体时删除该子实体@OneToMany
- 或者,在删除级联时将子表中的外键约束指定为
。调用后需要调用,因为需要刷新持久性上下文-在数据库中删除子实体后,子实体不应该存在于持久性上下文中
@Entity
public class Parent implements Serializable {
@Id
@GeneratedValue
private long id;
@OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE)
private Set<Child> children;
}
@实体
公共类父级实现可序列化{
@身份证
@生成值
私人长id;
@OneToMany(mappedBy=“parent”,cascade=CascadeType.REMOVE)
私人儿童;
}
@Cascade(org.hibernate.annotations.CascadeType.DELETE\u孤儿)
给定的注释对我有用。我可以试一试
例如:-
public class Parent{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="cct_id")
private Integer cct_id;
@OneToMany(cascade=CascadeType.REMOVE, fetch=FetchType.EAGER,mappedBy="clinicalCareTeam", orphanRemoval=true)
@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
private List<Child> childs;
}
public class Child{
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="cct_id")
private Parent parent;
}
公共类父类{
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
@列(name=“cct\U id”)
私有整数cct_id;
@OneToMany(cascade=CascadeType.REMOVE,fetch=FetchType.EAGER,mappedBy=“clinicalCareTeam”,orphanRemoving=true)
@Cascade(org.hibernate.annotations.CascadeType.DELETE\u孤儿)
私人名单儿童;
}
公营儿童{
@manytone(fetch=FetchType.EAGER)
@JoinColumn(name=“cct\U id”)
私人家长;
}
如果您使用hibernate作为JPA提供者,则可以使用注释@OnDelete
。此注释将向关系中添加DELETE CASCADE上的触发器,该触发器将子项的删除委托给数据库
例如:
public class Parent {
@Id
private long id;
}
public class Child {
@Id
private long id;
@ManyToOne
@OnDelete(action = OnDeleteAction.CASCADE)
private Parent parent;
}
使用此解决方案,从子对象到父对象的单向关系足以自动删除所有子对象。此解决方案不需要任何侦听器等。此外,类似于DELETE FROM Parent,其中id=1
的JPQL查询将删除子项。我在单向@manytone中看到,DELETE无法按预期工作。
删除父项时,理想情况下也应删除子项,但只删除父项,不删除子项,并将其作为孤立项
使用的技术是Spring引导/Spring数据JPA/Hibernate
Sprint启动:2.1.2.0版本
Spring数据JPA/Hibernate用于删除行
parentRepository.delete(parent)
ParentRepository扩展了标准CRUD存储库,如下所示
ParentRepository扩展了crudepository
下面是我的实体类
@Entity(name = “child”)
public class Child {
@Id
@GeneratedValue
private long id;
@ManyToOne( fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = “parent_id", nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
private Parent parent;
}
@Entity(name = “parent”)
public class Parent {
@Id
@GeneratedValue
private long id;
@Column(nullable = false, length = 50)
private String firstName;
}
使用此方法仅删除一侧
@ManyToOne(cascade=CascadeType.PERSIST, fetch = FetchType.LAZY)
// @JoinColumn(name = "qid")
@JoinColumn(name = "qid", referencedColumnName = "qid", foreignKey = @ForeignKey(name = "qid"), nullable = false)
// @JsonIgnore
@JsonBackReference
private QueueGroup queueGroup;
你不需要使用双向关联来代替你的代码,你只需要添加CascaType.Remove作为manytone注释的属性,然后使用@OnDelete(action=OnDeleteAction.CASCADE),这对我来说很好。即使只有“Child”引用了“Parent”(这样引用是单向的)将带有“@OneToMany”映射和“Cascade=ALL”属性的“Child”列表添加到“Parent”中是否有问题?我认为JPA应该解决的问题是,即使很难,也只有一方持有引用。@kvDennis,有些情况下,您不想将多方紧密地耦合到一方。例如,在类似ACL的设置中,安全权限是透明的“附加组件”,有没有办法使用JPA注释执行No2?如何使用Hibernate xml映射执行No2?我不能这样做,是否有特定版本的Hibernate或其他类似的更详细示例?很难说为什么它不适用于您。要使其正常工作,您可能需要重新生成模式,或者必须手动添加级联删除。@OnDelete注释似乎存在了一段时间,因此我猜版本不是问题。谢谢你的回答。快速说明:只有通过hibernate启用DDL生成时,才会创建数据库级联触发器。否则,您必须以另一种方式添加它(例如,液化)要允许直接针对DB运行特别查询,如“从父项中删除,其中id=1”,请执行级联删除。当关联为@OneToOne
时,这不起作用。有什么办法可以用@OneToOne
解决吗?@ThomasHunziker这对删除孤儿不起作用,对吗?回答不好,双向关系在JPA中很糟糕,因为在大的子集合上操作需要惊人的时间。有证据表明双向关系很慢吗?@enercio如果双向关系是一对一的呢?另外,请展示一篇文章,说明双向关系是缓慢的?什么慢?找回?删除?更新?@saran3h每个操作(添加、删除)都将加载所有子项,因此这是一个巨大的数据加载,可能是无用的(就像添加一个值不需要从数据库加载所有子项,这正是此映射所做的)。@enercio我想每个人