Guiced Persistence gives you JTA with multi-datasource connection, and distributed connection handling through BTM.
This project exposes a Module DatabaseModule that you can extend to configure and connect your databases as you desire

You can mix and match any of the imports for your project depending on your needs
<dependency>
    <groupId>com.guicedee.persistence</groupId>
    <artifactId>guiced-persistence</artifactId>
</dependency>
<dependency>
    <groupId>com.guicedee.persistence</groupId>
    <artifactId>guiced-persistence-btm</artifactId>
</dependency>
<dependency>
    <groupId>com.guicedee.persistence</groupId>
    <artifactId>guiced-persistence-jpa</artifactId>
</dependency>
<dependency>
    <groupId>com.guicedee.persistence</groupId>
    <artifactId>guiced-persistence-c3p0</artifactId>
</dependency>
<dependency>
    <groupId>com.guicedee.persistence</groupId>
    <artifactId>guiced-persistence-wildfly</artifactId>
</dependency>

You will need an annotation to identify the connection
@Qualifier
@Target({ METHOD,FIELD,PARAMTER })
@Retention(RetentionPolicy.RUNTIME)
@BindingAnnotation
public @interface MyDB {
}
Mark the requirement, and register your new module with the IGuiceModule service
module my.module {
    requires com.guicedee.guicedpersistence.btm;
    provides IGuiceModule with DBModule;
}
A database module is needed to configure the connection, with overridable properties to alter it in any way
public class DBModule extends DatabaseModule<DBModule>
{
    protected @NotNull String getPersistenceUnitName()
    {
        return "MyFirstPersistenceUnit";
    }
    protected @NotNull ConnectionBaseInfo getConnectionBaseInfo(PersistenceUnit unit, Properties filteredProperties)
    {
        return new BTMConnectionBaseInfo();
    }
    protected @NotNull String getJndiMapping()
    {
        return "jndi/jta/datasource";
    }
    protected @NotNull Class getBindingAnnotation()
    {
        return MyDb.class;
    }
}
Method Interception can specify which transaction to start on which database source. A Request Scoper is available to make each request into it's own unit of work for complete transaction control
@Transactional(entityManagerAnnotation = MyDb.class,timeout = 500)
public void me();
The request scoping addon can be added on by simply including the artifact, and adding it to your module-info file
<dependency>
    <groupId>com.guicedee.servlets</groupId>
    <artifactId>guiced-servlets-request-scoper</artifactId>
</dependency>

Currently you can use the following ConnectionBaseInfo types (or your own)

  • BTMConnectionBaseInfo (For JTA)
  • JPAConnectionBaseInfo (For JPA)
  • C3P0ConnectionBaseInfo (For Pooled JPA)
  • WildflyConnectionBaseInfo (For standalone files)

This module will bind (and log) the following bindings with the annotation as a key,
EntityManagerFactory.class
EntityManager.class
PersistService.class
UnitOfWork.class
PersistenceUnit.class
DataSource.class