Skip to content

Avaje Inject

Use this integration when Avaje Inject owns dependency injection and Kaumei jdbc-tx owns transaction boundaries. Avaje Inject generates the service proxy at compile time. For the framework-independent setup, see the Transactions guide. The normative annotation and integration rules are defined by Declarative Transactions.

Import @KaumeiTx as an aspect and delegate each transaction type to the corresponding KaumeiTxManager operation:

KaumeiTxAspect.java
@Override
public MethodInterceptor interceptor(Method method, @Nullable KaumeiTx annotation) {
requireNonNull(method, "method");
KaumeiTx resolved = annotation != null
? annotation
: method.getDeclaringClass().getAnnotation(KaumeiTx.class);
requireNonNull(resolved, "No @KaumeiTx found for " + method);
KaumeiTxDefinition definition = KaumeiTxDefinition.from(resolved);
return invocation -> execute(resolved.value(), definition, invocation);
}
private void execute(KaumeiTx.Type type, KaumeiTxDefinition definition, Invocation invocation) throws Exception {
switch (type) {
case REQUIRED -> txManager.requiredOpt(definition, context -> invoke(invocation));
case REQUIRES_NEW ->
txManager.requiresNewOpt(definition, context -> invoke(invocation));
case MANDATORY -> txManager.mandatoryOpt(definition, context -> invoke(invocation));
case SUPPORTS -> txManager.supportsOpt(definition, context -> invoke(invocation));
case NOT_SUPPORTED ->
txManager.notSupportedOpt(definition, context -> invoke(invocation));
case NEVER -> txManager.neverOpt(definition, context -> invoke(invocation));
}
}

Register the H2 data source, connection provider, transaction manager, and generated repository as Avaje Inject beans:

ApplicationFactory.java
@Factory
public final class ApplicationFactory {
@Bean
JDBCDataSource dataSource() {
var dataSource = new JDBCDataSource();
dataSource.setURL(Config.get("database.url"));
dataSource.setUser(Config.get("database.username"));
dataSource.setPassword(Config.get("database.password"));
return dataSource;
}
@Bean
JdbcConnectionProvider connectionProvider(JDBCDataSource dataSource) {
return dataSource::getConnection;
}
@Bean
KaumeiTxManager txManager(JdbcConnectionProvider connectionProvider) {
return KaumeiTxManager.getInstance(connectionProvider);
}
@Bean
TradeRepository tradeRepository(KaumeiTxManager txManager) {
return new TradeRepository$Jdbc(txManager);
}
}

TradeService is an Avaje Inject @Singleton using constructor injection. Its @KaumeiTx(REQUIRED) method updates the customer’s total and inserts the trade in one transaction. The duplicate-UTI test verifies that both statements are rolled back together.

A bare @KaumeiTx defaults to MANDATORY. Methods that start a transaction therefore select REQUIRED or REQUIRES_NEW explicitly.