3

I am working on migrating a app to use the lastest version of quarkus. The app implements multi-tenant using the database strategy from the hibernate interfaces. Quarkus recommends ( if possible ) avoiding the use of persistence.xml, what is the correct approach for this case of multi-tenant given the quarkus context ? keep the persistence.xml or use only the application.properties recommended by quarkus ?

@Singleton
public class HibernateConnectionProviderFactory implements ConnectionProviderFactory {
    private Logger logger = Logger.getLogger(getClass().getName());

    private static final String TENANT_ID_PLACEHOLDER = "{tenant.id}";

    @Inject
    @SystemProperty("multitenant.hibernate.connection.url")
    private Optional<String> dbUrl;

    @Inject
    @SystemProperty("multitenant.hibernate.connection.driver_class")
    private Optional<String> dbDriverClass;

    @Inject
    @SystemProperty("multitenant.hibernate.dialect")
    private Optional<String> dbDialect;

    @Inject
    @SystemProperty("multitenant.hibernate.connection.username")
    private Optional<String> dbUsername;

    @Inject
    @SystemProperty("multitenant.hibernate.connection.password")
    private Optional<String> dbPassword;

    @Inject
    @SystemProperty(value = "multitenant.hibernate.schema.generation", defaultValue = "false")
    private boolean generateSchema;

    @Inject
    @SystemProperty("multitenant.default.tenant.id")
    private Optional<String> defaultTenantId;

    @Inject
    private PersistenceUnitDescriptorFactory persistenceUnitDescriptorFactory;

    @Inject
    private SchemaGenerator schemaGenerator;

    private final ConcurrentHashMap<String, ConnectionProvider> providers = new ConcurrentHashMap<>();


    @Override
    public Optional<ConnectionProvider> getDefaultConnectionProvider() {
        return defaultTenantId.map(this::getConnectionProvider);
    }

    @Override
    public ConnectionProvider getConnectionProvider(String tenantId) {
        return providers.computeIfAbsent(tenantId, this::createDriverManagerConnectionProvider);
    }


    private ConnectionProvider createDriverManagerConnectionProvider(String tenantId) {
        final PersistenceUnitDescriptor persistenceUnit = persistenceUnitDescriptorFactory.getPersistenceUnitDescriptor(tenantId);
        final Map<Object, Object> persistenceProperties = getPersistenceProperties(tenantId, persistenceUnit.getProperties());
        final StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(persistenceProperties).build();

        if (generateSchema) {
            schemaGenerator.updateSchema(serviceRegistry, persistenceUnit);
        }

        final ConnectionProvider connectionProvider = serviceRegistry.getService(ConnectionProvider.class);


        return connectionProvider;
}
//...
}
Victor
  • 53
  • 3

1 Answers1

2

Right now we don't support setting up Hibernate ORM multitenancy with the Quarkus application.properties so you should go the persistence.xml way.

That being said, we might consider supporting it in the future if there is enough traction for it. Could you open an issue on GitHub so that we can collect feedback on this feature?

Thanks!

Guillaume Smet
  • 9,921
  • 22
  • 29
  • Issue open in the [quarkus github](https://github.com/quarkusio/quarkus/issues/3651) – Victor Aug 27 '19 at 00:15
  • @Guillame Smet is there any progress on this feature since? Cause I need it badly to migrate to quarkus. Also I posted similar question https://stackoverflow.com/questions/61561056/multiple-datasource-with-micronautor-or-quarkus if you can please comment there – Bohdan Myslyvchuk May 03 '20 at 17:50
  • Multi-tenant is in development on quarkus: https://github.com/quarkusio/quarkus/issues/5681 – victorfts May 05 '20 at 15:12