JpaRepository删除子元素 [英] JpaRepository delete child elements

查看:125
本文介绍了JpaRepository删除子元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做一个非常简单的删除操作,但不知何故,它不起作用,因为我更新了DAO到JpaRepository。基本上是这样的:

  A a = aRepository.findOne(id); 
a.setSomeField(someNewString);

列表< B> bList = a.getBs();
bList.clear();
repository.saveAndFlush(a);

字段get按预期更新,但 bList 保持不变。我甚至试过:

  A a = aRepository.findOne(id); 
a.setSomeField(someNewString);

列表< B> bList = a.getBs(); (b b:bList){
bRepository.delete(b);

}
bRepository.flush();
bList.clear();
repository.saveAndFlush(a);

还是一样...



A类看起来像这样:

  @Entity 
@Table(name =A)
public类A实现Serializable {
private static final long serialVersionUID = -1286451120913657028L;

@Column(name =id,length = 16,nullable = false,updatable = false)
@GenericGenerator(name =uuid,strategy =uuid2)
@GeneratedValue(generator =uuid)
@Basic(fetch = FetchType.EAGER)
@Id
受保护的UUID ID;

@OneToMany(mappedBy =a,fetch = FetchType.EAGER)
@Cascade({CascadeType.ALL})
List< B> bList;

// getter + setter
}

我是什么做错了!






B类:

  @Entity 
@Table(name =B)
public class B implements Serializable {
@Column(name =id,length = 16,nullable = false,updatable = false)
@GenericGenerator(name =uuid,strategy =uuid2)
@GeneratedValue(generator =uuid)
@Basic(fetch = FetchType。 EAGER)
@Id
受保护的UUID ID;

@ManyToOne(可选= false)
@JoinColumns({@JoinColumn(name =A_id,referencedColumnName =id,nullable = false)})
@Valid
A a;

// setter + getter
}

Setters and getters无论如何都是如此简单:

  public List< B> getBList(){
return bList;
}

public void setBList(List< B> bList){
this.bList = bList;





$ b

更多信息:
$ / p>


  • spring 3.2.2

  • hibernate 4.2.2

  • spring-data-commons 1.5.1

  • spring-data-jpa 1.3.2


解决方案

更新 A.bList 属性如下:

  public class A {
@OneToMany(mappedBy =a,fetch = FetchType.EAGER,cascade = CascadeType.ALL,orphanRemoval = true)
List< B> bList;

orphanRemoval = true annotation属性将告诉基础JPA实现删除没有任何父级的B记录。



另外,由于 B side管理关联,您应该在中断关系时清除它的 a 属性。为了更容易阅读并从调用者中移除这些实现细节的负担,您应该在 A 中引入管理方法:

  public class A {
public void clearBList(){
for(B b:bList){
b.releaseA();
}
bList.clear();



public class B {
void releaseA(){
this.a = null;




$ b

你应该避免直接暴露集合,而是返回一个不可变的它的版本,以防止客户在没有A类知道的情况下直接修改集合。 A 管理 B 列表,所以它应该完全控制它!

  public class A {
public List< B> getBList(){
返回Collections.unmodifiableList(bList);
}
}

希望有帮助。


I'm trying to do a very simple delete operation, but somehow it doesn't work since I updated the DAOs to JpaRepository. Basically it's this:

A a = aRepository.findOne(id);
a.setSomeField("someNewString");

List<B> bList = a.getBs();
bList.clear();
aRepository.saveAndFlush(a);

The field get's updated as expected, but the bList stays unchanged. I've even tried:

A a = aRepository.findOne(id);
a.setSomeField("someNewString");

List<B> bList = a.getBs();
for(B b : bList) {
   bRepository.delete(b);
}
bRepository.flush();
bList.clear();
aRepository.saveAndFlush(a);

Still the same...

Class A looks like this:

@Entity
@Table(name = "A")
public class A implements Serializable {
    private static final long serialVersionUID = -1286451120913657028L;

    @Column(name = "id", length = 16, nullable = false, updatable = false)
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    @GeneratedValue(generator = "uuid")
    @Basic(fetch = FetchType.EAGER)
    @Id
    protected UUID id;

    @OneToMany(mappedBy = "a", fetch = FetchType.EAGER)
    @Cascade({ CascadeType.ALL })
    List<B> bList;

    // getter + setter
}

What am I doing wrong?!


Class B:

@Entity
@Table(name = "B")
public class B implements Serializable {
    @Column(name = "id", length = 16, nullable = false, updatable = false)
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    @GeneratedValue(generator = "uuid")
    @Basic(fetch = FetchType.EAGER)
    @Id
    protected UUID id;

    @ManyToOne(optional = false)
    @JoinColumns({ @JoinColumn(name = "A_id", referencedColumnName = "id", nullable = false) })
    @Valid
    A a;

    // setter + getter
}

Setters and getters are all just as simple as possbile:

public List<B> getBList() {
    return bList;
}

public void setBList(List<B> bList) {
    this.bList = bList;
}


Some more information:

  • spring 3.2.2
  • hibernate 4.2.2
  • spring-data-commons 1.5.1
  • spring-data-jpa 1.3.2

解决方案

Update the A.bList property as follows:

public class A {
    @OneToMany(mappedBy = "a", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
    List<B> bList;
}

The orphanRemoval = true annotation attribute will tell the underlying JPA implementation to delete B records which don't have any parent left.

Also, Since the B side manages the association, you should clear its a attribute when breaking the relationship. To make this easier to read and to remove the burden of such implementation details from the caller, you should introduce management methods in A :

public class A {
    public void clearBList() {
        for (B b : bList) {
            b.releaseA();
        }
        bList.clear();
    }
}

public class B {
    void releaseA() {
        this.a = null;
    }
}

You should avoid exposing collections directly and instead return an immutable version of it to prevent clients to the A class of modifying the collection directly without the A class knowing it. A manages the B list, so it should have full control over it!

public class A {
    public List<B> getBList() {
        return Collections.unmodifiableList(bList);
    }
}

Hope that helps.

这篇关于JpaRepository删除子元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆