JPA - microfox-framework/MicroFox GitHub Wiki
JPA (Java Persistence API) is the standard Java specification for object-relational mapping (ORM), allowing developers to manage relational data using Java objects. It abstracts away the underlying SQL queries and provides a declarative way to persist Java objects into databases.
In this example, we use Hibernate as the JPA provider and configure it programmatically via MicroFoxJpa.
We use HikariCP as the connection pool and configure JPA with the following options:
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setDriverClassName(Driver.class.getCanonicalName());
hikariConfig.setJdbcUrl("jdbc:h2:mem:testdb;MODE=Oracle;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false");
hikariConfig.setUsername("sa");
hikariConfig.setPassword("sa");
HikariDataSource hikariDataSource = new HikariDataSource(hikariConfig);
JpaConfig databaseConfig = new JpaConfig.Builder()
.setPersistenceUnit("h2")
.setProvider(new HibernatePersistenceProvider())
.setHbm2ddl("update")
.setDialect(H2Dialect.class)
.setShowSql(true)
.setPackages(List.of("ir.moke.example.entity"))
.build();
- Persistence Unit: Logical name for this JPA configuration.
- Provider: We use HibernatePersistenceProvider.
- Hbm2ddl: The schema auto-generation strategy (e.g. update, create, validate).
- Dialect: SQL dialect for H2 in Oracle compatibility mode.
- Packages: Package(s) containing JPA entity classes.
Instead of using a full JPA implementation like Spring Data JPA, we define a custom lightweight repository interface using annotations:
public interface PersonRepository {
@Persist
void save(Person person);
@Query("select p from Person p")
List<Person> find();
@Find
Person find(long id);
@Merge
void update(Person person);
@Remove
void delete(Person person);
}
This interface uses custom annotations:
- @Persist: Persists a new entity.
- @Merge: Updates an existing entity.
- @Find: Looks up by primary key.
- @Remove: Deletes an entity.
- @Query: Runs a JPQL query with optional @QueryParams. Supports pagination via @Offset and @Size.
// 1. Save persons
jpaTx(PersonRepository.class, "h2", repo -> {
repo.save(new Person("Mahdi", "Sheikh Hosseini"));
});
// 2. Retrieve all
jpa(PersonRepository.class, "h2", repo -> {
repo.find().forEach(System.out::println);
});
// 3. Update a record
person.setName("Sina");
jpaTx(PersonRepository.class, "h2", repo -> repo.update(person));
// 4. Delete a record
jpaTx(PersonRepository.class, "h2", repo -> repo.delete(repo.find(1)));
- jpa() runs a read-only operation.
- jpaTx() runs a transactional (read/write) operation.
- Abstracted database access using object-oriented programming.
- Clean separation of persistence logic using repositories.
- Lightweight, flexible setup without the need for a full framework.
- Supports dynamic queries with parameters and pagination.