When building data-driven applications, Micronaut Data allows you to choose between:
- JPA (Java Persistence API)
- JDBC (Direct SQL Mapping)
Both approaches are fully supported by Micronaut Data, but they serve different use cases.
In this post, weβll explore both options, their differences, pros/cons, and how to configure them.

π What is JPA?
JPA (Java Persistence API) is the standard API for object-relational mapping (ORM) in Java.
It allows you to map Java objects (entities) to database tables and automatically handles SQL generation.
- β Familiar if you’ve used Hibernate, Spring Data, Jakarta EE.
- β Full ORM β relationships, lazy loading, cascading, etc.
- β More abstraction, less SQL.
Micronaut supports JPA through its micronaut-data-jpa module.
π What is JDBC in Micronaut Data?
JDBC (Java Database Connectivity) uses Micronaut’s micronaut-data-jdbc module for more direct mapping.
- β Simple SQL mapping without full ORM.
- β Fast compile-time query generation.
- β Minimal runtime overhead.
- β Excellent for microservices where complex ORM features arenβt needed.
Micronaut Data JDBC focuses on compile-time SQL generation β no heavy runtime proxies like Hibernate.
β JPA vs JDBC: Quick Comparison
Feature | JPA | JDBC |
---|---|---|
Performance | Slower (runtime parsing) | Faster (compile-time SQL) |
Complexity | Higher (lazy loading, proxies) | Lower |
Learning Curve | Steeper | Easier |
Relationships | Full ORM | Limited (manual handling) |
Use case | Complex domains | Microservices, high-performance apps |
π§ Configuring JPA in Micronaut
Add Maven Dependencies
1 2 3 4 5 6 7 8 9 10 11 12 |
<dependency> <groupId>io.micronaut.data</groupId> <artifactId>micronaut-data-hibernate-jpa</artifactId> </dependency> <dependency> <groupId>org.hibernate.orm</groupId> <artifactId>hibernate-core</artifactId> </dependency> |
β Micronaut Data uses Hibernate under the hood when JPA is selected.
Sample JPA Entity
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
package com.kscodes.micronaut.school.entities; import jakarta.persistence.*; import java.time.LocalDate; @Entity @Table(name = "students") public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false) private String name; private LocalDate dateOfBirth; private String email; // Getters and Setters } |
β
Uses standard JPA annotations from jakarta.persistence
.
Repository Interface (same as before!)
1 2 3 4 5 6 7 8 9 10 11 |
package com.kscodes.micronaut.school.repositories; import com.kscodes.micronaut.school.entities.Student; import io.micronaut.data.annotation.Repository; import io.micronaut.data.repository.CrudRepository; @Repository public interface StudentRepository extends CrudRepository<Student, Long> { } |
π‘ Even with JPA, Micronaut generates repository code at compile-time.
Enable JPA in application.yml
1 2 3 4 5 6 7 8 9 |
jpa: default: properties: hibernate: hbm2ddl: auto: update |
β
For production, you should disable hbm2ddl.auto
and use migrations like Flyway or Liquibase.
π§ Configuring JDBC in Micronaut
Add Maven Dependencies
1 2 3 4 5 6 7 |
<dependency> <groupId>io.micronaut.data</groupId> <artifactId>micronaut-data-jdbc</artifactId> </dependency> |
β No Hibernate required!
Sample JDBC Entity
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
package com.kscodes.micronaut.school.entities; import io.micronaut.data.annotation.*; import java.time.LocalDate; @MappedEntity("students") public class Student { @Id @GeneratedValue(GeneratedValue.Type.IDENTITY) private Long id; @Column(nullable = false) private String name; private LocalDate dateOfBirth; private String email; // Getters and Setters } |
β
Uses @MappedEntity
instead of @Entity
.
β
Mapping is much lighter.
Repository Interface (same!)
β Whether you use JPA or JDBC β repository code remains very similar.
Configure Datasource for JDBC (same as before)
1 2 3 4 5 6 7 8 9 |
datasources: default: url: jdbc:h2:mem:devDb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE username: sa driverClassName: org.h2.Driver dialect: H2 |
π§ͺ Which one should you choose?
If you need… | Use |
---|---|
Full ORM, relationships, cascading | JPA |
Simpler, faster, lightweight mapping | JDBC |
Large monolith enterprise systems | JPA |
Modern microservices & cloud apps | JDBC |
π Common Errors
Error | Cause | Solution |
---|---|---|
Hibernate exceptions | Missing Hibernate dependency | Add micronaut-data-hibernate-jpa |
Table not found | Auto-DLL disabled | Use Flyway/Liquibase or enable auto |
Field mapping issues | Incorrect annotations | Use correct annotations for JPA vs JDBC |
π External References
β Summary
- β Micronaut supports both JPA and JDBC.
- β JDBC is lighter and faster.
- β JPA is full ORM and more powerful for complex domains.
- β Choose based on your projectβs size and complexity.