hibernate jpa_使用Hibernate(JPA)一键式删除

hibernate jpa

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

一键式删除部分显示:

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

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

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

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

Hibernate不知道第二个选项可能更快。 Hibernate如此直观可能会不受欢迎,因为这种行为可能会使数据库触发器混乱,等等。

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

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

inverse="true"适用于(Hibernate映射)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

hibernate jpa

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

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

相关文章

python测试开发实战_《python测试开发实战》基于pytest基础部分实例1-Hello

要求实现如下命令行接口python 1hello.py -husage: 1hello.py [-h] [-n NAME]Say hellooptional arguments:-h, --help show this help message and exit-n NAME, --name NAME Name to greet没有参数时输出Hello, World!$python 1hello.pyHello, World!有参数时输出Hello, 人名…

kafka 发布订阅_在Kafka中发布订阅模型

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

python socket recvfrom_Python socket学习笔记(一)

最近在看 Python的视频&#xff0c;针对socket 编程做一个笔记一、socket是什么&#xff1f;socket 通常也称为“套接字”&#xff0c;用于描述 IP 地址和端口&#xff0c;是一个通讯链的句柄。应用程序通常通过 “套接字”向网络发出请求或者应答网络请求。说白了&#xff0c;…

dynamodb java_使用Java更新DynamoDB项

dynamodb java在上一篇文章中&#xff0c;我们继续使用Java将项目插入DynamoDB。 DynamoDB还支持更新项目。 我们将使用Login表获取更新示例。 发布更新时&#xff0c;必须指定要更新的项目的主键。 public void updateName(String email,String fullName) {Map<String,A…

apache camel_使用Apache Camel进行负载平衡

apache camel在此示例中&#xff0c;我们将向您展示如何使用Apache Camel作为系统的负载平衡器。 在计算机世界中&#xff0c;负载平衡器是一种充当反向代理并在许多服务器之间分配网络或应用程序流量的设备。 负载平衡器用于增加容量&#xff08;并发用户&#xff09;和应用程…

lombok 自动使用_Lombok,自动值和不可变项

lombok 自动使用我喜欢布兰登&#xff08;Brandon &#xff09;在博客文章中比较Project Lombok &#xff0c; AutoValue和Immutables的建议 &#xff0c;而这篇文章试图做到这一点。 我已经简要概述了Project Lombok &#xff0c; AutoValue和Immutables &#xff0c;但是这篇…

邮箱批量登录接验证码_记一次莫名的需求(临时邮箱|企业邮箱)

目录&#xff1a;前言行情伪需求过程1.前戏2.买域名3.网易企业邮箱4.模糊的需求5.晚饭后6.临时邮箱16.临时邮箱27.域名版临时邮箱8.遇见问题8.1.DNSPOD8.2.换种思路拓展1.思路2.后续2.1.简单2.2.自建临时邮箱后话记一次需求不明的亏看完这篇文章你会学到&#xff1a; 免费企业邮…

【四】初步预测

import time from lxml import etree from collections import defaultdict import math import requests from matplotlib import pyplot as plt import pandas as pd import datetimed = defaultdict(list) listp = list()# 90+进球球队 setp = set()Allset = set()def httpg…

java 补充日期_Java 9对可选的补充

java 补充日期哇&#xff0c;人们真的对Java 9对Stream API的添加感兴趣。 想要更多&#xff1f; 让我们看一下…… 可选的 可选::流 无需解释&#xff1a; Stream<T> stream();想到的第一个词是&#xff1a; 终于 &#xff01; 最后&#xff0c;我们可以轻松地从可选…

msf如何升级_Kali linux 2016.2(Rolling)中的Metasploit如何更新与目录结构初步认识...

如何更新MSF1、Windows平台方法1&#xff1a;运行msfupdate.bat在msfconsole里执行命令svn update或者方法2&#xff1a;2、unix/linux平台方法1&#xff1a;运行msfupdate即可。方法2&#xff1a;(比较麻烦)安装subversion客户端(--with-ssl)&#xff0c;之后连接CVS server进…

【五】每个球队胜率统计

import time from lxml import etree from collections import defaultdict import math import requests from matplotlib import pyplot as plt import pandas as pd import datetimed = defaultdict(list) listp = list()# 近七天比赛所有球队 listall = list()# 近七天所有…

jaxb注解使用_使用JAXB的简介

jaxb注解使用我正在将一些依赖于Apache XMLBeans的模块迁移到JAXB。 这是令人兴奋和充满挑战的几天。 我想记下我遇到的一些重要事情&#xff0c;以供将来可能会发现有用的任何人使用。 首先&#xff0c;让我们来看一下设置用于JAXB代码生成的maven插件。 在撰写本文时&#x…

离散信号的抽取和内插例题_信号与系统例题分析

第1章 信号及其基本运算1.1 内容要点1.2 公式摘要1.3 例题分析例1.1 连续时间信号与波形例1.2 离散时间信号与波形例1.3 信号的积分运算例1.4 单位冲激信号的筛选特性例1.5 信号的平移例1.6 信号的求和、积分运算例1.7 卷积的两种计算方法例1.8 卷积的位移特性例1.9 卷积概念的…

dynamodb java_使用Java扫描DynamoDB项目

dynamodb java在之前的文章中&#xff0c;我们介绍了如何查询DynamoDB数据库 查询DynamoDB第1部分 查询DynamoDB第2部分 。 除了发出查询之外&#xff0c;DynamoDB还提供扫描功能。 扫描所做的是获取您在DynamoDB表上可能拥有的所有项目。 因此&#xff0c;扫描不需要任何基…

【Python科学计算系列】行列式

1.二元线性方程组求解 import numpy as np a np.array([[3, -2], [2, 1]]) b np.array([12, 1]) d np.linalg.solve(a, b) print(d) 2.三阶行列式求值 import numpy as np a np.array([[1, 2, -4], [-2, 2, 1], [-3, 4, -2]]) d np.linalg.det(a) print(d) 3.行列式的余…

python写的hadoop实战_Hadoop实战

Hadoop实战1 Hadoop简介1.1 什么是Hadoop1.1.1 Hadoop概述1.1.2 Hadoop的历史1.1.3 Hadoop的功能与作用1.1.4 Hadoop的优势1.1.5 Hadoop的应用现状和发展趋势1.2 Hadoop项目及其结构1.3 Hadoop的体系结构1.3.1 HDFS的体系结构1.3.2 MapReduce的体系结构1.4 Hadoop与分布式开发1…

mfc 弹簧_弹簧活性样品

mfc 弹簧Spring-Reactive旨在为基于Spring的项目带来响应式编程支持 &#xff0c;并且有望在Spring 5的时间表中提供。 我的意图是使用此模型为REST端点行使一些非常基本的签名。 在继续之前&#xff0c;请允许我确认整个样本完全基于塞巴斯蒂安德勒兹&#xff08;SbastienDel…

【Python科学计算系列】矩阵

1.矩阵的幂计算&#xff08;设计思想&#xff1a;递归&#xff09; #!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np def matrixPow(Matrix,n):if(type(Matrix)list):Matrixnp.array(Matrix)if(n1):return Matrixelse:return np.matmul(Matrix,matrixPow(…

layui按钮展开、_layui可折叠的组织架构树形图

layui.config({base: module/}).extend({treetable: treetable-lay/treetable}).use([layer, table, treetable], function () {var $ layui.jquery;var table layui.table;var layer layui.layer;var treetable layui.treetable;// 渲染表格var renderTable function () …

swarm 本地管理远程_带有WildFly Swarm的远程JMS

swarm 本地管理远程我再次在博客中谈论WildFly群&#xff1f; 简短的版本是&#xff1a;我需要对远程JMS访问进行测试&#xff0c;并且拒绝设置复杂的功能&#xff08;如完整的应用程序服务器&#xff09;。 这个想法是要有一个简单的WildFly Swarm应用程序&#xff0c;该应用程…