Hibernate Based Migrations are a simple method to do complex migrations of persisted data using Hibernate. Since Hibernate mappings and annotated entity classes always represent the current state of the persisted data, the Maven plugin offers goals to freeze files in a specific version and thaw them in a later version to use in a Migration class. Hibernate Migrations leverage Flyway's rarely used Java-based-Migrations feature.
<plugin>
<groupId>dev.bodewig.hibernate-based-migration</groupId>
<artifactId>hibernate-based-migration-plugin</artifactId>
<version>1.0.2</version>
</plugin>
<plugin>
...
<executions>
<execution>
<id>thaw</id>
<goals>
<goal>thaw</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
...
<executions>
<execution>
<id>freeze</id>
<goals>
<goal>freeze</goal>
</goals>
<configuration>
<persistenceClassesFileList>
<file>src/main/java/dev/bodewig/hibernate_based_migration/example/Fruit.java</file>
</persistenceClassesFileList>
<persistenceResourcesFileList>
<file>src/main/resources</file>
</persistenceResourcesFileList>
</configuration>
</execution>
</executions>
</plugin>
@Entity
public class Fruit {
@Id
public String name;
public int weight;
public String colorHex; // --> public String colorRgb;
}
src
|- main
|- migration
|- 1
| |- java/...
| |- resources/...
|- 2
|- java/...
|- resources/...
<dependency>
<groupId>dev.bodewig.hibernate-based-migration</groupId>
<artifactId>hibernate-based-migration</artifactId>
<version>1.0.0</version>
</dependency>
7. Subclass HibernateMigration to create a migration between the frozen versions of your persistence files (read the Hibernate configuration from the frozen version directories)
public class V1__My_Migration extends HibernateMigration {
private List<OldData> persistedData;
@Override
protected long getSerialVersionUID() { ... }
@Override
public Configuration configBefore() {
return new Configuration().configure("/_1/hibernate.cfg.xml");
}
@Override
public Configuration configAfter() {
return new Configuration().configure("/_2/hibernate.cfg.xml");
}
@Override
public void doBefore(StatelessSession session) {
this.persistedData = loadDataWithHibernate(session);
}
@Override
public void doSql(Context context) throws SQLException {
try (Statement stmt = context.getConnection().createStatement()) {
// change your database scheme
}
}
@Override
public void doAfter(StatelessSession session) {
NewData data = migrateData(this.persistedData);
saveDataWithHibernate(data);
}
}
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>9.22.0</version>
</plugin>
<plugin>
...
<executions>
<execution>
<id>migrate</id>
<goals>
<goal>migrate</goal>
</goals>
</execution>
</executions>
</plugin>
Your database scheme and your persisted data have been migrated - without doing complex value transformations in pure SQL.
A full example implementation is available in the hibernate-based-migration-example.
Copy a set of files to a separate project directory, resolve the common package and place them in a versioned, named package.
Configuration option | Description | Default/Required | Example |
---|---|---|---|
freezeVersion | The version used to store frozen files and to calculate the base package name | If no version is supplied the frozenDir is inspected for existing versions and tries to increment. If no prior version is found starts with version 1 | 1 |
frozenDir | Output directory for the frozen persistence files | ${project.basedir}/src/migration/ |
${project.basedir}/migration/ |
persistenceClassesFileList | Define persistence classes to freeze (can be used in conjunction with persistenceClassesGlobList) | Requires one of persistenceClassesFileList, persistenceClassesGlobList | <persistenceClassesFileList> <file>src/main/java/my/db/classes/Person.java</file> <file>src/main/java/my/db/classes/pkg</file> ... </persistenceClassesFileList> |
persistenceClassesGlobList | Define persistence classes to freeze (can be used in conjunction with persistenceClassesFileList) | Requires one of persistenceClassesFileList, persistenceClassesGlobList | <persistenceClassesGlobList> <glob>path/relative/to/./src/main/java/my/db/classes/C*.java</glob> ... <glob> <basePath>${project.build.sourceDirectory}</basePath> <pattern>Bi*.java</pattern> </glob> </persistenceClassesGlobList> |
persistenceResourcesFileList | Define resources to freeze (can be used in conjunction with persistenceResourcesGlobList) | Requires one of persistenceResourcesFileList, persistenceResourcesGlobList | <persistenceResourcesFileList> <file>src/main/resources/logging.xml</file> <file>src/main/resources/config</file> ... </persistenceResourcesFileList> |
persistenceResourcesGlobList | Define resources to freeze (can be used in conjunction with persistenceResourcesFileList) | Requires one of persistenceResourcesFileList, persistenceResourcesGlobList | <persistenceResourcesGlobList> <glob>path/relative/to/./src/main/resources/*.xml_bak</glob> ... <glob> <basePath>${project.build.resourceDirectory}</basePath> <pattern>*.conf</pattern> </glob> </persistenceResourcesGlobList> |
resourceFilteringExcludeFileList | List of persistenceResourcesFiles that should not be considered when replacing package references (can be used in conjunction with resourceFilteringExcludeGlobList) | Defaults to empty list | <resourceFilteringExcludeFileList> <file>src/main/resources/logging.xml</file> <file>src/main/resources/config</file> ... </resourceFilteringExcludeFileList> |
resourceFilteringExcludeGlobList | List of persistenceResourcesGlobs that should not be considered when replacing package references (can be used in conjunction with resourceFilteringExcludeGlobList) | Defaults to empty list | <resourceFilteringExcludeGlobList> <glob>path/relative/to/./src/main/resources/*.xml_bak</glob> ... <glob> <basePath>${project.build.resourceDirectory}</basePath> <pattern>*.conf</pattern> </glob> </resourceFilteringExcludeGlobList> |
Target a range of versioned frozen files to include them for compilation.
Configuration option | Description | Default/Required | Example |
---|---|---|---|
frozenDir | Directory of the frozen persistence files | ${project.basedir}/src/migration/ |
${project.basedir}/migration/ |
versionRange | Frozen versions to include as project source. Uses the default maven version range format. | Defaults to all versions | [15,) |
Run git config --add include.path ../.gitconfig
to include the template config in your project config.