JPA在ddl-auto=update时,首次执行报错Cant DROP; check that column/key exists

本文针对在新数据库上启动项目时遇到的Can't DROP错误进行了深入分析,并探讨了AbstractSchemaMigrator中的策略处理方式,最后提出了重写exporter的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

在一个新的数据库上启动项目,报了一堆Can't DROP xxx; check that column/key exists的错误,虽然不影响系统正常启动,也不影响建表,但是影响心情。因此上网查询原因,发现大部分都没提到这个问题,要么就是顾左右而言他,回答不在点上。没办法,只好自己看源码。

原理

抽象数据库结构移植器(AbstractSchemaMigrator)在处理uniqueKeys(applyUniqueKeys)的时候,使用到三种策略,分别为先删后建静悄悄(DROP_RECREATE_QUIETLY)策略、只建不删静悄悄(RECREATE_QUIETLY)策略和啥都不做(SKIP)策略。

首先必须吐槽一下这个静悄悄处理,仅仅是做了一个tryCatch,然后做了忽略,但是没有想到错误的底层自己也有一套print策略,仍然将异常打印了出来(LogFilter中的isStatementLogErrorEnabled判断),所以根本不是彻底的静悄悄嘛。

其次来说一说这个默认使用的策略DROP_RECREATE_QUIETLY,主要是靠exporter.getSqlDropStrings创建的DROP的Sql,我们发现其默认使用的exporter的标准实现StandardUniqueKeyExporter创建出来的就是一条非常标准的DROP语句,类似于alter table xxx drop index yyy,当然会在yyy不存在时报错了

Workaround

初步可以考虑重写exporter,替代默认的StandardUniqueKeyExporter实现。有时间再来贴代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值