Recettes courantes pour mansart-jakarta-data, mansart-transactions et mansart-pool. La référence exhaustive (toutes annotations, toutes options de config) est dans Référence.
Repositories Jakarta Data
BasicRepository<T, K> et CrudRepository<T, K>
BasicRepository couvre save, delete, findById, findAll. CrudRepository ajoute des variantes batch typées. Pour aller plus loin, on déclare des méthodes spécialisées sur l’interface ; l’APT les transforme en plans de requête statiques.
@Repository
public interface AuthorRepository extends CrudRepository<Author, Long> {
long count();
boolean existsById(Long id);
}
Derived queries (par nom de méthode)
Mansart parse le nom et produit un AST neutre, puis du SQL via le dialecte cible. Mots-clés supportés : findBy, existsBy, countBy, deleteBy, opérateurs And, Or, Like, Between, LessThan, GreaterThan, LessThanEqual, GreaterThanEqual, IgnoreCase, OrderBy<Asc|Desc>.
List<Author> findByName(String name);
Optional<Author> findOneByName(String name);
List<Author> findByNameLike(String pattern);
List<Author> findByNameIgnoreCase(String name);
List<Author> findAllByOrderByNameAsc();
long deleteByName(String name);
@Find (matching par paramètres typés)
@Find
List<Book> findByAuthorAndPublishedOnBetween(Author author,
LocalDate from,
LocalDate to);
Le nom du paramètre Java doit correspondre à l’attribut entité (compiler avec -parameters).
@Query JDQL
JDQL est le dialecte de requête défini par Jakarta Data 1.0. Plus simple que JPQL, suffisant pour le SELECT/UPDATE/DELETE typés.
@Query("FROM Author WHERE name LIKE :pattern AND id > :minId")
List<Author> search(String pattern, Long minId);
@Query("UPDATE Author SET name = :newName WHERE name = :oldName")
long rename(String oldName, String newName);
Pagination — offset et keyset
Page<Author> findByNameLikeOrderByNameAsc(String pattern, PageRequest page);
// Appel
var page = authors.findByNameLikeOrderByNameAsc("S%", PageRequest.ofPage(1).size(20));
Les curseurs keyset (PageRequest.afterKey(…)) évitent le drift en pagination longue.
Lifecycle annotations
@Insert, @Update, @Delete, @Save typés : paramètre = entité, collection ou varargs ; retour void/T/Iterable<T>/int/long/boolean. Voir Référence.
Transactions
@Transactional (CDI)
L’intercepteur de mansart-transactions matérialise @jakarta.transaction.Transactional (TxType REQUIRED, REQUIRES_NEW, MANDATORY, SUPPORTS, NEVER, NOT_SUPPORTED).
@ApplicationScoped
public class AuthorService {
@Inject AuthorRepository authors;
@Transactional
public Author register(String name) {
return authors.save(new Author(name));
}
@Transactional(Transactional.TxType.REQUIRES_NEW)
public void audit(String message) { /* ... */ }
}
Pool de connexions
Configuration minimale
var ds = MansartDataSource.create(PoolConfig.builder()
.jdbcUrl("jdbc:postgresql://db.local:5432/shop")
.username("shop").password("...")
.minSize(4).maxSize(32)
.acquireTimeout(Duration.ofSeconds(5))
.idleTimeout(Duration.ofMinutes(10))
.maxLifetime(Duration.ofMinutes(30))
.validationMode(ValidationMode.IS_VALID)
.build());
Sizing
Avec virtual threads, le sizing classique « threads = connections » disparaît : on dimensionne sur la concurrence DB réelle, pas sur la concurrence applicative. Règle de pouce : maxSize ≈ vCPUs DB × 2..4. Au-delà, le DB devient le goulot — voir lien:https://codeberg.org/Vidocq/mansart/src/branch/main/mansart-pool/BENCH.md[mansart-pool BENCH.md].
Composition avec les autres modules
-
Vauban CDI — produit les beans
@Repository, gère l’intercepteur@Transactional. -
Cassini REST — endpoints REST appelant les services transactionnels.
-
Vidocq Runtime — orchestrateur qui assemble pool + tx + data + REST dans un fat-jar AOT-friendly.