IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> hibernate ConstraintViolationException uplicate primaryKey -> 正文阅读

[Java知识库]hibernate ConstraintViolationException uplicate primaryKey

调用hibernateTamplate的merge方法,抛出异常ConstraintViolationException违背一致性异常,merge时难道不是当数据库存在此主键时update,不存在时insert吗,怎么会报主键冲突呢?即hibernate认为数据库没有,所以merge时执行了insert。

ConstraintViolationException

刚开始把这个单词都理解错了:此意违背数据完整性约束(database integrity constraint),它是造成SpringDataIntegrityViolationException的最常见的原因: spring-dataIntegrityviolationexception;英语不达标不利于解决问题

StackOverflow: merge performs insert instead of update

jpa-hibernate-merge-performs-insert-instead-of-update
有回答:

I had a version column which was not set when seed data was inserted into database. Hence all the problems with update and delete

是version字段引起的,hibernate用version字段做乐观锁,所以问题又回到了之前遇到entity删除删不掉了
https://quizix.gitbooks.io/hibernate/content/hibernate_user_guide/9_locking.html

A version or timestamp property can never be null for a detached instance. Hibernate detects any instance with a null version or timestamp as transient, regardless of other unsaved-value strategies that you specify. Declaring a nullable version or timestamp property is an easy way to avoid problems with transitive reattachment in Hibernate, especially useful if you use assigned identifiers or composite keys.
对于一个detached实例,version和timestamp属性永远不能为null。Hibernate检测到任何version或者timestamp属性为null的instance均视为transient。忽视你指定的其他未被保存的值。Hibernate中声明一个空的version或者timestamp属性是一个简单的办法来避免转换重附着,当你使用了指定Id或组合键时非常有用

回答中另一个例子:hibernate-merge-may-insert-new-record
级联查出的属性entity(UserUserDetail属性),在保存的时候并没有Id,所以merge时执行了insert而不是update。

Detached–>Entity的状态

detach
不受EntityManager管理的对象,但仍代表数据库里的一个记录;文中列举了三个属性:

  1. 许多JPA方法不支持在detached实例
  2. Retrieval by navigation from detached objects is not supported, so only persistent fields that have been loaded before detachment should be used. 这句话没读懂,大意应该是只有在detached前的persistent域才能使用(好像还能部分field受管理,即取回部分,取决于策略)
  3. 修改一个detached实例并不会影响到数据库,除非merge,重新接收EntityManager管理
    另外提一点关于merge(文中的级联merge与detach就不讲了):

The content of the specified detached entity object is copied into an existing managed entity object with the same identity (i.e. same type and primary key). If the EntityManager does not manage such an entity object yet a new managed entity object is constructed. The detached object itself, however, remains unchanged and detached.

对于merge方法,如果EntityManager中没有同样Id的实例,则new一个,否则复制其状态;但是这个待merge对象(merge的参数)本身依然没有变化、依然detached,但merge返回的是受管理的实例。
有人就提问了JPA的persistmerge的区别:(jpa-entitymanager-why-use-persist-over-merge)[https://stackoverflow.com/questions/1069992/jpa-entitymanager-why-use-persist-over-merge] 第一个回答中我们得知,persist区别在,传入的实例就是那个受管理的实例,后续对实例的修改(flush后)也会影响到数据库

再来看Entity的所有状态:
Working with JPA Entity Objects entity都有哪些状态?Transient Persistent Detached
JAP的Entity状态变迁(来自StackOverflow回答:https://stackoverflow.com/a/30168342
在这里插入图片描述
Hibernate的状态变迁:
在这里插入图片描述
hibernate对EntityManager的实现在类:org.hibernate.impl.SessionImpl hibernate-core-3.6.10.Final.jar
baeldung对各种hibernate API的详细讲解,非常值得阅读hibernate-save-persist-update-merge-saveorupdate

回到问题

问题简化成了:从数据库取出一个Entity,其version字段为NULL—>修改某个属性—>hibernate的merge 抛出异常ConstraintViolationException
我大致追了下hibernate的代码,看到每个数据库(不准确)操作请求都被转换成一个Event,比如MergeEventLoadEventUpdateEvent,然后都会提供默认的Listener去处理这些事件,最终的DefaultMergeEventListener我是没看明白。
我猜测是,因为受管理的Entity的version为NULL,则认为它是Transient状态的,于是就new了一个,把merge参数那个实例的所有属性都复制过来(包括primaryKey),然后执行insert

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-11-19 17:30:07  更:2021-11-19 17:32:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:50:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码