2013-06-18 93 views
1

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

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

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

现场获取的更新预期,但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 
} 

getter和setter方法都一样简单possbile:

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

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

一些详细信息:

  • 春天3.2.2
  • 冬眠4.2.2
  • 弹簧数据公地1.5.1
  • 弹簧数据的JPA 1.3.2
+0

B类是什么样的?和A.getBs()方法? – Spiff

+0

更新了最初的发布。 –

回答

6

更新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); 
    } 
} 

希望有帮助。

+0

谢谢你!我现在得到它的工作:我已经把'CascadeType.ALL'放在'@ OneToMany'注释中。在我**之前**使用来自休眠的'@ Cascade'注释。现在我将保留两个注释。我还加了'orphanRemoval = true'。清除列表'a.getBList()。clear(); aRepository.saveAndFlush(a);'就够了。 :) –