JPA - microfox-framework/MicroFox GitHub Wiki

🧠 Overview:

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.

⚙️ Configuration

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.

🧩 Repository Interface

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.

▶️ Usage

// 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.

✅ Benefits

  • 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.
⚠️ **GitHub.com Fallback** ⚠️