Use Atlas with Hibernate ORM to manage your database schema as code. By connecting your Hibernate entity classes to Atlas, you can define and edit your schema directly in Java. Atlas will then automatically plan and apply database schema migrations for you, eliminating the need to write migrations manually.
Atlas brings automated CI/CD workflows to your database, along with built-in support for testing, linting, schema drift detection, and schema monitoring. It also allows you to extend Hibernate with advanced database objects such as triggers, row-level security, and custom functions that are not supported natively.
- Declarative migrations - Use the Terraform-like
atlas schema apply --env hibernatecommand to apply your Hibernate schema to the database. - Automatic migration planning - Use
atlas migrate diff --env hibernateto automatically plan database schema changes and generate a migration from the current database version to the desired version defined by your Hibernate schema.
Install Atlas from macOS or Linux by running:
curl -sSf https://atlasgo.sh | shSee atlasgo.io for more installation options.
Add the provider to your Gradle project:
plugins {
id("io.atlasgo.hibernate-provider-gradle-plugin") version "0.1"
}This plugin adds a task named schema to the project. Running this task will print the schema generated by
Hibernate using entities and configurations taken from the runtime classpath.
The task implements the JavaExec task and the plugin does not make any configuration or dependency changes to the project.
Let's check that the task works by running the following command:
./gradlew -q schemaTo add the provider to your project, you need to add the hibernate-provider-maven-plugin plugin to the pluginManagement section in your pom.xml:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>io.atlasgo</groupId>
<artifactId>hibernate-provider-maven-plugin</artifactId>
<version>0.3.8</version>
</plugin>
</plugins>
</pluginManagement>
</build>A complete example can be seen in the examples folder.
The plugin adds a MOJO with a goal named 'schema' to your project.
You should add the plugin to
pluginManagementas it is not meant to be running in any specific phase of the build process.
Let's check that the goal is installed correctly by running:
mvn help:describe -Dplugin=hibernate-provider -Dgoal=schema
By default, the task is configured to scan the entire runtimeClasspath configuration and look for Jakarta (JPA) entities.
The task does not require a database connection, but it does need to configure Hibernate with a specific database dialect.
There are several flags and hooks you can use to configure how Hibernate is being initialized inside the task, we will explore these later.
In your project directory, create a new file named atlas.hcl with the following contents:
data "external_schema" "hibernate" {
program = [
"./gradlew",
"-q",
"schema"
]
}
env "hibernate" {
src = data.external_schema.hibernate.url
dev = "docker://mysql/8/dev"
migration {
dir = "file://migrations"
}
format {
migrate {
diff = "{{ sql . \" \" }}"
}
}
}For Maven, change the program field to use mvn instead of gradlew:
data "external_schema" "hibernate" {
program = [
"mvn",
"compile",
"-q",
"hibernate-provider:schema"
]
}The above configuration uses a dev database that is configured to use MySQL.
The SchemaTask is initializing Hibernate which typically uses the file hibernate.properties from your project to
determine which dialect it should be using.
If needed, you can override the dialect specification using the --properties flag.
For example, for PostgreSQL:
- define
jakarta.persistence.database-product-name=PostgreSQLinhibernate.properties- define
docker://postgres/15/dev?search_path=publicas atlas dev database inatlas.hcl
Now we can check that the configuration is working by inspecting the schema:
atlas schema inspect -w --env hibernate --url env://srcBoth the Gradle and Maven plugins support the following flags:
packages- List of package names (for exampleorg.example.myservice.model). If specified, only classes inside these packages will be considered during the entity scan. Given packages must be part of the classpathclasses- List of classes that will be added to the entity scan explicitly. Ignores thepackagesargument.properties- Name of a properties file used to override the default properties read by Hibernate.registry-builder- FQDN of a class that implementsjava.util.Function.Function<java.util.Properties, org.hibernate.service.ServiceRegistry>. Used when you need to override the defaultServiceRegistryinitialized by the task. Useful if you have a custom initialization process for Hibernate. The properties parameter is the default settings used by the plugin, including ones read from thepropertiesparameter.metadata-builder- FQDN of a class that implementsjava.util.Function.Function<org.hibernate.service.ServiceRegistry, org.hibernate.boot.Metadata>. Used when you need to override the defaultMetadataused by the task. mutually exclusive withpackagesandclassesarguments.enable-table-generators- Atlas does not currently support generated fields that require data initialization such asGenerationType.SEQUENCE,GenerationType.TABLE, andGeneration.AUTO. By default, the provider will throw an exception if it finds unsupported statements. By enabling this flag, the provider will print the unsupported SQL statements.- Make sure to apply the ignored statements (using
atlas migrate --env hibernate diff --edit) See more information on manual migrations here
- Make sure to apply the ignored statements (using
You can configure these flags by adding arguments in the external_schema block in atlas.hcl:
data "external_schema" "hibernate" {
program = [
"./gradlew",
"--properties", "other.properties"
"--classes", "org.example.model.Person"
"-q",
"schema"
]
}Or, if you are using Maven:
data "external_schema" "hibernate" {
program = [
"mvn",
"compile",
"-Dproperties", "other.properties"
"-Dclasses", "org.example.model.Person"
"-q",
"hibernate-provider:schema"
]
}Note: The '-q' flag is important, without it, Gradle/Maven will add additional output
Alternatively, you can define a new Gradle task:
import io.atlasgo.SchemaTask
tasks.register<SchemaTask>("my_schema") {
classes = listOf("org.example.model.Person")
}
And refer to this task in atlas.hcl:
data "external_schema" "hibernate" {
program = [
"./gradlew",
"-q",
"my_schema"
]
}Once you have the provider installed, you can use it to apply your Hibernate schema to the database:
You can use the atlas schema apply command to plan and apply a migration of your database to
your current Hibernate schema. This works by inspecting the target database and comparing it to the
Hibernate schema and creating a migration plan. Atlas will prompt you to confirm the migration plan
before applying it to the database.
atlas schema apply --env hibernate -u "mysql://root:password@localhost:3306/mydb"Where the -u flag accepts the URL to the
target database.
Atlas supports a versioned migration
workflow, where each change to the database is versioned and recorded in a migration file. You can use the
atlas migrate diff command to automatically generate a migration file that will migrate the database
from its latest revision to the current Hibernate schema.
run atlas migrate diff --env hibernate command and observe the migrations directory.
If you are using Spring in your project, you will need to import the hibernate-provider and create a new empty spring application, for example:
@SpringBootApplication
@PropertySource(value = {"classpath:schema-export.properties"})
public class Main {
public static void main(String[] args) {
new AnnotationConfigApplicationContext(Main.class);
}
}A complete example project is provided here
Try running the example by running:
atlas schema inspect -w --env hibernate --url env://srcinside the project directory.
We need to configure the spring application so that it will print the schema to stdout. Spring is often configured to load Hibernate during startup, by adding the configuration below, we instruct Spring to generate the schema during initialization and print it to stdout:
spring.jpa.properties.jakarta.persistence.schema-generation.database.action=create
spring.jpa.properties.hibernate.schema_management_tool=io.atlasgo.ConsoleSchemaManagementTool
Configuring the driver with dialect and version can be done either via the same configuration file or via a dedicated Bean. For example, in the example project, this configuration is used for MySQL 8:
spring.jpa.properties.jakarta.persistence.database-product-name=MySQL
spring.jpa.properties.jakarta.persistence.database-major-version=8
In your atlas.hcl file you will need to invoke the Spring application instead of the Gradle/Maven plugin.
This project is licensed under the Apache License 2.0.