mansart-jakarta-data implémente Jakarta Data 1.0 — annotations @Repository, query methods, pagination, JDQL — au-dessus de JDBC, sans ORM lourd, sans réflexion runtime. Tout repository utilisateur est matérialisé à la compilation par APT. TCK officiel : 73/73 PASS (M7, mai 2026).
Mission
-
Couvrir les besoins courants de persistance (CRUD, queries typées, pagination) sans imposer un
EntityManager. -
Zéro réflexion à l’usage — métamodèle statique +
MethodHandlecachés. -
Dialectes JDBC pluggables (H2, PostgreSQL livrés ; MariaDB / SQL Server au backlog).
-
Compatible AOT (GraalVM native-image, Leyden CDS).
Modules
| Sous-module | Rôle |
|---|---|
|
Annotations |
|
Runtime : |
|
APT — métamodèle statique ( |
|
Plugin Maven — génère à la compilation les |
|
SPI : |
|
Dialecte H2 (référence tests + embarqué). |
|
Dialecte PostgreSQL (cible production). |
|
Bootstrap CDI 4.1 — BCE qui lit |
|
Tests unitaires H2 in-memory. |
|
Runner TCK Jakarta Data 1.0 — hors reactor (POM Model 4.0.0 standalone). |
Quickstart
Voir Démarrage rapide. Résumé :
@Entity
public class Author {
@Id @GeneratedValue Long id;
String name;
}
@Repository
public interface AuthorRepository extends BasicRepository<Author, Long> {
List<Author> findByName(String name);
@Query("FROM Author WHERE name LIKE :pattern")
List<Author> search(String pattern);
}
// APT génère AuthorRepositoryImpl + _Author + META-INF/mansart-repositories.list
Périmètre fonctionnel (livré)
-
BasicRepository,CrudRepository,DataRepository. -
Méthodes héritées :
save,delete,findById,findAll,count,existsById. -
Lifecycle :
@Insert,@Update,@Delete,@Save. -
@Find(binding par nom de paramètre). -
Derived queries :
findBy,existsBy,countBy,deleteBy+And,Or,Like,Between,LessThan,GreaterThan,LessThanEqual,GreaterThanEqual,IgnoreCase,OrderBy<Asc|Desc>. -
@QueryJDQL (SELECT/UPDATE/DELETE). -
Pagination offset (
PageRequest.ofPage(n).size(s)) et keyset (PageRequest.afterKey(…)). -
Sort,Order,Limit. -
Mapping erreurs SQLState → exceptions Jakarta Data (
OptimisticLockingFailureException,EntityExistsException, etc.).
Hors scope v1
-
Subqueries explicites en JDQL.
-
Joins explicites multi-niveaux.
-
Agrégations multi-attributs.
-
@OneToMany,@ManyToMany,@MappedSuperclass,@Inheritance. -
@Convert/AttributeConverter. -
NoSQL (Jakarta Data NoSQL est une extension hors scope Mansart v1).
Reportés à mansart-persistence (M7) ou v1.1.
Architecture runtime
-
Plans de requête préparés à
<clinit>(constants statiques). -
MethodHandlecachés une seule fois viaMethodHandles.privateLookupIn(…). -
Connexion : empruntée au
DataSourceinjecté ; libérée à la fin de la méthode (sauf si TX active → connexion de la TX).
Voir Fonctionnement interne pour le détail du codegen et du mapping.
Repositories de jars externes (génération AOT, plugin Maven)
Par défaut, seuls les @Repository présents dans les sources de l’application sont matérialisés
par l’APT. Une interface @Repository fournie par une dépendance déjà compilée (une bibliothèque
qui n’a pas exécuté l’APT) n’a donc pas d’implémentation : à l’exécution, le BCE retombe alors sur un
chemin réflexif (proxy généré au démarrage via la Class-File API).
mansart-data-maven-plugin supprime ce repli pour les builds applicatifs. Au goal
generate-external-repositories (phase generate-sources), il :
-
scanne le classpath de compilation (Class-File API du JDK) à la recherche des interfaces
@Repositorysans implémentation (déduplication via les indexmansart-repositories*.listdéjà présents) ; -
réutilise les mêmes émetteurs que l’APT via une tâche
javacsans source — aucun codegen dupliqué ; -
génère les
*RepositoryImpl(et les métamodèles_Entitymanquants) dans un package possédé par l’application, en référençant les types externes par nom pleinement qualifié → pas de split-package JPMS avec le jar d’origine ; -
écrit l’index
META-INF/mansart-repositories-external.list, lu par le BCE demansart-data-cdiau même titre que l’index APT.
Résultat : les beans des repositories fournis par des bibliothèques sont câblés statiquement (zéro réflexion), exactement comme ceux définis dans l’application. Le chemin réflexif reste le filet de sécurité pour les archives qu’on ne build pas (suites TCK, jars opaques).
<plugin>
<groupId>io.vidocq.mansart</groupId>
<artifactId>mansart-data-maven-plugin</artifactId>
<version>${mansart.version}</version>
<executions>
<execution>
<goals><goal>generate-external-repositories</goal></goals>
</execution>
</executions>
<!-- Optionnel : package cible des classes générées (défaut : dérivé des coordonnées du projet). -->
<configuration>
<targetPackage>com.acme.app.mansart.generated</targetPackage>
</configuration>
</plugin>
|
Le métamodèle généré lit les champs privés de l’entité via |
Dialectes
| Dialecte | Statut | Notes clés |
|---|---|---|
H2 |
✅ Livré |
|
PostgreSQL |
⏳ M4 |
|
MariaDB |
❌ Backlog |
— |
SQL Server |
❌ Backlog |
— |
Différences clés isolées dans le dialecte : pagination, upsert, retour d’identifiant, types natifs (UUID, JSONB, BOOLEAN), schéma snake_case.
JPMS
module io.vidocq.mansart.data {
requires jakarta.data;
requires jakarta.persistence;
requires java.sql;
exports io.vidocq.mansart.data;
exports io.vidocq.mansart.data.runtime;
exports io.vidocq.mansart.data.dialect.spi;
uses io.vidocq.mansart.data.dialect.spi.DialectFactory;
}
Bench
Premier smoke : voir lien:https://codeberg.org/Vidocq/mansart/src/branch/main/mansart-jakarta-data/BENCH.md[mansart-jakarta-data BENCH.md] (BENCH-20260504-01 : findById H2 in-memory).
Bugs
Voir lien:https://codeberg.org/Vidocq/mansart/src/branch/main/mansart-jakarta-data/BUG.md[BUG.md]. Bug majeur historique : BUG-20260505-01 (entités TCK non métamodélisées) — résolu via le runtime repo creator de M7.
Roadmap
-
✅ M2 — Squelette + APT métamodèle.
-
✅ M3a — H2 dialect + BasicRepository CRUD.
-
⏳ M3b — Pagination keyset, lifecycle, derived queries (compléments).
-
⏳ M4 — Dialecte PostgreSQL.
-
⏳ M5 —
@QueryJDQL (compléments — base livrée en M7-27). -
✅ M6 — TCK Jakarta Data 1.0.
-
✅ M7 — Runtime impl generation — TCK 73/73 PASS.
Voir lien:https://codeberg.org/Vidocq/mansart/src/branch/main/mansart-jakarta-data/PLAN.md[PLAN.md] pour le détail des sous-jalons (M7-26 à M7-29).