Skip to content
AB

Azra Balić

Product Manager

1 article

July 19, 2022

Java-based Migrations

Software Development

Java-based Migrations

It is important to develop a well-designed schema at the beginning of the project, but with the new requirements, changing your initial schema is hard to avoid. These changes must be carefully applied to avoid compromising existing data but also to meet new expectations. Migration group changes that modify database structure. It allows controlled transition from their current state to a new desired state (e.g., adding, deleting columns or tables). One of the commonly used open-source database migrations tools is Flyway. It updates a database from one version to the next using migrations. For a single migration, all statements are run within a single database transaction. Migrations can be written in SQL or Java for advanced database transformations. Flyway’s SQL-script based migrations are good enough for most use cases. Java-based migrations provide an easy and powerful way to implement requested logic to adapt existing data in case SQL script cannot be used. Flyway automatically finds and executes SQL scripts as well as migration classes. CREATE TABLE demo_user ( id UUID PRIMARY KEY, name VARCHAR(100) NOT NULL ); Simple SQL migration V1__init.sql Java-based migrations must implement the JavaMigration interface. However, it is easier to extend BaseJavaMigration abstract class as it encourages Flyway’s default naming convention, enabling Flyway to automatically extract the version and the description from the class name. It only remains to implement the interface. Class name should follow Flyway’s naming schema <Prefix><Version>__<Description>.java. When migrations are being run, Flyway detects the current database version, scans for all SQL and Java migrations, and executes the required ones. Mentioned naming schema parts have different interpretations: Prefix - V for versioned migrations, U for undo migrations, R for repeatable migrations Version - Migration version number. Major and minor versions may be separated by an underscore. Underscores are automatically replaced by dots at runtime. Description - Textual description of the migration. A double underscore separates the description from the version numbers. Single underscores (automatically replaced by spaces at runtime) separate the words. @Component public class V2__trigger_java_migration extends BaseJavaMigration { @Override public void migrate(Context context) { System.out.println("Triggering V2 migration..."); } } Simple Java-based migration As part of the migration run, Flyway performs change detection validation using a migration checksum. Java-based migrations, by default, do not have a checksum, so to be considered for the mentioned validation, getChecksum()method must be implemented. When using Flyway in combination with Spring Boot and Hibernate, auto-configuration ensures that database migrations have run before Hibernate is initialized. That is, one should not rely on Flyway auto-configuration and use Flyway to populate tables created by Hibernate. The solution is to use Flyway to both create and populate tables, along with switching off Hibernate’s table creation: spring.jpa.hibernate.ddl-auto=none Another solution is to disable Flyway auto-configuration: flyway.enabled=false With this, it is possible to adjust the configuration to support the requested changes. Flyway initialization time can be changed, and one useful use case is depending on Hibernate. Another use case that may come in handy is using Dependency Injection and already defined application beans, running Java migrations after application startup. This approach requires defining component with custom Flyway configuration that will pick up both SQL and Java migrations. @Component public class FlywayConfiguration implements CommandLineRunner { private JavaMigration[] javaMigrations; private DataSource dataSource; public FlywayConfiguration(DataSource dataSource) { this.dataSource = dataSource; } @Autowired public void setJavaMigrations(JavaMigration[] javaMigrations) { this.javaMigrations = javaMigrations; } @Override public void run(String... args) { Flyway flyway = Flyway.configure() .dataSource(dataSource) .javaMigrations(javaMigrations) .load(); flyway.migrate(); } } Flyway custom configuration After configuring Flyway initialization time, Java migration class can use service methods, etc. Note: this feature is available with importing flyway-core dependency version 6.0.0 and higher. @Component public class V3__insert_demo_user extends BaseJavaMigration { private final DemoUserService demoUserService; public V3__insert_demo_user(DemoUserService demoUserService) { this.demoUserService = demoUserService; } @Override public void migrate(Context context) throws Exception { demoUserService.createDemoUser("John Doe"); } } Java-based migration using Dependency Injection Flyway keeps track of all created migrations, marking them as pending, successful, or failed. All this information (and much more) provides an automatically created flyway_schema_history table. This way, all database versioning, and made changes are being monitored in one place.  version description type checksum execution time success 1 init SQL -899440118 7 true 2 trigger java migration JDBC [null] 2 true 3 insert demo user JDBC [null] 92 true Relevant information about executed migrations Interested in more? Click here for Atlantbh Blogs and Success Stories about Software Development.

Ready to Achieve More?

We’ll help you reach your goals quickly with an easy and straightforward process to kick off our collaboration. Here’s what happens next.

STEP 1

Discovery Call

Let’s chat to understand your company, project needs, and answer any questions along the way.

STEP 2

Free Consultation

Work closely with our experts to explore the right solutions for your business.

STEP 3

Collaboration Proposal

We'll recommend the best strategy for your goals, ensuring you get the most from our expertise.

STEP 4

30-Day Cancellation
Policy Contract

Spoiler: It’s Never Been Used

Enjoy peace of mind while we deliver excellence from day one—our track record speaks for itself.

Services you're interested in (Optional)