背景
在一个新的数据库上启动项目,报了一堆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实现。有时间再来贴代码。