Nicola Beghin
Nicola Beghin

Reputation: 494

Quarkus - programmatically retrieve named JTA datasource

Hi everyone I'm migrating from Wildfly to Quarkus, but unable to understand how to programmatically retrieve a named datasource. Below the code used until now in Wildfly to retrieve datasourceName programmatically (datasource datasourceName already defined in application.properties along with many others)

Properties p = new Properties();
p.put(AvailableSettings.DATASOURCE, datasourceName);
p.put(AvailableSettings.JTA_PLATFORM, JBossAppServerJtaPlatform.class.getName());
p.put("current_session_context_class", "jta");
p.put(AvailableSettings.SHOW_SQL, false);
p.put(AvailableSettings.FORMAT_SQL, false);
// Adding "hibernate.classLoaders" property is critical for this to work with keycloak!!!
p.put(AvailableSettings.CLASSLOADERS, Collections.singletonList(getClass().getClassLoader()));
entityManagerFactory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME, p);

conf/quarkus.properties

quarkus.datasource.user-store.db-kind=mysql

quarkus.datasource.DATASOURCEA.db-kind=mysql
quarkus.datasource.DATASOURCEA.username=USER
quarkus.datasource.DATASOURCEA.password=PASSWORD
quarkus.datasource.DATASOURCEA.jdbc.url=jdbc:mysql://HOSTNAME/DATABASE

When running such code in Quarkus, exception is thrown

The FastbootHibernateProvider PersistenceProvider can not support runtime provided properties. Make sure you set all properties you need in the configuration resources before building the application.

given by this FastBootHibernatePersistenceProvider.java line

@SuppressWarnings("rawtypes")
private void verifyProperties(Map properties) {
    if (properties != null && properties.size() != 0) {
        throw new PersistenceException(
                "The FastbootHibernateProvider PersistenceProvider can not support runtime provided properties. "
                        + "Make sure you set all properties you need in the configuration resources before building the application.");
    }
}

Meaning, no property is allowed.

Tried with

Arc.container().instance(EntityManagerFactory.class, new PersistenceUnit.PersistenceUnitLiteral(datasourceName))

but throwing

WARN  [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator] (JPA Startup Thread: user-storage-jpa) HHH000342: Could not obtain connection to query metadata: java.lang.UnsupportedOperationException: The application must supply JDBC connections
at org.hibernate.engine.jdbc.connections.internal.UserSuppliedConnectionProviderImpl.getConnection(UserSuppliedConnectionProviderImpl.java:44)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:181)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:68)

Any hint on this? Really struggling to find any useful reference to accomplish this. Can find only injection-based datasources.

thanks a lot, nicola

Upvotes: 1

Views: 1095

Answers (1)

Thomas Lann
Thomas Lann

Reputation: 1234

Have you seen the following? It is based on an example from one of the Keycloak Developers

MyUserStorageProvider(KeycloakSession session, ComponentModel model) {
    this.session = session;
    this.model = model;
    em = session.getProvider(JpaConnectionProvider.class, "user-store").getEntityManager();
}

https://github.com/pedroigor/keycloak-quickstarts/blob/issue-10579/user-storage-jpa/src/main/java/org/keycloak/quickstart/storage/user/MyUserStorageProvider.java#L73

Upvotes: 1

Related Questions