Why is a change set applied twice?

Hi, Mark; yes, for reasons that have never been clear to me the filename (unless you do something about it; see below) is part of the primary key/unique identifier for a changeset.  Read that again: move the file and you’re running a new changeset.


Fortunately this severe design flaw is correctable by using the logicalFilePath attribute.  You can use this attribute on either a databaseChangeLog element (in which case it will apply to all its children) or on individual changeSet elements (undocumented).  A logicalFilePath actually has nothing whatsoever to do with files or paths—it is simply the third of three items that make up a changeset’s identity, and can be anything you like.


I heartily encourage you to place it—redundant though it might be—on every changeSet element.  That way, too, if you move a changeset from one changelog file to another, you don’t inadvertently create a new changeset.


Best,

Laird



http://about.me/lairdnelson

I have a copy of a changelog in two separate folders.  I run the changelog in the first folder successfully.


Then, when I run the second (copy) changelog I would have thought that the given changeset would be listed as already run and not run again. This isn’t the case - the identical changset is re-executed.  This happens with all my changesets, not just one. This one in, in particular, is idempotent, but other steps are not and must only be executed once.


Here is the result as recorded in the databasechangelog:


select * from databasechangelog where id like ‘%drop-obsolete-admin-functions%’;

              id               | author |                               filename                               |         dateexecuted          | orderexecuted | exectype |               md5sum               | description |                                comments                                 | tag | liquibase 

-------------------------------±-------±---------------------------------------------------------------------±------------------------------±--------------±---------±-----------------------------------±------------±------------------------------------------------------------------------±----±----------

 drop-obsolete-admin-functions | 2.1.1  | wdts.db.changelogs/wdts_local.wdts_admin.changelog-2.1.1.xml         | 2012-07-05 18:55:27.439518-04 |            13 | EXECUTED | 3:92a6358f4df9f7dddac7e0626befea18 | Custom SQL  | drop obsolete admin functions that were created in the wdts_mgmt schema |     | 2.0.1

 drop-obsolete-admin-functions | 2.1.1  | wdts.db.changelogs-revised/wdts_local.wdts_admin.changelog-2.1.1.xml | 2012-07-09 10:39:10.301812-04 |           103 | EXECUTED | 3:92a6358f4df9f7dddac7e0626befea18 | Custom SQL  | drop obsolete admin functions that were created in the wdts_mgmt schema |     | 2.0.1

(2 rows)



Note that the ID, AUTHOR, and MD5 are identical. 



And here is the changeset in question:


   

        drop obsolete admin functions that were created in the wdts_mgmt schema

       

            DROP FUNCTION IF EXISTS wdts_mgmt.f_update_config_prop_val(


Can someone explain why/how the changeset is run the second time? Is the filename a part of the identifier of the step, so a different filename would trigger the second execution?


I’m running Liquibase 2.0.1, and Java 1.6.0_31 (on Mac).


Thanks!



Mark

Hi Laird,


Thanks so much for the clear answer. logicalFilePath is indeed the answer, given the current definition of primary keys for a changeset. I will post again with results of the update.



Mark

Success!  Thanks for the pointer.  I’m using a combination of logicalFilePath on changelog and changset items to get the desired behavior.


Mark