feat: introduce WebSocket support with new endpoints and transaction propagation enhancements

This commit is contained in:
Relism
2026-05-11 16:14:26 +02:00
parent a4a16bdb00
commit ccc5550598
55 changed files with 2705 additions and 752 deletions
@@ -0,0 +1,92 @@
# flash-ext-data-hibernate
Backend Hibernate per `flash-ext-data-core`.
## Scopo
Questo modulo implementa `TxManager` sopra `SessionFactory` e fornisce una base repository Hibernate-centric.
## Come si usa
### 1. Creare il manager
```java
SessionFactory sessionFactory = ...;
HibernateTxManager txManager = new HibernateTxManager(sessionFactory);
DataExtension extension = new DataExtension(txManager);
```
### 2. Installare lestensione in Flash
Lestensione registra `Tx` e `TxManager` nel `FlashContext`.
Le handler class-based annotate con `@Transactional` vengono wrappate automaticamente.
### 3. Definire una repository
```java
public final class UserRepository extends HibernateRepository<User, Long> {
public UserRepository(Tx tx) {
super(tx, User.class);
}
}
```
Con il nuovo modello query/spec puoi esporre campi riusabili come costanti:
```java
public final class UserRepository extends HibernateRepository<User, Long> {
public static final SpecBuilder.FieldSpec<User, String> EMAIL = SpecBuilder.field("u.email");
public static final SpecBuilder.FieldSpec<User, Boolean> ACTIVE = SpecBuilder.field("u.active");
public UserRepository(Tx tx) {
super(tx, User.class);
}
public Optional<User> findByEmail(String email) {
return findOne(EMAIL.eq(email));
}
}
```
Le query domain-specific possono usare gli helper della base class:
```java
public List<User> findByEmailDomain(String domain) {
return findMany("from User u where u.email like :email", q ->
q.setParameter("email", "%@" + domain)
);
}
```
## Come funziona sotto
- La tx corrente è rappresentata da `HibernateTxStatus`.
- La risorsa esposta al core è una `Session`.
- `Tx.resource(Session.class)` recupera la `Session` dal contesto corrente.
- `REQUIRES_NEW` sospende lo status attivo e apre una nuova `Session`.
- `NOT_SUPPORTED` sospende la tx attiva e continua senza sessione bindata.
## Repository base
`HibernateRepository` fornisce:
- `findById`, `findAll`, `findPage`, `findOne`
- `save`, `update`, `delete`, `saveAll`
- bulk `deleteAll(Spec<T>)` e `updateAll(Spec<T>, T)`
- helper HQL: `hql(...)`, `hqlMutate(...)`
Le classi concrete devono solo implementare query di dominio, non il plumbing transazionale.
## Semantica transazionale
- `REQUIRED`: join o apertura nuova tx.
- `REQUIRES_NEW`: sospensione del contesto corrente.
- `SUPPORTS`: join se c’è tx, altrimenti no-op.
- `NOT_SUPPORTED`: sospende e prosegue senza tx.
- `MANDATORY`: fallisce se non c’è tx.
## Note
- `Session` viene chiusa a fine tx nuova.
- Le synchronizations vengono eseguite al commit/rollback.
- Il backend è pensato per essere usato tramite la base class, non direttamente.