删除操作的JPA和DAO实现

Posted

技术标签:

【中文标题】删除操作的JPA和DAO实现【英文标题】:JPA and DAO implementation of delete operation 【发布时间】:2011-12-27 18:01:24 【问题描述】:

我想知道 remove 方法的哪个实现更好:

public void remove(T t) 
   entityManager.remove(entityManager.merge(t));


public void remove(PK pk) 
   entityManager.remove(entityManager.getReference(entityType, pk));

我已经阅读了很多关于此的文章,几乎每一篇文章都与第一种方法相似,在我看来这完全没有必要,因为它可以在不需要从数据库中检索整个实体的情况下完成(如果它不存在于持久性上下文中),然后将其删除。有什么我遗漏的,第一种方法真的更好吗?

【问题讨论】:

你为什么不打电话给entityManager.remove(t) @stacker:我希望这个方法同时删除托管实体和分离实体。 【参考方案1】:

你可以通过调用来检查实体是否被管理

boolean isManaged = entityManager.contains( t );

如果为真,只需调用

entityManager.remove(t);

否则,您的第二种方法似乎更好,因为由于急切加载(如果已配置),合并可能会导致更多的数据库活动。 getReference 上的 javadoc 说“获取一个实例,其状态可能会被延迟获取。如果请求的实例在数据库中不存在,则在第一次访问实例状态时抛出 EntityNotFoundException。(允许持久性提供程序运行时抛出 EntityNotFoundException当调用 getReference(java.lang.Class, java.lang.Object) 时。)应用程序不应期望实例状态在分离时可用,除非在实体管理器打开时由应用程序访问。"

简而言之,必须管理实体,我建议:

em.remove(em.contains(r) ? r : em.merge(r));

【讨论】:

这个解决方案看起来不错,但是,我很想知道是否有人按照“DELETE FROM Entity e WHERE e.id=:当实体不包含在管理器中时,id" 会比调用合并然后删除更快吗?构建查询的开销是否超过了不需要获取实体的开销? 对我来说似乎没有必要,如果实体存在于持久性上下文中,调用 em.merge(r) 会返回对托管实体的引用。这不是这个问题的目的。困扰我的是当实体不存在于持久性上下文中时..因为合并方法必须从数据库中检索实体,在这种情况下,这在我看来是不必要的,因为我只需要从数据库中删除一行。

以上是关于删除操作的JPA和DAO实现的主要内容,如果未能解决你的问题,请参考以下文章

SpringData JPA实现增删改查

如何使用 JPA 实现测试 DAO?

使用 EntityManager (JPA) 在 DAO 中更新 () 方法的推荐行为?

JPA的泛型DAO设计及使用

spring boot:实现jpa+thymeleaf 用户管理

spring boot:实现jpa+thymeleaf 用户管理