使用Hibernate(JPA)一键式删除
在旧版本的Hibernate中,我可以看到手册中指示的一键式删除 。 但是较新的版本不再包含此部分。 我不知道为什么。 因此,在这篇文章中,我来看看它是否仍然有效。
一键式删除部分显示:
有时一个接一个地删除收集元素可能效率极低。 对于新的空集合(例如,如果您调用
list.clear()
,Hibernate不会这样做。 在这种情况下,Hibernate将发出一个DELETE
。假设您向大小为20的集合中添加了一个元素,然后删除了两个元素。 除非集合是一个包,否则Hibernate将发出一个
INSERT
语句和两个DELETE
语句。 这当然是可取的。但是,假设我们删除了18个元素,剩下两个,然后添加了新元素。 有两种可能的方式进行
- 一一删除十八行,然后再插入三行
- 在一个SQL
DELETE
删除整个集合,并一一插入所有五个当前元素Hibernate不知道第二个选项可能更快。 对于Hibernate来说,如此直观可能是不希望的,因为这种行为可能会使数据库触发器混乱,等等。
幸运的是,您可以随时通过丢弃(即取消引用)原始集合并返回带有所有当前元素的新实例化集合来强制执行此行为(即第二种策略)。
一击删除不适用于映射为
inverse="true"
集合。
inverse="true"
用于(休眠映射)XML。 但是在这篇文章中,我们将看到JPA (以Hibernate为提供者)如何进行“一次性删除”。
我们将尝试不同的方法,看看哪种方法会导致一次删除。
- 双向一对多
- 单向一对多(带连接表)
- 单向一对多(无连接表)
- 单向一对多(使用
ElementCollection
)
我们将使用具有多个CartItem
的Cart
实体。
双向一对多
对于这一点,我们从双方的引用。
@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
。 一次性删除可能仅适用于聚合根。 在这些情况下,使用Embeddable
和ElementCollection
可能适合于组成聚合的值对象的集合。 当除去聚合根时,最好也应除去“子”对象(并以有效的方式)。
我希望JPA中有一种方法可以指示子实体是私有的,并且在删除父实体时可以安全地删除它们(例如,类似于EclipseLink中的@PrivateOwned
)。 让我们看看它是否将包含在API的将来版本中。
希望这可以帮助。
翻译自: https://www.javacodegeeks.com/2016/07/one-shot-delete-hibernate-jpa.html
使用Hibernate(JPA)一键式删除相关推荐
- hibernate jpa_使用Hibernate(JPA)一键式删除
hibernate jpa 在旧版本的Hibernate中,我可以看到手册中指示的一键式删除 . 但是较新的版本不再包含此部分. 我不知道为什么. 因此,在这篇文章中,我来看看它是否仍然有效. 一键式 ...
- Spring Hibernate JPA 联表查询 复杂查询
(转自:http://www.cnblogs.com/jiangxiaoyaoblog/p/5635152.html) 今天刷网,才发现: 1)如果想用hibernate注解,是不是一定会用到jpa的 ...
- Spring MVC + Hibernate JPA + Bootstrap 搭建的博客系统
Spring MVC + Hibernate JPA + Bootstrap 搭建的博客系统 Demo 相关阅读: 1.Spring MVC+Hibernate JPA+ Bootstrap 搭建的博 ...
- scp会覆盖同名文件吗_你会Hypermesh一键式完成几何文件到求解文件的输出吗?
前不久,我在仿真秀APP更新了2篇Hypermesh二次开发的文章,介绍了<Hypermesh二次开发之电子产品跌落全流程开发讲解>和<前处理软件Hypermesh二次开发如何从入门 ...
- androidstudio在mainactivity实现监听器借口无法抽象_趣操作,Tomcat如何实现一键式启停?
推荐阅读 一线大厂为什么面试必问分布式? 在一次又一次的失败中,我总结了这份万字的<MySQL性能调优笔记> 并发编程详解:十三个工具类,十大设计模式,从理论基础到案例实战 首先我们通过一 ...
- 4步搞定MySQL安装部署(附MySQL一键式部署脚本)
墨墨导读:良好的开端是成功的一半,从MySQL安装开始. 学习数据库技术,实际动手的第一步是安装自己的MySQL.MySQL方面也提供多样式的安装方式rpm ,tar ,源码包.当安装完投入使用之后, ...
- Hibernate JPA中insert插入数据后自动执行select last_insert_id()解决方法
本文出处:http://blog.csdn.net/chaijunkun/article/details/8647281,转载请注明.由于本人不定期会整理相关博文,会对相应内容作出完善.因此强烈建议在 ...
- jenkins 一键式部署的工具
文章目录 一键式部署的工具 il2cpp的特点: 打包更慢,但代码运行更快,效率更高 全局配置: 插件安装: 在全局工具配置中,加入多个版本的unity. 重启jenkins慢的问题: 定时构建: 比 ...
- 泛泰binx一键式离线刷机(可断网刷机,可刷任意版本)(官网脚本更新7.30)
一键式离线刷机.zip 密码suky 小白们以我匪夷所思的思路和步骤得出了错误的结论,我低估了小白的战斗力啊 使用前请先关闭所有IE窗口,若要使用官网请使用下面脚本 regsvr32.exe /s / ...
最新文章
- studio 热重载应用_使用VS Code开发Flutter应用,体验热重载技术
- css3中关于transform rotate、translate()、skew()、scale()的复合变换
- 为什么AI需要的是角色扮演,而不是象棋和围棋?
- 大数据技术生态体系(截图)
- 国自然标书,600多份成功申请基金的标书 可下载
- 【美图秀秀】如何P图恶搞——室友的噩梦
- 1.4版走迷宫小游戏
- dhtml、html、html5、xml、xhtml的区别
- 学生成绩录入系统与查询
- 梯度下降法的不同形式——随机梯度下降法和小批量梯度下降法
- 2022年熔化焊接与热切割考试题模拟考试题库及模拟考试
- 【调剂】东华理工大学2020年硕士研究生预调剂信息
- 基于人工势场法的路径规划
- 第十一篇:读《文明,现代化,价值投资与中国》
- 如何c51和mdk共存兼容_keil5 MDK软件中传统C51与STM32相互兼容的方法
- jQuery俄罗斯方块游戏动画
- 七大壁纸网站满足所有分辨率需求!
- MS8257 超低噪声,宽带,可选反馈电阻跨阻放大器
- 计算两个时间戳型的时间差
- 王道辅导书中代码LinkList L中的作用
热门文章
- Java 内存泄露总结
- (十一)Spring 基础注解(对象创建相关注解、注入相关注解)
- 单例模式懒汉式(线程安全写法)
- expect() php,Linux expect 的安装
- (转)java动态代理与aop
- Mybatis3(3)动态 SQL
- java –cp ./:_成为Java流大师–第3部分:终端操作
- 版本交付_连续交付友好的Maven版本
- junit 5测试异常处理_使用JUnit 5测试异常
- hotspot 垃圾收集器_HotSpot增量Java垃圾收集器