What I'm trying to do
I'm creating a Vaadin application with Quarkus, and while trying to connect multiple datasources, an error was thrown :
2023-08-06 13:24:47,765 ERROR [io.qua.dep.dev.IsolatedDevModeMain] (main) Failed to start quarkus: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: jakarta.enterprise.inject.spi.DeploymentException: Found 3 deployment problems:
[1] Unsatisfied dependency for type jakarta.persistence.EntityManagerFactory and qualifiers [@Default]
- java member: io.quarkus.security.jpa.runtime.JpaTrustedIdentityProvider#entityManagerFactory
- declared on CLASS bean [types=[io.quarkus.security.jpa.runtime.JpaTrustedIdentityProvider, io.quarkus.security.identity.IdentityProvider<io.quarkus.security.identity.request.TrustedAuthenticationRequest>, com.database.model.crm.CrmUser__JpaTrustedIdentityProviderImpl, java.lang.Object], qualifiers=[@Default, @Any], target=com.database.model.crm.CrmUser__JpaTrustedIdentityProviderImpl]
The following beans match by type, but none have matching qualifiers:
- Bean [class=org.hibernate.SessionFactory, qualifiers=[@Any, @io.quarkus.hibernate.orm.PersistenceUnit("default"), @Named("default")]]
- Bean [class=org.hibernate.SessionFactory, qualifiers=[@Any, @Named("reservation"), @io.quarkus.hibernate.orm.PersistenceUnit("reservation")]]
[2] Unsatisfied dependency for type jakarta.persistence.EntityManagerFactory and qualifiers [@Default]
- java member: io.quarkus.security.jpa.runtime.JpaIdentityProvider#entityManagerFactory
- declared on CLASS bean [types=[io.quarkus.security.jpa.runtime.JpaIdentityProvider, io.quarkus.security.identity.IdentityProvider<io.quarkus.security.identity.request.UsernamePasswordAuthenticationRequest>, java.lang.Object, com.database.model.crm.CrmUser__JpaIdentityProviderImpl], qualifiers=[@Default, @Any], target=com.database.model.crm.CrmUser__JpaIdentityProviderImpl]
The following beans match by type, but none have matching qualifiers:
- Bean [class=org.hibernate.SessionFactory, qualifiers=[@Any, @io.quarkus.hibernate.orm.PersistenceUnit("default"), @Named("default")]]
- Bean [class=org.hibernate.SessionFactory, qualifiers=[@Any, @Named("reservation"), @io.quarkus.hibernate.orm.PersistenceUnit("reservation")]]
[3] Unsatisfied dependency for type io.quarkus.security.identity.AuthenticationRequestContext and qualifiers [@Default]
- java member: com.ui.configuration.UserAugmentor#augment():context
- declared on PRODUCER METHOD bean [types=[java.lang.Object, io.smallrye.mutiny.Uni<io.quarkus.security.identity.SecurityIdentity>], qualifiers=[@Any, @PersistenceUnitExtension], target=io.smallrye.mutiny.Uni<io.quarkus.security.identity.SecurityIdentity> augment(io.quarkus.security.identity.SecurityIdentity identity, io.quarkus.security.identity.AuthenticationRequestContext context), declaringBean=com.ui.configuration.UserAugmentor]
My datasources configuration look like this :
quarkus.datasource.default... # Default datasource config
quarkus.datasource.reservation... # Reservation datasource config
quarkus.hibernate-orm.default.datasource=default # Orm Default mapping
quarkus.hibernate-orm.reservation.datasource=reservation # Orm reservation mapping
And my entities are correctly associated to according datasource with package-info.java
:
@PersistenceUnit("default")
package com.database.model.crm;
import io.quarkus.hibernate.orm.PersistenceUnit;
and
@PersistenceUnit("reservation")
package com.database.model.reservation;
import io.quarkus.hibernate.orm.PersistenceUnit;
I already tried a few things :
First i tried adding relevant annotation @PersistenceUnitExtension
to my UserAugmentor
responsible of security identity providing inside my app :
@PersistenceUnitExtension
@RequestScoped
public class UserAugmentor implements SecurityIdentityAugmentor {
...
}
Then, as I was using Active Record Pattern, I tried switching to Repository Pattern to add @PersistenceUnitExtension
on the injected repository :
@Inject
@PersistenceUnitExtension
CrmUserRepository crmUserRepository;
None of this worked unfortunately. I have read every documentation available and at this point I have no idea what's could be the solution.
Could someone point me in the right direction please ? Did I forgot something ?
Thank you for reading.
Edit 1
After playing around I think i found the origin of the problem here in JpaIdentityProvider
where EntityManagerFactory
is injected.
public abstract class JpaIdentityProvider implements IdentityProvider<UsernamePasswordAuthenticationRequest> {
private static Logger log = Logger.getLogger(JpaIdentityProvider.class);
@Inject
EntityManagerFactory entityManagerFactory; // I think this one is the origin
public JpaIdentityProvider() {}
...
Do you think this may be a bug ?
Edit 2
Previous error is gone, but suggested configuration is not working yet. I simply cannot annotate package-info.java
with @PersistenceUnit
with no value.
It gives me 'value' missing though required
. I also tried using @PersistenceUnit("<default>")
as its the default value specified in annotation.
This gave me the following error :
Model classes are defined for the default persistence unit <default> but configured datasource <default> not found: the default EntityManagerFactory will not be created. To solve this, configure the default datasource. Refer to https://quarkus.io/guides/datasource for guidance.
Even with proper configuration of default datasource :
quarkus.datasource... # Default datasource config
quarkus.datasource.reservation... # Reservation datasource config
quarkus.hibernate-orm.reservation.datasource=reservation # Orm reservation mapping
Edit 3
The following error was due to bad configuration :
Model classes are defined for the default persistence unit <default> but configured datasource <default> not found: the default EntityManagerFactory will not be created. To solve this, configure the default datasource. Refer to https://quarkus.io/guides/datasource for guidance.
But I still cannot set @PersistenceUnit
without value.
There is not default persistence unit / datasource in your configuration as far as Quarkus is concerned. There is only a named datasource which happens to be named
default
. The default persistence unit / datasource doesn't have a name.You should use this configuration:
Same for annotations, you shouldn't use the name "default":
As to why
quarkus-security-jpa
only works with the default PU... it seems support for named datasource simply wasn't implemented yet. I opened https://github.com/quarkusio/quarkus/issues/35231 to address that. In the meantime, the configuration I gave above should work.