If only a soft migration instead of a big bang migration of an application to the cloud possible, the database must be shared between the old and the new application. Here is how we solved this in our project.
The situation before
We have a JEE based application on a portal server using JSF to deliver content to the user The relational database is accessed using JPA/Hibernate. The database schema is evolved executing flyway scripts during the deployment of the application. This application is released every 3 month.
The business logic of the application should extracted to a REST-Service running in a cloud, so that the business logic can be accessed both by the portal application (JSF) and some new applications developed by other teams. The deployment of the REST-Service should be as independent from the release cycle of the portal application is it could be, to support the needs of the new applications. The migration of the business logic can’t be done in one big bang step, because it would stop the development of new features for month. Therefore a smoth migration, where the old portal application and the new REST-Service uses the same database.
Both applications must use exactly the same database schema and the database schema can only be changed every three month when the portal application is released.
The new REST-Service is a Spring Boot application also using Hibernate to access the database. The easy part is to copy the JPA-Enties from the portal application to the REST-Service. But after the copy is done both applications can change the entities independent. When an entity is changed in one application, it must be changed in the other application. Because of the different release cycles of the applications, we have to prevent, that the two applications can be released based on different database schemas.
Because of its long release cycle the portal application is the master of the database schema. If the database migration scripts dont implement breaking changes (e.g. deleting a table or changing a tables name or adding not null columns), there should be no problem to deploy the REST-Service after the portal application is deployed.
Our migration solution
But when deploying the REST-Service it must be sure, that the database schema fits to JPA-Entities.
Hibernate Validation on startup
One solution is to validate the schema during startup. In Spring boot this can be activated in the application.yml
If the validation fails the application will be shut down. The advantage is that we are sure that schema fits to the JPA-Entities. The only problem with this solution is, that it costs time during the startup, depending on the count of the JPA-Entities.
Hibernate Validation by Integration-Test
The schema validation can also be implemented by an integration-test, which is executed during the build. If the schema does not match the test will fail. Unfortunately hibernate’s SchemaValidator ignores SQLExceptions merely logging their occurrence. This would for example happen when there is no suitable database driver found on the class path – no validation takes place, but the test passes anyway. Therefore the test also opens and immediately closes a transaction to verify that a connection to the database can be successfully established.
The advantage of this solution is, that server starts fast. The problem is, that the test is only executed building the application, not when deploying the application.
Check flyway version
Flyway has an extra table in the database containing the schema version. The application can check this version during the startup against a property in the application.yml. If the check fails the application will shutdown. The advantage of this solution is, that it is much more faster than the solution before. But if the error occurs it can be fixed quickly by the changing the application.yml, forgetting to change the JPA-Entities.