Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

quarkus-security-jpa:3.5.2 when config multi datasources #37277

Closed
987856377 opened this issue Nov 23, 2023 · 3 comments
Closed

quarkus-security-jpa:3.5.2 when config multi datasources #37277

987856377 opened this issue Nov 23, 2023 · 3 comments
Labels
area/security kind/bug Something isn't working triage/invalid This doesn't seem right

Comments

@987856377
Copy link

Describe the bug

quarkus-security-jpa:3.5.2 can't determine which datasource to use when config multi datasources

Expected behavior

ways resolve:

  1. Indicate which datasource in @UserDefinition , like @UserDefinition(ds = "his"),
    then JpaTrustedIdentityProvider.java and JpaIdentityProvider.java in quarkus-security-jpa use the @UserDefinition attribute indicates
  2. quarkus.hibernate-orm.his.packages = com.acme.application.module.his
    com.acme.application.module.his.entity.User.java under package com.acme.application.module.his use current datasource

Actual behavior

When i run my application , then error shows:

[error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: jakarta.enterprise.inject.spi.DeploymentException: Found 2 deployment problems: 
[1] Unsatisfied dependency for type jakarta.persistence.EntityManagerFactory and qualifiers [@Default]
	- java member: io.quarkus.security.jpa.runtime.JpaIdentityProvider#entityManagerFactory
	- declared on CLASS bean [types=[com.acme.application.module.his.entity.User__JpaIdentityProviderImpl, io.quarkus.security.jpa.runtime.JpaIdentityProvider, io.quarkus.security.identity.IdentityProvider<io.quarkus.security.identity.request.UsernamePasswordAuthenticationRequest>, java.lang.Object], qualifiers=[@Default, @Any], target=com.acme.application.module.his.entity.User__JpaIdentityProviderImpl]
	The following beans match by type, but none have matching qualifiers:
		- Bean [class=org.hibernate.SessionFactory, qualifiers=[@Any, @io.quarkus.hibernate.orm.PersistenceUnit("his"), @Named("his")]]
		- Bean [class=org.hibernate.SessionFactory, qualifiers=[@io.quarkus.hibernate.orm.PersistenceUnit("lis"), @Any, @Named("lis")]]
[2] 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>, java.lang.Object, com.acme.application.module.his.entity.User__JpaTrustedIdentityProviderImpl], qualifiers=[@Default, @Any], target=com.acme.application.module.his.entity.User__JpaTrustedIdentityProviderImpl]
	The following beans match by type, but none have matching qualifiers:
		- Bean [class=org.hibernate.SessionFactory, qualifiers=[@Any, @io.quarkus.hibernate.orm.PersistenceUnit("his"), @Named("his")]]
		- Bean [class=org.hibernate.SessionFactory, qualifiers=[@io.quarkus.hibernate.orm.PersistenceUnit("lis"), @Any, @Named("lis")]]
	at io.quarkus.arc.processor.BeanDeployment.processErrors(BeanDeployment.java:1455)
	at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:311)
	at io.quarkus.arc.processor.BeanProcessor.initialize(BeanProcessor.java:158)
	at io.quarkus.arc.deployment.ArcProcessor.validate(ArcProcessor.java:471)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:849)
	at io.quarkus.builder.BuildContext.run(BuildContext.java:282)
	at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
	at java.base/java.lang.Thread.run(Thread.java:833)
	at org.jboss.threads.JBossThread.run(JBossThread.java:501)
	Suppressed: jakarta.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type jakarta.persistence.EntityManagerFactory and qualifiers [@Default]
	- java member: io.quarkus.security.jpa.runtime.JpaIdentityProvider#entityManagerFactory
	- declared on CLASS bean [types=[com.acme.application.module.his.entity.User__JpaIdentityProviderImpl, io.quarkus.security.jpa.runtime.JpaIdentityProvider, io.quarkus.security.identity.IdentityProvider<io.quarkus.security.identity.request.UsernamePasswordAuthenticationRequest>, java.lang.Object], qualifiers=[@Default, @Any], target=com.acme.application.module.his.entity.User__JpaIdentityProviderImpl]
	The following beans match by type, but none have matching qualifiers:
		- Bean [class=org.hibernate.SessionFactory, qualifiers=[@Any, @io.quarkus.hibernate.orm.PersistenceUnit("his"), @Named("his")]]
		- Bean [class=org.hibernate.SessionFactory, qualifiers=[@io.quarkus.hibernate.orm.PersistenceUnit("lis"), @Any, @Named("lis")]]
		at io.quarkus.arc.processor.Beans.resolveInjectionPoint(Beans.java:478)
		at io.quarkus.arc.processor.BeanInfo.init(BeanInfo.java:624)
		at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:299)
		... 13 more

How to Reproduce?

  1. When i config two datasources in application.properties :
quarkus.datasource.his.db-kind = postgresql
quarkus.datasource.his.jdbc.url = jdbc:postgresql://localhost:5432/test1
quarkus.datasource.his.username = postgres
quarkus.datasource.his.password = postgres
quarkus.hibernate-orm.his.datasource = his
quarkus.hibernate-orm.his.packages = com.acme.application.module.his
quarkus.hibernate-orm.his.database.generation = drop-and-create
quarkus.hibernate-orm.his.log.sql = true
quarkus.hibernate-orm.his.log.format-sql = true

quarkus.datasource.lis.db-kind = postgresql
quarkus.datasource.lis.jdbc.url = jdbc:postgresql://localhost:5432/test2
quarkus.datasource.lis.username = postgres
quarkus.datasource.lis.password = postgres
quarkus.hibernate-orm.lis.datasource = lis
quarkus.hibernate-orm.lis.packages = com.acme.application.module.lis
quarkus.hibernate-orm.lis.database.generation = drop-and-create
quarkus.hibernate-orm.lis.log.sql = true
quarkus.hibernate-orm.lis.log.format-sql = true
  1. Use quarkus-security-jpa, the User.java
@Entity
@Table(name = "test_user")
@UserDefinition
@SQLDelete(sql = "update test_user set deleted = 1, version = version + 1 where id = ? and version = ?")
@Where(clause = "deleted = 0")
public class User extends PanacheEntity {
    @Username
    public String username;
    @Password
    public String password;
    public Integer deleted = 0;
    @Version
    public Integer version = 0;

    @ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
    @JoinTable(name = "test_user_role", joinColumns = {@JoinColumn(name = "u_id", referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "r_id", referencedColumnName = "id")})
    @Roles
    public List<Role> roles = new ArrayList<>();

    /**
     * Adds a new user to the database
     *
     * @param username the username
     * @param password the unencrypted password (it will be encrypted with bcrypt)
     * @param roles    the comma-separated roles
     */
    public static void add(String username, String password, List<Role> roles) {
        User user = new User();
        user.username = username;
        user.password = password;
        user.roles = roles;
        user.persist();
    }
}
  1. JpaTrustedIdentityProvider.java and JpaIdentityProvider.java in quarkus-security-jpa:3.5.2 just inject:
    @Inject
    EntityManagerFactory entityManagerFactory;
    

### Output of `uname -a` or `ver`

_No response_

### Output of `java -version`

17

### Quarkus version or git rev

3.5.2

### Build tool (ie. output of `mvnw --version` or `gradlew --version`)

apache-maven-3.9.5

### Additional information

_No response_
@987856377 987856377 added the kind/bug Something isn't working label Nov 23, 2023
Copy link

quarkus-bot bot commented Nov 23, 2023

/cc @sberyozkin (security)

@michalvavrik
Copy link
Member

michalvavrik commented Nov 25, 2023

Hello @987856377 ,

Quarkus uses default datasource. You use Quarkus 3.5.2. I've added #36728 option to set quarkus.security-jpa.persistence-unit-name=his in Quarkus 3.6.x +.

I think currently there is 3.6.0.CR1 released on which you can try it. I think 3.6.0 should be released any time now: https://github.com/quarkusio/quarkus/wiki/Release-Planning

Please consider trying it and closing this issue as it is not a bug because it was not documented to work, but 100 % agree it was worth implementing :-)

@michalvavrik michalvavrik added triage/consider-closing Bugs that are considered to be closed because too old. Using the label to do a mark and sweep proces triage/invalid This doesn't seem right and removed triage/consider-closing Bugs that are considered to be closed because too old. Using the label to do a mark and sweep proces labels Nov 25, 2023
@michalvavrik
Copy link
Member

Closing as this is fixed with Quarkus 3.6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/security kind/bug Something isn't working triage/invalid This doesn't seem right
Projects
None yet
Development

No branches or pull requests

2 participants