我使用的是Spring Boot 2和Spring Boot starter数据jpa以及底层的MariaDB。
我有一个带有唯一键“用户名”的表。如果违反了此约束,我想捕获DataIntegrityViolationException
,但似乎Spring正在记录DataIntegrityViolationException
并且不会在记录后重新抛出(我最好的猜测)。MySQLIntegrityConstraintViolationException
被抛出。
我想在UserService.createUser(...)
中捕获DataIntegrityViolationException
。
以下是几段代码片段:
@Repository
@Transactional(propagation = Propagation.MANDATORY)
public class UserRepository {
@PersistenceContext
private EntityManager entityManager;
public void save(User user) {
entityManager.persist(user);
}
}
@Service
@Transactional(value = Transactional.TxType.REQUIRED)
public class UserService {
@Autowired
private UserRepository userRepository;
private void createUser(User user){
userRepository.save(user);
}
堆栈跟踪:
2018-09-22 14:20:33.163 WARN 10700 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1062, SQLState: 23000
2018-09-22 14:20:33.163 ERROR 10700 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : Duplicate entry 'kkflf' for key 'user_username_uindex'
2018-09-22 14:20:33.163 ERROR 10700 --- [nio-8080-exec-1] o.h.i.ExceptionMapperStandardImpl : HHH000346: Error during managed flush [org.hibernate.exception.ConstraintViolationException: could not execute statement]
2018-09-22 14:20:33.177 ERROR 10700 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [user_username_uindex]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'kkflf' for key 'user_username_uindex'
...
正如kkflf所说,在txn提交之前,异常通常不会抛出。如果需要抛出,可以在该行之后调用flush()。
然而,我学到了一种艰难的方法,即不要将其作为任何事情的条件逻辑。例如,我想尝试删除,如果不起作用,请执行其他操作。但是,如果有任何进一步的数据库活动涉及该对象(甚至通过引用),系统(spring/hibernate/whathaveyou)将不喜欢该状态。
正确的流程是在尝试操作之前自己在代码中检查条件。换句话说,不要将数据库用作IF语句:-)
// Just say 'no' to this:
if (DB doesn't like it) {
// do this
} else {
// do that
}
我解决了这个问题。
在事务提交之前不会发生异常,这是完全有道理的。
我能够在控制器类中捕获事务范围外的异常。
问题内容: 我正在尝试捕获“ android.database.sqlite.SQLiteException:错误代码5:数据库已锁定”异常,并带有: 由于某些原因,我仍然会收到错误消息,并且LogCat中没有显示“ caught”。我尝试捕获一般的“异常”,但这仍然行不通。怎么了? 更新, 我发现了这个问题,这确实很奇怪:由于某种原因,将goto10声明的db.insert()更改为db.ins
问题内容: 尽管我在日志中看到了异常,但似乎无法捕获到约束违例异常。 实体 我正试图抓住它 -它永远不会到达捕获块。 当我使用 捕获(异常e) 我捕获到“ javax.transaction.RollbackException:ARJUNA016053:无法提交事务。” 这是错误日志: 我究竟做错了什么 ? 更新>> 我当前的代码是: 日志是 环境:PostgreSQL 9.2 JBoss AS
问题内容: 我的IDE给我该行的错误 我试着抓住,但是并没有使错误消失。有什么想法吗? 问题答案: 扩展了,所以您的IDE本身就有了更深的麻烦-也许库导入被搞砸了?
我正在尝试捕获SocketTimeoutException,以便我的套接字保持活动状态,并且可以继续读取程序。不幸的是,无论我如何尝试捕获读取超时,我都无法捕获,因此应用程序关闭。
我有一个实体类Person,它通过JoinColumn连接到另一个实体Address,并且与Person有一个关系,Address实体在字段Country上有一个@NotNull注释。 简化代码如下: 我还有一个服务方法,即updateAddress,该方法最简单的形式如下: 我编写了一个小的单元测试,其中我试图使用updateAddress方法为一个没有预定义地址的人更新地址。 即 Transa
问题内容: 是否可以在Java中构建一小段代码,以使假设的代码无法捕获? 想到的想法正在使用例如拦截器或面向方面的编程。 问题答案: 我没有试过,所以我不知道,如果JVM将限制这样的事情,但也许你可以编译代码抛出,但在运行时提供了一个类定义的其 未延伸的Throwable 。 更新: 没用 它生成一个验证错误: 更新2: 实际上,如果禁用字节码验证程序,则可以使它正常工作!() 更新3: 对于那些