title: How to use Liquibase with Spring-Boot JPA and Maven to manage migrations from JPA entities
body: <p>I've been trying to use <a href="https://www.liquibase.org/" rel="noreferrer">liquibase</a> to manage migrations on a Spring JPA project similarly as Python/Django does with <code>makemigrations</code>. Liquibase <a href="https://docs.liquibase.com/home.html" rel="noreferrer">documentation</a> is extremely confusing, and I've tried to follow a number of SA answers and tutorials I found online but to no avail.</p>
  <p>Here's what I'm trying to do:</p>
  <ol>
  <li>Define entities via JPA annotated classes.</li>
  <li>Generate a migration to reflect those entities on a MySQL DB.</li>
  <li>Apply said migration on the database. (Initially empty)</li>
  </ol>
  <p>So far I'm able to generate a &quot;diff&quot; changeLog file and somehow managed to get liquibase to create the <code>databasechangelog</code> and <code>databasechangeloglock</code> tables on an empty DB. However, I've not been able to have the <code>master.xml</code> file updated with the diff or have the diff applied on the DB.</p>
  <p>Here's my config so far (basic spring-jpa project with just one entity for testing):</p>
  <p><strong>Pom.xml (abbreviated)</strong></p>
  <pre><code>&lt;project&gt;
      &lt;parent&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
          &lt;version&gt;2.4.3&lt;/version&gt;
          &lt;relativePath/&gt;
      &lt;/parent&gt;
      &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
      &lt;groupId&gt;my-group&lt;/groupId&gt;
      &lt;artifactId&gt;web&lt;/artifactId&gt;
      &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
  
      &lt;properties&gt;
          &lt;maven.compiler.source&gt;15&lt;/maven.compiler.source&gt;
          &lt;maven.compiler.target&gt;15&lt;/maven.compiler.target&gt;
      &lt;/properties&gt;
  
      &lt;dependencies&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-validation&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;mysql&lt;/groupId&gt;
              &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.liquibase&lt;/groupId&gt;
              &lt;artifactId&gt;liquibase-core&lt;/artifactId&gt;
              &lt;version&gt;4.3.2&lt;/version&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
              &lt;scope&gt;test&lt;/scope&gt;
          &lt;/dependency&gt;
      &lt;/dependencies&gt;
      &lt;build&gt;
          &lt;plugins&gt;
              &lt;plugin&gt;
                  &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
                  &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
              &lt;/plugin&gt;
              &lt;plugin&gt;
                  &lt;groupId&gt;org.liquibase&lt;/groupId&gt;
                  &lt;artifactId&gt;liquibase-maven-plugin&lt;/artifactId&gt;
                  &lt;version&gt;4.3.2&lt;/version&gt;
                  &lt;configuration&gt;
                      &lt;changeLogFile&gt;src/main/resources/db/changelog-master.xml&lt;/changeLogFile&gt;
                      &lt;diffChangeLogFile&gt;src/main/resources/db/diff-changelog.xml&lt;/diffChangeLogFile&gt;
                      &lt;outputChangeLogFile&gt;src/main/resources/db/out-changelog.xml&lt;/outputChangeLogFile&gt;
                      &lt;driver&gt;com.mysql.jdbc.Driver&lt;/driver&gt;
                      &lt;referenceUrl&gt;hibernate:spring:my.project.model?dialect=org.hibernate.dialect.MySQL5Dialect&amp;amp;hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&amp;amp;hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy&lt;/referenceUrl&gt;
                      &lt;url&gt;jdbc:mysql://localhost:3306/my-db?useSSL=false&lt;/url&gt;
                      &lt;username&gt;user&lt;/username&gt;
                      &lt;password&gt;pass&lt;/password&gt;
                      &lt;outputDefaultSchema&gt;true&lt;/outputDefaultSchema&gt;
                  &lt;/configuration&gt;
                  &lt;dependencies&gt;
                      &lt;dependency&gt;
                          &lt;groupId&gt;org.liquibase.ext&lt;/groupId&gt;
                          &lt;artifactId&gt;liquibase-hibernate5&lt;/artifactId&gt;
                          &lt;version&gt;4.3.2&lt;/version&gt;
                      &lt;/dependency&gt;
                      &lt;dependency&gt;
                          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
                          &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
                          &lt;version&gt;2.4.3&lt;/version&gt;
                      &lt;/dependency&gt;
                      &lt;dependency&gt;
                          &lt;groupId&gt;org.springframework&lt;/groupId&gt;
                          &lt;artifactId&gt;spring-beans&lt;/artifactId&gt;
                          &lt;version&gt;5.3.4&lt;/version&gt;
                      &lt;/dependency&gt;
                      &lt;dependency&gt;
                          &lt;groupId&gt;org.springframework&lt;/groupId&gt;
                          &lt;artifactId&gt;spring-core&lt;/artifactId&gt;
                          &lt;version&gt;5.3.4&lt;/version&gt;
                      &lt;/dependency&gt;
                      &lt;dependency&gt;
                          &lt;groupId&gt;javax.validation&lt;/groupId&gt;
                          &lt;artifactId&gt;validation-api&lt;/artifactId&gt;
                          &lt;version&gt;2.0.1.Final&lt;/version&gt;
                      &lt;/dependency&gt;
                      &lt;dependency&gt;
                          &lt;groupId&gt;org.javassist&lt;/groupId&gt;
                          &lt;artifactId&gt;javassist&lt;/artifactId&gt;
                          &lt;version&gt;3.27.0-GA&lt;/version&gt;
                      &lt;/dependency&gt;
                  &lt;/dependencies&gt;
              &lt;/plugin&gt;
          &lt;/plugins&gt;
      &lt;/build&gt;
  &lt;/project&gt;
  </code></pre>
  <p><strong>application.properties</strong></p>
  <pre><code>spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
  spring.jpa.hibernate.ddl-auto=none
  spring.datasource.driver-class-name=com.mysql.jdbc.Driver
  spring.datasource.url = jdbc:mysql://localhost:3306/my-db?useSSL=false
  spring.datasource.username = user
  spring.datasource.password = pass
  spring.liquibase.enabled=true
  spring.liquibase.url=jdbc:mysql://localhost:3306/my-db?useSSL=false
  spring.liquibase.user=user
  spring.liquibase.password=pass
  spring.liquibase.change-log=classpath:db/changelog-master.xml
  logging.level.org.springframework=INFO
  hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
  hibernate.show_sql=true
  hibernate.hbm2ddl.auto=update
  hibernate.generate_statistics=true
  </code></pre>
  <p>I also added an empty changelog-master.xml file containing (namespaces excluded):</p>
  <pre><code>&lt;databaseChangeLog /&gt;
  </code></pre>
  <p>So, if I run <code>spring-boot:run</code> it creates those two databasechangelog tables.(no contents). I can then run <code>mvn liquibase:diff</code> which generates a diff.xml file (albeit with some hibernate warnings). This diff file makes sense to me:</p>
  <pre><code>&lt;?xml version=&quot;1.1&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
  &lt;databaseChangeLog&gt;
      &lt;changeSet author=&quot;tiago (generated)&quot; id=&quot;1618352585193-1&quot;&gt;
          &lt;createTable tableName=&quot;chunk&quot;&gt;
              &lt;column autoIncrement=&quot;true&quot; name=&quot;id&quot; type=&quot;BIGINT&quot;&gt;
                  &lt;constraints nullable=&quot;false&quot; primaryKey=&quot;true&quot; primaryKeyName=&quot;chunkPK&quot;/&gt;
              &lt;/column&gt;
              &lt;column name=&quot;x_origin&quot; type=&quot;BIGINT&quot;&gt;
                  &lt;constraints nullable=&quot;false&quot;/&gt;
              &lt;/column&gt;
              &lt;column name=&quot;y_origin&quot; type=&quot;BIGINT&quot;&gt;
                  &lt;constraints nullable=&quot;false&quot;/&gt;
              &lt;/column&gt;
          &lt;/createTable&gt;
      &lt;/changeSet&gt;
  &lt;/databaseChangeLog&gt;
  </code></pre>
  <p>But now, how do I apply this? How do I make that diff command &quot;append&quot; this particular diff to the master changelog? Running <code>mvn liquibase:update</code> does nothing. Also, the changelog tables on the DB remain empty.</p>
  <p>EDIT:
  I tried manually adding the diff to the master file like so:</p>
  <pre><code>&lt;databaseChangeLog&gt;
      &lt;include file=&quot;classpath:db/diff-changelog.xml&quot; /&gt;
  &lt;/databaseChangeLog&gt;
  </code></pre>
  <p>After running <code>changelogSync</code> and <code>update</code> I managed to get a record on the <code>databasechangelog</code> table. However the new table was not created.</p>
  <p>Thank you for the help,</p>