Mansart targets the standard (Jakarta Data 1.0 + Jakarta Persistence 3.2), not proprietary extensions. Migrating from Spring Data is trivial — the Jakarta Data spec explicitly took Spring Data conventions on board. Hibernate / EclipseLink takes more effort if the application uses out-of-spec features (custom dialects, listeners, events).

From Spring Data JPA

Spring Data Mansart Jakarta Data Note

org.springframework.data.repository.CrudRepository

jakarta.data.repository.CrudRepository

Standardized API — very close signatures.

@org.springframework.stereotype.Repository

@jakarta.data.repository.Repository

Different semantics: Jakarta Data scope = bean repository, not exception translator.

Derived methods (findByXxx)

Identical

Convention adopted by Jakarta Data.

@Query("SELECT b FROM Book b WHERE …​")

@Query("FROM Book WHERE …​") (JDQL)

JDQL is simpler than JPQL — the leading SELECT is implicit.

Pageable / Page<T>

PageRequest / Page<T>

Identical semantics. PageRequest.afterKey(…​) for keyset.

@Transactional (Spring)

@jakarta.transaction.Transactional

Six standard TxType values. No propagation = NESTED (savepoints) in v1.

JpaRepository<T, ID>

BasicRepository<T, K> or CrudRepository<T, K>

No findAll(Sort) — use @OrderBy or a findAllByOrderByXxxAsc.

Migrating from Spring Data is the shortest path. Derived method names and @Query JDQL transpose line-by-line in most cases.

From Hibernate ORM 6/7

Hibernate Mansart Note

SessionFactory / EntityManagerFactory

MansartManagerFactory (M7 pending)

For everyday needs, switch to mansart-jakarta-data directly.

HQL

JPQL (M7) or JDQL (delivered)

Mansart targets the spec, not proprietary HQL extensions.

@Entity, @Id, @GeneratedValue, @Column

Identical

Standard JPA annotations recognized as-is.

@OneToMany, @ManyToMany, inheritance

Out of scope v1

Deferred to mansart-persistence (M7).

Hibernate Reactive

mansart-jakarta-data + virtual threads

Blocking JDBC under Loom — no Vert.x, no callback.

JPA listeners (@PrePersist, @PostLoad)

Out of scope v1

Covered by M7.

Criteria API

Out of scope v1

Covered by M7.

Schema generation (hibernate.hbm2ddl)

External (Flyway / Liquibase recommended)

Mansart does not handle DDL migrations.

Less common case; transposition similar to Hibernate. Standard JPA 3.2 annotations are recognized as-is; proprietary extensions (@CustomConverter, @Cache(…​)) must be rewritten as standard equivalents or deferred to mansart-persistence (M7).

From HikariCP (pool)

HikariCP mansart-pool Note

HikariDataSource

MansartDataSource

Implements standard javax.sql.DataSource.

HikariConfig

PoolConfig builder

Similar API — jdbcUrl, username, password, maximumPoolSizemaxSize.

minimumIdle

minSize

Same.

connectionTimeout

acquireTimeout

Same.

idleTimeout

idleTimeout

Same.

maxLifetime

maxLifetime

Same.

leakDetectionThreshold

leakDetectionThreshold

Same.

connectionTestQuery

validationQuery + validationMode=QUERY

Mansart prefers Connection.isValid() (validationMode=IS_VALID) — JDBC standard, no custom SQL.

Micrometer / Prometheus metrics

PoolMetrics (snapshot)

Micrometer bridge on the mansart-pool backlog.

Performance comparison: see lien:https://codeberg.org/Vidocq/mansart/src/branch/main/mansart-pool/BENCH.md[mansart-pool BENCH.md]. mansart-pool is virtual-thread-native and avoids the pinning cost under Loom load.

Known pitfalls

  • No entity proxy — Mansart materializes entities directly. Lazy loading is not magical: @ManyToOne(fetch=LAZY) loads the attribute on next access through a getter intercepted by APT-generated bytecode (M5).

  • No implicit auto-flush — the user calls flush() explicitly or ends the transaction. Different from Hibernate which flushes on query.

  • No runtime entity scan — the APT registers entities at compile time. Adding an @Entity without recompiling is a classic mistake when migrating from Hibernate.

  • No @OneToMany in v1 — model explicitly via the owning @ManyToOne and a findByOwner(…​) in the target’s repository.

No migration needed

Vidocq Runtime ships vidocq-runtime-mansart-h2-example which shows a clean end-to-end integration. For a new project, starting from this example is often simpler than migrating a legacy.