hibernate 刷新_Hibernate事实:了解刷新操作顺序很重要
hibernate 刷新
Hibernate将开发人员的思维方式从思考SQL转变为思考对象状态转换。 根据Hibernate Docs,实体可能处于以下状态之一:
- new / transient:实体不与持久性上下文相关联,因为它是数据库不知道的新创建的对象。
- 持久性:实体与持久性上下文相关联(位于第一级缓存中),并且存在一个表示该实体的数据库行。
- 分离:实体先前与持久性上下文相关联,但是持久性上下文已关闭,或者手动移出了实体。
- 已删除:实体被标记为已删除,并且持久性上下文将在刷新时从数据库中将其删除。
通过调用EntityManager方法来将对象从一种状态移动到另一种状态,例如:
- 坚持()
- 合并()
- 去掉()
级联允许将给定事件从父级传播到子级,也简化了实体关系管理的管理。
在刷新期间,Hibernate会将当前持久性上下文记录的更改转换为SQL查询。
现在,请考虑以下代码中发生了什么(为简洁起见,将其简化):
@Entity
public class Product {@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "product", orphanRemoval = true)@OrderBy("index")private Set images = new LinkedHashSet();public Set getImages() {return images;}public void addImage(Image image) {images.add(image);image.setProduct(this);}public void removeImage(Image image) {images.remove(image);image.setProduct(null);}
}@Entity
public class Image {@Column(unique = true)private int index;@ManyToOneprivate Product product;public int getIndex() {return index;}public void setIndex(int index) {this.index = index;}public Product getProduct() {return product;}public void setProduct(Product product) {this.product = product;}
}final Long productId = transactionTemplate.execute(new TransactionCallback() {@Overridepublic Long doInTransaction(TransactionStatus transactionStatus) {Product product = new Product();Image frontImage = new Image();frontImage.setIndex(0);Image sideImage = new Image();sideImage.setIndex(1);product.addImage(frontImage);product.addImage(sideImage);entityManager.persist(product);return product.getId();}
});try {transactionTemplate.execute(new TransactionCallback() {@Overridepublic Void doInTransaction(TransactionStatus transactionStatus) {Product product = entityManager.find(Product.class, productId);assertEquals(2, product.getImages().size());Iterator imageIterator = product.getImages().iterator();Image frontImage = imageIterator.next();assertEquals(0, frontImage.getIndex());Image sideImage = imageIterator.next();assertEquals(1, sideImage.getIndex());Image backImage = new Image();sideImage.setName("back image");sideImage.setIndex(1);product.removeImage(sideImage);product.addImage(backImage);entityManager.flush();return null;}
});fail("Expected ConstraintViolationException");
} catch (PersistenceException expected) {assertEquals(ConstraintViolationException.class, expected.getCause().getClass());
}
由于存在Image.index唯一约束,因此在刷新期间会收到ConstraintviolationException。
您可能想知道为什么会发生这种情况,因为我们在添加具有相同索引的backImage之前调用sideImage的remove,答案是刷新操作顺序。
根据Hibernate JavaDocs ,SQL操作顺序为:
- 插入
- 更新
- 集合元素的删除
- 集合元素的插入
- 删除
因为我们的图像集合是“ mappedBy”,所以图像将控制关联,因此“ backImage”插入发生在“ sideImage”删除之前。
select product0_.id as id1_5_0_, product0_.name as name2_5_0_ from Product product0_ where product0_.id=?
select images0_.product_id as product_4_5_1_, images0_.id as id1_1_1_, images0_.id as id1_1_0_, images0_.index as index2_1_0_, images0_.name as name3_1_0_, images0_.product_id as product_4_1_0_ from Image images0_ where images0_.product_id=? order by images0_.index
insert into Image (id, index, name, product_id) values (default, ?, ?, ?)
ERROR: integrity constraint violation: unique constraint or index violation; UK_OQBG3YIU5I1E17SL0FEAWT8PE table: IMAGE
要解决此问题,您必须在除去操作之后手动刷新持久性上下文:
transactionTemplate.execute(new TransactionCallback<Void>() {@Overridepublic Void doInTransaction(TransactionStatus transactionStatus) {Product product = entityManager.find(Product.class, productId);assertEquals(2, product.getImages().size());Iterator<Image> imageIterator = product.getImages().iterator();Image frontImage = imageIterator.next();assertEquals(0, frontImage.getIndex());Image sideImage = imageIterator.next();assertEquals(1, sideImage.getIndex());Image backImage = new Image();backImage.setIndex(1);product.removeImage(sideImage);entityManager.flush();product.addImage(backImage);entityManager.flush();return null;}
});
这将输出所需的行为:
select versions0_.image_id as image_id3_1_1_, versions0_.id as id1_8_1_, versions0_.id as id1_8_0_, versions0_.image_id as image_id3_8_0_, versions0_.type as type2_8_0_ from Version versions0_ where versions0_.image_id=? order by versions0_.type
delete from Image where id=?
insert into Image (id, index, name, product_id) values (default, ?, ?, ?)
- 源代码在这里 。
翻译自: https://www.javacodegeeks.com/2013/11/hibernate-facts-knowing-flush-operations-order-matters.html
hibernate 刷新
hibernate 刷新_Hibernate事实:了解刷新操作顺序很重要相关推荐
- php刷新onload(),JS页面刷新的方法总结
我们在前面介绍了JavaScript刷新页面location.reload()的用法,其实在JS中刷新页面的方法有很多种,这只是其中的一种,那么今天我们就带大家学习下JS刷新页面的方法总结! wind ...
- vue使用provide / inject 组合刷新页面+单独组件刷新
原文链接:https://www.cnblogs.com/leng12/p/xiaoleng.html 一.this.$router.go(0) 相当于F5刷新,这种方法虽然代码很少,只有一行,但是体 ...
- jquery刷新当前页面、刷新父级页面
jquery刷新当前页面.刷新父级页面 window.location.reload(); // 刷新当前页面 parent.location.reload(); // 刷新父级页面 opener.l ...
- 服务器刷新率和显示器刷新率,显示器的刷新率是什么?
显示器的刷新率是什么? 在早期的CRT时代,很少有玩家会去关注显示器刷新率这个参数,因为那个时代的显示器刷新率完全满足玩家们的需求,而到了液晶显示器时代早期的液晶显示器的刷新率大多在60Hz或75Hz ...
- 修改手机屏幕刷新率_什么是屏幕刷新率?高刷新率屏幕为手机带来什么
[维文信TP世界]当年乔布斯说道:"当你距离屏幕10-12英寸时,300以上的ppi就分辨不出像素点."显然,现在人们已经不再满足这"10-12英寸"距离的限制 ...
- android游戏boss坐标,热血江湖手游boss刷新点坐标 boss刷新时间 _图文攻略_高分攻略_百度攻略...
热血江湖手游的boss都是有固定的刷新时间和刷新坐标的,你如果不知道boss的刷新位置,好东西落入别人的口袋你就只能看看喽!下面小编给大家带来各boss刷新坐标和刷新时间. 在成功击杀BOSS后,参与 ...
- vue 添加完数据后刷新页面_页面刷新vuex数据消失
1.前言 vue构建的项目中,vuex的状态存储是响应式的,当vue组件从store中读取状态的时候,若store中的状态发生变化,那么相应的组件也会得到高效刷新,问题来了,vuex存储的数据只是在页 ...
- 用函数刷新页面内容比刷新页面要好
用函数刷新页面内容比刷新页面要好 app中有时需要更新页面的内容,这个时候可以选择刷新该页面 但如果使用函数来更改页面的内容,效果会更好: 例如 转载于:https://www.cnblogs.com ...
- Android PullToRefreshListView上拉刷新和下拉刷新
PullToRefreshListView实现上拉和下拉刷新有两个步骤: 1.设置刷新方式 pullToRefreshView.setMode(PullToRefreshBase.Mode.BOTH) ...
最新文章
- 编译器中代码自动对齐快捷键
- 根据注释生成项目文档
- 源服务器未能找到目标资源的表示或者不愿,java - 源服务器没有找到目标资源的当前表示,或者不愿意透露一个存在。 关于部署到 tomcat - 堆栈内存溢出...
- 在向服务器发送请求时发生传输级错误。
- 开发 高质量 android应用 pdf,《打造高质量Android应用》读书笔记
- 如何申请CSDN博客?
- 工作缺点和不足及措施_个人工作缺点和不足
- 5G注册流程分级详解Step4-8
- 辉芒微IO单片机FT60F024-RB
- 卡片式超声波水表优势
- 常用小波基函数以及多尺度多分辨率的理解
- 成功解决raise AssertionError(“Torch not compiled with CUDA enabled“)AssertionError: Torch not compiled
- 计算机教育传播理论,-通信传播论文:计算机理论教育探讨
- Bursuite暴力破解实践
- 秋月之谋:恒生指数弱势反抽继续空,德指阴阳变幻继续空!
- L2TP客户端之Strongswan移植(一)
- Vue.js--下拉菜单组件
- Spark3大数据实时处理-Streaming+Structured Streaming 实战(完整版)
- 论文阅读笔记(1)Beyond Natural Motion: Exploring Discontinuity for Video Frame Interpolation——超越自然运动: 探索视频帧
- 【FPGA】定点数 数据位宽 运算 位宽截取
热门文章
- codeforces gym-101745 C-Infinite Graph Game 分块
- Spark入门(十五)之分组求最小值
- Oracle入门(五D)之如何设置show parameter显示隐含参数
- 装饰器模式(讲解+应用)
- Spring 知识点详解
- Java中的binarySearch方法
- ssh(Spring+Spring mvc+hibernate)——applicationContext.xml
- JS删除之前弹出一个带有确认和取消按钮的提示框confirm()
- 遍历线索化二叉树+图解
- xml vs db.properties