2014-07-03 42 views
0

我尝试编写一个JPQL查询,它删除了另一个实体集合中的所有实体。 (示例代码,没有的getter/setter和注释)JPQL DELETE查询:删除另一个实体列表中的实体

class Aa implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    private String value; 
} 

@Entity 
class A implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @JoinColumn(nullable = false) 
    @OneToOne 
    private Aa aa; 

    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}) 
    private List<B> data; 
} 
@Entity 
class B implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 


    private String value; 
} 

我曾尝试以下:

DELETE FROM B b WHERE b.id IN(SELECT k.id FROM A a JOIN a.data k WHERE a.id = :id) 

但它的外键冲突异常结束。 另一种方法是

DELETE FROM B b WHERE EXISTS(SELECT a FROM A a WHERE a.id = :id) 

,但其在外国键冲突也结束。

但是如果我执行一个SQL查询直接对数据库进行,像

DELETE FROM B WHERE id = <a id number here> 

,那么不发生错误...

EntityManager.remove()是不是一种选择,因为我要删除大量的数据。

我很感谢你的回答和帮助。

回答

0

好,用Syfors的建议帮助我有改变A和B之间的关系:

class Aa implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    private String value; 
} 

@Entity 
class A implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @JoinColumn(nullable = false) 
    @OneToOne 
    private Aa aa; 

    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}, mappedBy = "owner") 
    private List<B> data; 
} 
@Entity 
class B implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @OneToOne 
    private A owner; 


    private String value; 
} 

我还发现:

[...]一般而言,这是最好的在Java中定义多对一回参考[...]

来源:http://en.wikibooks.org/wiki/Java_Persistence/OneToMany

现在JPA不会产生THRID表为M:1间的关系,现在我的JPQL查询工作正常:

DELETE FROM B b WHERE b.id IN(SELECT k.id FROM A a JOIN a.data k WHERE a.id = :id) 
0

由于我没有足够的声望,无法添加评论。

您跳过注释,这很重要,因为它有助于了解哪个方面,父母,孩子或他们之间的某个东西是否处于关系控制之中。例如,如果父方正在控制,在某些情况下,只需在父节点上清空List并坚持删除其子节点就足够了。所以更多的代码会有帮助。

编辑1:

如果你正在使用JPA 2.0你可以添加orphanRemoval="true"@OneToMany。然后,从持久性获得父母,执行parent.getData().clear(),然后执行EntityManager.merge(parent)或让孩子知道关系。您正在尝试移除不知道其父母的孩子,所以我建议您通过父母或通过提醒他们注意。

+0

你是对的。我在主帖中添加了注释。母方正在控制关系。但是我有大量的A对象存储大量的B对象。这就是我使用DELETE语句的原因。 – user2429841

+0

检查编辑,增加了一些建议。 – Candyman

+0

问题是,如果我打电话给家长。getData(),然后选择列表中的所有实体(它不管是取类型laze还是渴望)。我试图阻止这一点。 – user2429841

相关问题