Spring Boot integration
Exposed provides Spring Boot 3 and Spring Boot 4 integration through the Exposed Spring Boot starter.
The starter integrates Exposed with Spring Boot’s autoconfiguration model and transaction infrastructure. It registers an Exposed-specific transaction manager and allows you to configure Exposed using standard Spring Boot configuration properties.
It also contributes the required runtime hints for GraalVM native image support, so you can build native executables without additional configuration in most cases.
Requirements
To use Exposed with Spring Boot, your project must meet the following requirements:
Kotlin 2.1.x
JDK 17 or newer
Spring Boot 3 and Spring Boot 4 both require JDK 17 or later. Ensure that your build tool (Gradle or Maven) and IDE target a compatible JDK version.
If you use Gradle, configure the JVM toolchain accordingly:
Add dependencies
Spring Boot 4
To use Exposed with Spring Boot 4, add the exposed-spring-boot4-starter artifact to your build script:
This starter includes the latest version of Exposed and its custom SpringTransactionManager class from the spring7-transaction library along with the Spring Boot Starter JDBC.
Spring Boot 3
For applications using Spring Boot 3, use the exposed-spring-boot-starter artifact:
Configure a database connection
The starter depends on spring-boot-starter-jdbc, so all standard Spring Boot datasource properties can be used to configure the database connection.
To configure a datasource, add the required properties to your src/resources/application.properties file. The following example configures the connection for an H2 in-memory database:
Configure Exposed
To integrate Exposed with Spring’s transaction infrastructure, you need to do the following:
Optionally, customize Exposed's default behavior by registering a database configuration bean.
Enable Exposed auto-configuration
To ensure that Exposed’s transaction manager is used, you need to first enable it and disable Spring Boot’s default DataSourceTransactionManager autoconfiguration.
You can apply the autoconfiguration directly to the class annotated with @SpringBootApplication:
Customize Exposed behavior
To customize the default Exposed behavior, register a DatabaseConfig bean:
Enable automatic schema creation
To generate database schemas from Exposed table definitions at startup, set the spring.exposed.generate-ddl property in your application.properties file:
When enabled, the starter detects all classes extending org.jetbrains.exposed.v1.core.Table and creates the schema during application startup.
Exclude packages
To exclude specific packages from automatic schema generation, use the spring.exposed.excluded-packages property in your application.properties file:
This is useful for shared modules or tables managed outside the application lifecycle.
Enable SQL logging
To log SQL statements executed by Exposed, enable the spring.exposed.show-sql property in your application.properties file:
This replaces the need to manually call addLogger() inside transactions and integrates with Spring Boot's logging system.
Manage transactions
The Exposed Spring Boot starter integrates directly with Spring’s declarative transaction model.
Use @Transactional
By annotating a service class or method with Spring’s @Transactional, Spring opens and closes the transaction for you. Inside the method, you can freely use Exposed DSL or DAO APIs without wrapping your code in transaction {} blocks:
Spring opens the transaction before invoking the method and commits or rolls it back when the method completes.
Register additional transaction managers
After configuring Exposed, you may still want to register additional transaction managers (for example, a plain JDBC or JPA manager).
Define them in separate @Configuration classes as usual:
Select a specific transaction manager using the transactionManager attribute of @Transactional:
Define composed annotations
To reduce repetition, you can define composed annotations:
Configure the primary transaction manager
If you register multiple transaction managers, annotate the bean of the default one with @Primary. Spring then uses it by default when @Transactional does not specify a manager.
GraalVM native image support
You can build a GraalVM native image of a Spring Boot application that uses the Exposed Spring starter without additional configuration.
The starter contributes the required runtime hints through the ExposedAotContribution class, which enables compatibility with Spring Boot’s AOT (Ahead-of-Time) processing.
AOT limitations
When you build a native image, Spring Boot applies AOT processing. AOT restricts dynamic configuration at runtime.
In particular, beans declared with @ConditionalOnProperty cannot change their behavior at runtime. As a result, setting spring.exposed.generate-ddl=true does not enable automatic schema creation in a native image.
Instead, create the database schema programmatically. For example:
Resolve KotlinReflectionInternalError: Unresolved class
If the native image build or runtime fails with KotlinReflectionInternalError: Unresolved class the application likely lacks required runtime hints for reflection.
To resolve this issue, implement RuntimeHintsRegistrar and register the missing types explicitly:
To register your implementation, use one of the following approaches:
Annotate a configuration class with
@ImportRuntimeHints:@Configuration @ImportRuntimeHints(ExposedHints::class) class NativeHintsConfigurationRegister the implementation in a
META-INF/spring.factoriesfile:org.springframework.aot.hint.RuntimeHintsRegistrar=com.example.ExposedHintsReplace
com.example.ExposedHintswith the fully qualified name of your implementation.