Can I force a commit on change sets?

I’m working on a CustomTaskChange, but it appears that other change sets that run before it have not committed.  The result is that I get an error that the column I added in a previous change set doesn’t exist.  Is there some way to force a commit after a specific change set has completed?

Here’s an example change log file to help illustrate:

           

It seems like changeSet “a” has run but is not yet committed.  So, when changeSet “b” runs and tries to manipulate the new column, I get SQL Exceptions.

It should commit after ever changeSet.  On most databases, addColumn autocommits as well.

What version of liquibase and what database are you running?

Nathan

Liquibase 1.9.3, and in this particular case the database is H2, in-memory.

I thought that it should have committed between change sets.  That’s why I added the custom task change as a separate change set.  It just doesn’t seem to be behaving as expected.

According to http://www.h2database.com/html/grammar.html#alter_table_add, add column will auto-commit.  What if you add an extra addColumn to add an extra column, to see if that commits your first addColumn?

Nathan

Adding an extra column did not make any difference.
I did upgrade to the 1.9.5 version of Liquibase, just in case it might make a difference.

Even if the dml alter table statement only committed before the call, the second addColumn change should have forced the first to commit.

If you select * from databasechangelog do you see the changeset a marked as ran?

Nathan

In the case of my test configuration, I can’t see the contents of the DATABASECHANGELOG table.  It disappears once the test run is finished.

I ran the updates against my static MySQL database.  In this case, the change set that includes the addColumn does run and the column is added.  The change set containing the custom task change did not.  It failed because it could not find resources on the classpath (the second problem I alluded to above).

Maybe I can add some code to my custom task change to inspect the DATABASECHANGELOG table.  I’ll work on that to see if I can verify that the first change set completes in the test configuration.

Dave

Well, in looking to see if the row showed up in DATABASECHANGELOG, I have discovered that something has changed.  Indeed the first change set finishes and is marked.  So, it would appear that my customer_id column is showing up, now.  Now, the error has become a LazyInitializationException.  I guess I don’t have a Hibernate session available in the thread for my persistent objects to make use of.  So, I’ll be working on that.

I’m not sure what I changed to suddenly get past the original problem.

I don’t anticipate having any issues with the lazy init problem, but once I get the code to work in the test environment I’ll likely be back asking about that classpath resource issue - unable to find my Spring configuration using the Liquibase Maven plugin.

Anyway, thanks for the input.  I guess I was chasing ghosts.
Dave

Glad you’re making progress.  let us know if you run into anything else

Nathan

It’s back!   ???

This has got to be one of the strangest problems I’ve encountered in a LONG time.  I cannot get it to fail on my own machine, but it fails for another developer.  I have intermittent pass/fail results on our CI server.

Is it possible that a timing delay (or lack thereof) could cause my custom task change to fail because the previous changeset hasn’t quite completed, yet?  In the cases where it fails, the table in question doesn’t have the new column that was added in the previous step.

Edit:  I should add that adding a Thread.sleep(10000) into my custom task change doesn’t change the outcome.  So, a timing problem seems unlikely.  I’m stumped, but this is really causing us a lot of grief.

Thanks,
Dave

You said you are using H2?  Could it be a case where you are accidentally creating or using a new connection and therefore new database sometimes?

Nathan

Crap!  I think you’re onto something here, Nathan.

My test case runs a snippet of code I found somewhere here on the forum (I think) that runs the Liquibase update on the in-memory database.  Here’s that snippet:

            FileOpener fileOpener = new FileSystemFileOpener();         DatabaseFactory databaseFactory = DatabaseFactory.getInstance();         Database database = null;         Connection connection = getConnection();         database = databaseFactory.findCorrectDatabaseImplementation(connection);         Liquibase liquibase = new Liquibase(databaseChangeLogFile, fileOpener, database);         liquibase.update("test");         connection.close();

Now, the trick is that my custom task change loads a Spring configuration that includes an EntityManagerFactory.  So, I’ll bet you’re right.  I’m getting a new connection and it doesn’t see the database that it should.  So, I guess the new question would be, is there some way for me to get the connection that is created in this snippet of code into my DAO beans?  Or, can I configure the Spring beans in such a way that they find the existing in-memory database?  I’ll have to dig into that.

Good call!
Dave