JPA多对多删除实体

Posted

技术标签:

【中文标题】JPA多对多删除实体【英文标题】:JPA Many To Many remove entity 【发布时间】:2019-02-11 11:12:46 【问题描述】:

我使用 Hibernate(通过 JPA)。有一种删除实体的方法:

    public void delete(final ID id)     entityManager.createQuery(String.format("delete from %s e where e.id = :id", entityClass.getSimpleName()))
.setParameter("id", id).executeUpdate();
    

我删除了实体(具有 many2many 关系):

休眠日志:

Hibernate: delete from author_to_book where (author_id) in (select id from author where id=?)
Hibernate: delete from author where id=?

谁负责从绑定表中删除关联?毕竟,我的代码仅指定从主表中删除。 它是如何工作的?

映射:

@Entity
public class Author extends BaseEntity implements IAuthor 

@Column
private String name;

@JoinTable(name = "author_to_book",
        joinColumns =  @JoinColumn(name = "author_id") ,
        inverseJoinColumns = @JoinColumn(name = "book_id")
)
@ManyToMany(targetEntity = Book.class, fetch = FetchType.LAZY)
@OrderBy("title ASC")
private Set<IBook> books = new HashSet<>();

Book 实体没有到 Author 实体的映射

【问题讨论】:

为什么使用查询删除实体并忽略em.remove?? Kinda 胜过使用持久性 API ... 我在下面回答。我真的不明白它是如何工作的(em.remove -> 通过 Hibernate 实现)。因此,我问了关于删除实体的问题。 如果您不理解,请阅读您的 JPA 提供者的文档。 em.remove 会处理所有的关系,批量删除查询不会(开发者负责)。但这就是 JPA 规范中的全部内容,因此建议您阅读它 【参考方案1】:

使用字符串构造查询 SQL 对于 JPA 来说不是一个好主意。应使用 JPQL 或 Criteria API。通常,关联的拥有方负责从连接表中删除行。对于双向关系,连接表中的行也可以从另一侧删除。这真的取决于 JPA 的实现。据我所知,CMobileCom JPA可以管理双方的连接表。

免责声明:我是CMobileCom JPA 的开发人员,这是一个适用于 android 和 Java JDBC 的轻量级 JPA 实现。

【讨论】:

这就是我使用JPQL的原因:thoughts-on-java.org/avoid-cascadetype-delete-many-assocations如果我错了,我在等待cmets :) 这不是很有效的代码:"String.format("delete from %s e where e.id = :id", entityClass.getSimpleName())"。最好直接使用“delect from EntityTypeName e where e.id=:id”。

以上是关于JPA多对多删除实体的主要内容,如果未能解决你的问题,请参考以下文章

多对多关系 JPA 与实体

JPA多对多映射

多对多实体上的 JPA WHERE 子句

JPA - 一个实体如何引用多对多关系中涉及的两个其他实体?

具有额外多对多关系的 JPA 多对多

JPA - 多对多集合的分页查询返回错误数量的实体