Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA:单向多对一和级联删除_Java_Jpa_Jpa 2.0_Many To One - Fatal编程技术网

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
    ,或者更改为单向
    @OneToMany
    。然后可以级联删除操作,以便删除父级和子级。您还可以指定为true,以在父集合中的子实体设置为null时删除任何孤立子实体,即在任何父集合中不存在子实体时删除该子实体
  • 或者,在删除级联时将子表中的外键约束指定为
    。调用后需要调用,因为需要刷新持久性上下文-在数据库中删除子实体后,子实体不应该存在于持久性上下文中

创建双向关系,如下所示:

@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我想每个人