There appears to be a bug in:
liquibase-core/src/main/java/liquibase/diff/compare/core/ForeignKeyComparator.java
Which was changed on 8/27/2013 for the 3.0.3 release.
If you have a precondition like this:
You will encounter this error since the ForeignKeyColumns and PrimaryKeyColumns aren’t set in the change set:
Caused by: liquibase.exception.MigrationFailedException: Migration failed for change set foo.xml::xxx:
Reason:
src/main/resources/db/activFoundation.xml : liquibase.precondition.core.ForeignKeyExistsPrecondition@5f96f335 : java.lang.NullPointerException
at liquibase.changelog.ChangeSet.execute(ChangeSet.java:310)
at liquibase.changelog.visitor.UpdateVisitor.visit(UpdateVisitor.java:28)
at liquibase.changelog.ChangeLogIterator.run(ChangeLogIterator.java:58)
at liquibase.Liquibase.update(Liquibase.java:135)
at org.liquibase.maven.plugins.LiquibaseUpdate.doUpdate(LiquibaseUpdate.java:31)
at org.liquibase.maven.plugins.AbstractLiquibaseUpdateMojo.performLiquibaseTask(AbstractLiquibaseUpdateMojo.java:24)
at org.liquibase.maven.plugins.AbstractLiquibaseMojo.execute(AbstractLiquibaseMojo.java:375)
… 21 more
Caused by: liquibase.exception.PreconditionErrorException: Precondition Error
at liquibase.precondition.core.ForeignKeyExistsPrecondition.check(ForeignKeyExistsPrecondition.java:76)
at liquibase.precondition.core.NotPrecondition.check(NotPrecondition.java:30)
at liquibase.precondition.core.AndPrecondition.check(AndPrecondition.java:34)
at liquibase.precondition.core.PreconditionContainer.check(PreconditionContainer.java:199)
at liquibase.changelog.ChangeSet.execute(ChangeSet.java:274)
… 27 more
I downloaded and changed the code to this and rebuilt locally and the issue is resolved. The change is checking the value of getForeignKeyColumns() and getPrimaryKeyColumns() for null before doing the comparison.
public boolean isSameObject(DatabaseObject databaseObject1, DatabaseObject databaseObject2, Database accordingTo, DatabaseObjectComparatorChain chain) {
if (!(databaseObject1 instanceof ForeignKey && databaseObject2 instanceof ForeignKey)) {
return false;
}
ForeignKey thisForeignKey = (ForeignKey) databaseObject1;
ForeignKey otherForeignKey = (ForeignKey) databaseObject2;
if (thisForeignKey.getName() != null && otherForeignKey.getName() != null) {
if (chain.isSameObject(thisForeignKey, otherForeignKey, accordingTo)) {
return true;
}
}
if (thisForeignKey.getForeignKeyColumns() != null && thisForeignKey.getPrimaryKeyColumns() != null &&
otherForeignKey.getForeignKeyColumns() != null && otherForeignKey.getPrimaryKeyColumns() != null) {
boolean columnsTheSame;
if (accordingTo.isCaseSensitive()) {
columnsTheSame = StringUtils.trimToEmpty(thisForeignKey.getForeignKeyColumns()).equals(StringUtils.trimToEmpty(otherForeignKey.getForeignKeyColumns())) &&
StringUtils.trimToEmpty(thisForeignKey.getPrimaryKeyColumns()).equals(StringUtils.trimToEmpty(otherForeignKey.getPrimaryKeyColumns()));
} else {
columnsTheSame = thisForeignKey.getForeignKeyColumns().equalsIgnoreCase(otherForeignKey.getForeignKeyColumns()) &&
thisForeignKey.getPrimaryKeyColumns().equalsIgnoreCase(otherForeignKey.getPrimaryKeyColumns());
return columnsTheSame &&
DatabaseObjectComparatorFactory.getInstance().isSameObject(thisForeignKey.getForeignKeyTable(), otherForeignKey.getForeignKeyTable(), accordingTo) &&
DatabaseObjectComparatorFactory.getInstance().isSameObject(thisForeignKey.getPrimaryKeyTable(), otherForeignKey.getPrimaryKeyTable(), accordingTo);
}
}
//false by default
return false;
}
I’m not sure this is the optimal solution, but certainly works.
Thanks in advance for help with this.
Andy
-
Learn
-
Resources
-
Free Tools
OSS Risk Scanner Database DevOps Risk AssessmentCheat Sheets
Snowflake + Liquibase Databricks + Liquibase -
eBooks
6 Liquibase Community Risks & How to Avoid Guide: SOC 2 Compliance at the Database Layer Guide: Quantify the Value of Liquibase Secure -
Comparison Guides
Liquibase vs. Flyway Liquibase vs. Bytebase Liquibase Community vs Liquibase Secure
-
- Quickstart
- Get Started
- Documentation
- University
-
Resources
- Connect
- Contribute
- Join
- Blog