使用Hibernate(JPA)一键式删除

在旧版本的Hibernate中,我可以看到手册中指示的一键式删除 。 但是较新的版本不再包含此部分。 我不知道为什么。 因此,在这篇文章中,我来看看它是否仍然有效。

一键式删除部分显示:

有时一个接一个地删除收集元素可能效率极低。 对于新的空集合(例如,如果您调用list.clear() ,Hibernate不会这样做。 在这种情况下,Hibernate将发出一个DELETE

假设您向大小为20的集合中添加了一个元素,然后删除了两个元素。 除非集合是一个包,否则Hibernate将发出一个INSERT语句和两个DELETE语句。 这当然是可取的。

但是,假设我们删除了18个元素,剩下两个,然后添加了新元素。 有两种可能的方式进行

  • 一一删除十八行,然后再插入三行
  • 在一个SQL DELETE删除整个集合,并一一插入所有五个当前元素

Hibernate不知道第二个选项可能更快。 对于Hibernate来说,如此直观可能是不希望的,因为这种行为可能会使数据库触发器混乱,等等。

幸运的是,您可以随时通过丢弃(即取消引用)原始集合并返回带有所有当前元素的新实例化集合来强制执行此行为(即第二种策略)。

一击删除不适用于映射为inverse="true"集合。

inverse="true"用于(休眠映射)XML。 但是在这篇文章中,我们将看到JPA (以Hibernate为提供者)如何进行“一次性删除”。

我们将尝试不同的方法,看看哪种方法会导致一次删除。

  1. 双向一对多
  2. 单向一对多(带连接表)
  3. 单向一对多(无连接表)
  4. 单向一对多(使用ElementCollection

我们将使用具有多个CartItemCart实体。

双向一对多

对于这一点,我们从双方的引用。

@Entity
public class Cart { ...@OneToMany(mappedBy="cart", cascade=ALL, orphanRemoval=true)Collection<OrderItem> items;
}@Entity
public class CartItem { ...@ManyToOne Cart cart;
}

为了测试这一点,我们为Cart的表插入一行,为CartItem的表插入三行或更多行。 然后,我们运行测试。

public class CartTests { ...@Testpublic void testOneShotDelete() throws Exception {Cart cart = entityManager.find(Cart.class, 53L);for (CartItem item : cart.items) {item.cart = null; // remove reference to cart}cart.items.clear(); // as indicated in Hibernate manualentityManager.flush(); // just so SQL commands can be seen}
}

所示的SQL命令将每个项目分别删除(而不是一次性删除)。

delete from CartItem where id=?
delete from CartItem where id=?
delete from CartItem where id=?

丢弃原始集合也不起作用。 它甚至引起了异常。

public class CartTests { ...@Testpublic void testOneShotDelete() throws Exception {Cart cart = entityManager.find(Cart.class, 53L);// remove reference to cartcart.items = new LinkedList<CartItem>(); // discard, and use new collectionentityManager.flush(); // just so SQL commands can be seen}
}
javax.persistence.PersistenceException:org.hibernate.HibernateException:A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: ….Cart.items

我用Hibernate 4.3.11和HSQL 2.3.2对此进行了测试。 如果您的结果有所不同,请点击评论 。

单向一对多(带连接表)

为此,我们对映射进行了更改。 这将导致创建一个联接表。

@Entity
public class Cart { ...@OneToMany(cascade=ALL)Collection<OrderItem> items;
}@Entity
public class CartItem { ...// no @ManyToOne Cart cart;
}

再次,我们为Cart的表插入一行,为CartItem的表插入三行或更多行。 我们还必须在连接表( Cart_CartItem )中插入适当的记录。 然后,我们运行测试。

public class CartTests { ...@Testpublic void testOneShotDelete() throws Exception {Cart cart = entityManager.find(Cart.class, 53L);cart.items.clear(); // as indicated in Hibernate manualentityManager.flush(); // just so SQL commands can be seen}
}

显示的SQL命令已删除联接表中的关联行(使用一个命令)。 但是表中CartItem的行仍然存在(并且没有被删除)。

delete from Cart_CartItem where cart_id=?
// no delete commands for CartItem

嗯,不完全是我们想要的,因为CartItem表中的行仍然存在。

单向一对多(无联接表)

从JPA 2.0开始,通过指定@JoinColumn可以避免单向一对多的连接表。

@Entity
public class Cart { ...@OneToMany(cascade=CascadeType.ALL, orphanRemoval=true)@JoinColumn(name="cart_id", updatable=false, nullable=false)Collection<OrderItem> items;
}@Entity
public class CartItem { ...// no @ManyToOne Cart cart;
}

再次,我们为Cart的表插入一行,为CartItem的表插入三行或更多行。 然后,我们运行测试。

public class CartTests { ...@Testpublic void testOneShotDelete() throws Exception {Cart cart = entityManager.find(Cart.class, 53L);cart.items.clear(); // as indicated in Hibernate manualentityManager.flush(); // just so SQL commands can be seen}
}

丢弃原始集合也不起作用。 这也导致了相同的异常(如双向一对多)。

javax.persistence.PersistenceException:org.hibernate.HibernateException:A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: ….Cart.items

单向一对多(带有

JPA 2.0引入了@ElementCollection 。 这允许与许多侧之中任建立一个一对多关系@Basic@Embeddable (即不是@Entity )。

@Entity
public class Cart { ...@ElementCollection // @OneToMany for basic and embeddables@CollectionTable(name="CartItem") // defaults to "Cart_items" if not overriddenCollection<OrderItem> items;
}@Embeddable // not an entity!
public class CartItem {// no @Id// no @ManyToOne Cart cart;private String data; // just so that there are columns we can set
}

再次,我们为Cart的表插入一行,为CartItem的表插入三行或更多行。 然后,我们运行测试。

public class CartTests { ...@Testpublic void testOneShotDelete() throws Exception {Cart cart = entityManager.find(Cart.class, 53L);cart.items.clear(); // as indicated in Hibernate manualentityManager.flush(); // just so SQL commands can be seen}
}

是的 CartItem的关联行在CartItem被删除。

delete from CartItem where Cart_id=?

总结思想

使用ElementCollection以单向一对多的方式进行一次删除( ElementCollection是嵌入式的,而不是实体)。

在单向一对多联接表方案中,删除联接表中的条目不会增加太多价值。

我不确定为什么一键式删除在Hibernate中起作用(或为什么这样起作用)。 但是我确实有一个猜测。 那就是底层的JPA提供者不能一口气删除,因为它不能确保多端实体不会被其他实体引用。 与ElementCollection不同,多面不是实体,其他实体也不能引用。

现在,这并不意味着您必须一直使用ElementCollection 。 一次性删除可能仅适用于聚合根。 在这些情况下,使用EmbeddableElementCollection可能适合于组成聚合的值对象的集合。 当除去聚合根时,最好也应除去“子”对象(并以有效的方式)。

我希望JPA中有一种方法可以指示子实体是私有的,并且在删除父实体时可以安全地删除它们(例如,类似于EclipseLink中的@PrivateOwned )。 让我们看看它是否将包含在API的将来版本中。

希望这可以帮助。

翻译自: https://www.javacodegeeks.com/2016/07/one-shot-delete-hibernate-jpa.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/353676.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UDP和TCP

TCP (Transmission Control Protocol)和UDP(User Datagram Protocol)协议属于传输层协议。其中TCP提供IP环境下的数据可靠传输&#xff0c;它提供的服务包括数据流传送、可靠性、有效流控、全双工操作和多路复用。通过面向连接、端到端和可靠的数据包发送。通俗说&#xff0c;它…

MyEclipse6.0 安装axis2插件, 调用加密的SAP webservice

MyEclipse6.0 安装axis2插件, 调用加密的SAP webservice 6人收藏此文章, 我要收藏 发表于1个月前(2013-06-06 09:41) , 已有116次阅读 &#xff0c;共0个评论 首先鄙视一下自己&#xff0c;还在用myeclipse,竟然还是6.0版本&#xff0c;没办法&#xff0c;用习惯了&#xff0c…

Eclipse中要导出jar包中引用了第三方jar包怎么办

Eclipse中要导出jar包中引用了第三方jar包怎么办 (2009-07-20 15:28:44) 转载▼标签&#xff1a; it 分类&#xff1a; Eclipse 今天做个小的java程序&#xff0c;想要先将其导出成一个可执行的jar包&#xff01;向往常一样&#xff0c;单击菜单栏中的 File -> export,弹出…

枚举类型定义

enum orientation:byte { north 1, south 2, east 3, west4 } 注意&#xff1a;声明在代码的主体之外 转载于:https://www.cnblogs.com/judes/p/9042426.html

拖动滑块拼图背景图没显示_计划B? 那是计划N…没什么。 拼图于2015年问世

拖动滑块拼图背景图没显示真是一天 当典型的欧洲人逐渐破产时&#xff0c;美国的人们开始喝咖啡。 这就是为什么我在Mark Reinhold最近的新闻中睡个好觉的原因。 他在题为“ Project Jigsaw&#xff1a;火车晚点 ”的帖子中建议将Project Jigsaw推迟到下一个版本Java 9。 在最近…

vi 常用命令行

vi 常用命令行 vi 常用命令行 1.vi 模式   a) 一般模式&#xff1a; vi 处理文件时&#xff0c;一进入该文件&#xff0c;就是一般模式了.   b) 编辑模式&#xff1a;在一般模式下可以进行删除&#xff0c;复制&#xff0c;粘贴等操作&#xff0c;却无法进行编辑操作。等…

java keytool证书工具使用小结

Keytool 是一个Java数据证书的管理工具 ,Keytool将密钥&#xff08;key&#xff09;和证书&#xff08;certificates&#xff09;存在一个称为keystore的文件中在keystore里&#xff0c;包含两种数据:密钥实体&#xff08;Key entity&#xff09;-密钥&#xff08;secret key&a…

在Kafka中发布订阅模型

这是第四个柱中的一系列关于同步客户端集成与异步系统&#xff08; 1&#xff0c; 2&#xff0c; 3 &#xff09;。 在这里&#xff0c;我们将尝试了解Kafka的工作方式&#xff0c;以便正确利用其发布-订阅实现。 卡夫卡概念 根据官方文件 &#xff1a; Kafka是一种分布式的&…

深入理解C++中的mutable关键字

2006-12-16 05:00 来源&#xff1a;BLOG 作者&#xff1a;寒星轩 责任编辑&#xff1a;方舟yesky 评论(32)推荐&#xff1a;经典教程专区mutalbe的中文意思是“可变的&#xff0c;易变的”&#xff0c;跟constant&#xff08;既C中的const&#xff09;是反义词。在C中&…

my.ini优化mysql数据库性能的十个参数(推荐)

(1)、max_connections&#xff1a;允许的同时客户的数量。增加该值增加 mysqld 要求的文件描述符的数量。这个数字应该增加&#xff0c;否则&#xff0c;你将经常看到 too many connections 错误。 默认数值是100&#xff0c;我把它改为1024 。(2)、record_buffer&#xff1a;每…

sizeof(string)

2012-07-14 00:38:54| 分类&#xff1a; C | 标签&#xff1a; |字号大中小 订阅 今天看《程序员面试宝典》一书&#xff08;为了应付将要到来的微软笔试&#xff09;&#xff0c;看到了sizeof(string)这个问题。在Dev C上测试的结果是4&#xff0c;很不明白。上网搜了一下…

实现userdetails_Spring Security使用Hibernate实现自定义UserDetails

实现userdetails大多数时候&#xff0c;我们将要在Web应用程序中配置我们自己的安全访问角色。 这在Spring Security中很容易实现。 在本文中&#xff0c;我们将看到最简单的方法。 首先&#xff0c;我们将在数据库中需要以下表格&#xff1a; CREATE TABLE IF NOT EXISTS myd…

C++类内存结构布局

分类&#xff1a;C 2011-01-16 09:40 阅读(379)评论(0)编辑删除 一、没有虚函数&#xff0c;没有继承的类内存结构&#xff1a;1.如下定义一个类&#xff1a;class A{public:void seta(int x) {a x;}; void setb(int x) {b x;};int sum() {return ab;};private:int a;int b;…

使用Boxfuse为您的REST API设置https

在我的上 一篇 文章中&#xff0c;我展示了在Boxfuse的帮助下&#xff0c;基于Spring Boot框架建立REST API并在AWS上运行非常容易 。 下一步是利用SSL与API进行通信。 通过使用SSL&#xff0c;我们确保在REST API服务器和API客户端之间的传输过程中保存了数据 。 要为Spring B…

Python类与对象实验

一、任务描述 本实验任务主要对Python类与对象进行一些基本操作&#xff0c;通过完成本实验任务&#xff0c;要求学生熟练掌握Python类与对象的关系&#xff0c;并对Python类与对象的基本操作进行整理并填写工作任务报告。 二、任务目标 1、掌握Python类的创建 2、掌握类对象 三…

c++类的内存布局

by andydeng • 2011 年 4 月 3 日 • C • 1 Comment 本文基本上是对于Stanley B.Lippman的Inside The C Object Model一书第一章第三章的概括,描述了c类的内存布局情况. c的类的内存布局有如下规则: 1. Nonstatic data member 存放在Class Object中; 2. Static data membe…

matlab 五点三次平滑算法

(2012-04-23 21:01:31) 转载▼标签&#xff1a; 杂谈 分类&#xff1a; matlab http://www.ilovematlab.cn/thread-71818-1-1.html 这里提供一个函数mean5_3(五点三次平滑算法)对数据进行平滑处理&#xff1a; load V1.mat subplot 211; plot(V1); ylim([2000 7000]); grid; y…

spring配置xml文件_XML配置文件中的Spring配置文件

spring配置xml文件我的上一个博客非常简单&#xff0c;因为它涵盖了我从Spring 3.0.x到Spring 3.1.x的轻松升级&#xff0c;最后我提到可以将Spring模式升级到3.1&#xff0c;以利用Spring的最新功能。 在今天的博客中&#xff0c;我将介绍这些功能中最酷的功能之一&#xff1a…

数组指针和指针数组的区别

数组指针&#xff08;也称行指针&#xff09; 定义 int (*p)[n]; ()优先级高&#xff0c;首先说明p是一个指针&#xff0c;指向一个整型的一维数组&#xff0c;这个一维数组的长度是n&#xff0c;也可以说是p的步长。也就是说执行p1时&#xff0c;p要跨过n个整型数据的长度。 如…

用JS写的取存款功能

console.log("请输入用户名&#xff1a;");let username readline.question(); // 接收用户输入的用户名console.log("请输入密码&#xff1a;");let password readline.question(); // 接收用户输入的密码let arr [["123", "123…