【问题标题】:JpaRepository delete child elementsJpaRepository 删除子元素
【发布时间】:2013-06-18 18:13:40
【问题描述】:

我正在尝试执行一个非常简单的删除操作,但不知何故它不起作用,因为我将 DAO 更新为 JpaRepository。基本上是这样的:

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

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

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

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);

还是一样……

A 类如下所示:

@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
}

我做错了什么?!


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
}

Setter 和 getter 都非常简单:

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

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

更多信息:

  • 春天 3.2.2
  • 休眠 4.2.2
  • spring-data-commons 1.5.1
  • spring-data-jpa 1.3.2

【问题讨论】:

  • B类是什么样的?还有 A.getBs() 方法?
  • 更新了初始发布。

标签: spring hibernate list jpa repository


【解决方案1】:

更新A.bList 属性如下:

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

orphanRemoval = true 注释属性将告诉底层 JPA 实现删除没有任何父级的 B 记录。

另外,由于B端管理关联,所以在断开关系时应清除其a属性。为了使这更易于阅读并减轻调用者对此类实现细节的负担,您应该在A 中引入管理方法:

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

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

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

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

希望对您有所帮助。

【讨论】:

  • 谢谢你!我现在已经开始工作了:我将 CascadeType.ALL 放在了 @OneToMany 注释中。在我不得不使用休眠中的@Cascade 注释之前。现在我将保留两个注释。我还添加了orphanRemoval = true。对于清除列表a.getBList().clear(); aRepository.saveAndFlush(a); 就足够了。 :)
猜你喜欢
  • 2010-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多