唯一键冲突到底抛 DuplicateKeyException 还是 DataIntegrityViolationException?JdbcTemplate、Spring Data、EntityManager 各抛什么?超长、not null、外键、语法错误、锁超时又各是什么?这篇用自己起的 MySQL 在 Spring Boot 4.0.8 上逐个触发。
重复的唯一键 email = a@x.com
JdbcTemplate:DuplicateKeyException(继承链 DuplicateKeyException → DataIntegrityViolationException → NonTransientDataAccessException → DataAccessException);原因链 SQLIntegrityConstraintViolationException;首行信息:StatementCallback; SQL [insert into acct values (2, 'a@x.com', 'bbb', null)]; Duplicate entry 'a@x.com' for key 'acct.email'
JPA 直接用 EntityManager.persist 加 flush:ConstraintViolationException(继承链 ConstraintViolationException → JDBCException → HibernateException → PersistenceException → );原因链 SQLIntegrityConstraintViolationException;首行信息:could not execute statement [Duplicate entry 'a@x.com' for key 'acct.email'] [insert into acct (email,name,parent_id,id) valu
Spring Data 的 saveAndFlush:DataIntegrityViolationException(继承链 DataIntegrityViolationException → NonTransientDataAccessException → DataAccessException);原因链 ConstraintViolationException ← SQLIntegrityConstraintViolationException;首行信息:could not execute statement [Duplicate entry 'a@x.com' for key 'acct.email'] [insert into acct (email,name,parent_id,id) valu三种写法抛三种异常。
name 列是 varchar(5),写入 7 个字符
JdbcTemplate:DataIntegrityViolationException(继承链 DataIntegrityViolationException → NonTransientDataAccessException → DataAccessException);原因链 MysqlDataTruncation;首行信息:StatementCallback; SQL [insert into acct values (2, 'b@x.com', 'abcdefg', null)]; Data truncation: Data too long for column '
JPA 直接用 EntityManager.persist 加 flush:DataException(继承链 DataException → JDBCException → HibernateException → PersistenceException → );原因链 MysqlDataTruncation;首行信息:could not execute statement [Data truncation: Data too long for column 'name' at row 1] [insert into acct (email,name,parent_
Spring Data 的 saveAndFlush:DataIntegrityViolationException(继承链 DataIntegrityViolationException → NonTransientDataAccessException → DataAccessException);原因链 DataException ← MysqlDataTruncation;首行信息:could not execute statement [Data truncation: Data too long for column 'name' at row 1] [insert into acct (email,name,parent_DataIntegrityViolationException,原因 MysqlDataTruncation。
name 列 not null,写入 null
JdbcTemplate:DataIntegrityViolationException(继承链 DataIntegrityViolationException → NonTransientDataAccessException → DataAccessException);原因链 SQLIntegrityConstraintViolationException;首行信息:StatementCallback; SQL [insert into acct values (2, 'b@x.com', null, null)]; Column 'name' cannot be null
JPA 直接用 EntityManager.persist 加 flush:ConstraintViolationException(继承链 ConstraintViolationException → JDBCException → HibernateException → PersistenceException → );原因链 SQLIntegrityConstraintViolationException;首行信息:could not execute statement [Column 'name' cannot be null] [insert into acct (email,name,parent_id,id) values (?,?,?,?)]
Spring Data 的 saveAndFlush:DataIntegrityViolationException(继承链 DataIntegrityViolationException → NonTransientDataAccessException → DataAccessException);原因链 ConstraintViolationException ← SQLIntegrityConstraintViolationException;首行信息:could not execute statement [Column 'name' cannot be null] [insert into acct (email,name,parent_id,id) values (?,?,?,?)]; SQLDataIntegrityViolationException。
parent_id 外键指向不存在的 id 99
JdbcTemplate:DataIntegrityViolationException(继承链 DataIntegrityViolationException → NonTransientDataAccessException → DataAccessException);原因链 SQLIntegrityConstraintViolationException;首行信息:StatementCallback; SQL [insert into acct values (2, 'b@x.com', 'bbb', 99)]; Cannot add or update a child row: a foreign key c
JPA 直接用 EntityManager.persist 加 flush:ConstraintViolationException(继承链 ConstraintViolationException → JDBCException → HibernateException → PersistenceException → );原因链 SQLIntegrityConstraintViolationException;首行信息:could not execute statement [Cannot add or update a child row: a foreign key constraint fails (`demo`.`acct`, CONSTRAINT `acc
Spring Data 的 saveAndFlush:DataIntegrityViolationException(继承链 DataIntegrityViolationException → NonTransientDataAccessException → DataAccessException);原因链 ConstraintViolationException ← SQLIntegrityConstraintViolationException;首行信息:could not execute statement [Cannot add or update a child row: a foreign key constraint fails (`demo`.`acct`, CONSTRAINT `acc
删除被引用的父行
JdbcTemplate delete id=1:DataIntegrityViolationException(继承链 DataIntegrityViolationException → NonTransientDataAccessException → DataAccessException);原因链 SQLIntegrityConstraintViolationException;首行信息:StatementCallback; SQL [delete from acct where id = 1]; Cannot delete or update a parent row: a foreign key constraint fails插入与删除都是 DataIntegrityViolationException。
SQL 语法错误 / 表不存在 / 列不存在
JdbcTemplate 语法错误(form 写成了 from 的位置):BadSqlGrammarException(继承链 BadSqlGrammarException → InvalidDataAccessResourceUsageException → NonTransientDataAccessException → DataAccessException);原因链 SQLSyntaxErrorException;首行信息:StatementCallback; bad SQL grammar [select * form acct]
JdbcTemplate 表不存在:BadSqlGrammarException(继承链 BadSqlGrammarException → InvalidDataAccessResourceUsageException → NonTransientDataAccessException → DataAccessException);原因链 SQLSyntaxErrorException;首行信息:StatementCallback; bad SQL grammar [select * from nope]
JdbcTemplate 列不存在:BadSqlGrammarException(继承链 BadSqlGrammarException → InvalidDataAccessResourceUsageException → NonTransientDataAccessException → DataAccessException);原因链 SQLSyntaxErrorException;首行信息:StatementCallback; bad SQL grammar [select nope from acct]
JPA 原生 SQL 列不存在:SQLGrammarException(继承链 SQLGrammarException → JDBCException → HibernateException → PersistenceException → );原因链 SQLSyntaxErrorException;首行信息:JDBC exception executing SQL [Unknown column 'nope' in 'field list'] [select nope from acct]BadSqlGrammarException。
事务 A 锁住 id=1 的行并持有 3 秒,事务 B 更新同一行(服务端 innodb_lock_wait_timeout=1)
JdbcTemplate:CannotAcquireLockException(继承链 CannotAcquireLockException → PessimisticLockingFailureException → ConcurrencyFailureException → TransientDataAccessException → DataAccessException);原因链 MySQLTransactionRollbackException;首行信息:StatementCallback; SQL [update acct set name = 'zzz' where id = 1]; Lock wait timeout exceeded; try restarting transactionCannotAcquireLockException,Transient 分支。