I’m working on a domain extension in Keycloak 21.0.2 and facing an issue when trying to fetch data through its endpoint. I haven’t modified the code from the example. I simply compiled it, added the JAR file to the providers folder in Keycloak, and started the server.
When I run the curl command mentioned in the README.md:
curl -i --request GET http://localhost:8080/realms/master/example/companies --header "Accept: application/json"
I receive the following error:
Caused by: java.lang.IllegalArgumentException: No query defined for that name [findByRealm]
I also face this error when I want to add a company:
I don’t do much JPA but I can try to help troubleshoot;
The ExampleJpaEntityProvider specifies the Company.class entity where that query is defined; so I’m guessing the ExampleJpaEntityProviderFactory isn’t being identified as a provider and that code isn’t running.
If you look in /src/main/resources/META-INF/services that org.keycloak.examples.domainextension.jpa.ExampleJpaEntityProviderFactory is used to identify the class for use as a SPI and must be in the JAR you produced - open it up and verify that it’s there in the META-INF/services folder.
Check the master realm’s landing page; there’s a tab for providers which should list your domain-extension-example module if it was registered correctly. If it’s not there, try rerunning the steps in the README.md in the project (screenshot below)
That does not make sense, as this is an outdated screenshot and an outdated readme file. This is legacy (Wildfly) information, there is no more jboss-cli and no more “modules” in Quarkus.
Yes, if you’re running a newer version of Keycloak you don’t need to do those steps but OP didn’t specify what version they’re running. Also, if you’re trying to deploy this as-is in latest you’re going to run into issues going from javax to jakarta.
For the Quarkus version of keycloak you just need that first step then, make sure that in your JAR file there’s a file in META-INF/services named org.keycloak.connections.jpa.entityprovider.JpaEntityProviderFactory and it should have a single line in it; org.keycloak.examples.domainextension.jpa.ExampleJpaEntityProviderFactory
You can confirm the classes are loaded by checking the Provider Info tab in your master realm
Yep, the domain extension code is indeed from Keycloak 21.0.2, you are correct. I read that as “this code/extention is in Keycloak 21.0.2” so maybe I misunderstood; that code would be compatible with lots of versions of Keycloak though, pretty much anything supporting the JpaEntityProviderFactory SPI and pre-jakarta.
Not sure this is going to help OP troubleshoot the issue though, not really constructive. Do you have any thoughts on how to actually solve the issue or do you just want to troll?
@ben.overcash Thanks so much for your reply. I checked and the domain-extension-example module is registered correctly.
So any other suggestion that would help me figure this out? I would really appreciate it.
@ben.overcash@dasniko
Regarding the images I sent and the explanations, do you have any other suggestions?
Note that compiling with Jakarta caused many errors, so I switched to javax. For example, I replaced import jakarta.persistence.EntityManager; with import javax.persistence.EntityManager;.
This is the whole error:
2025-01-22 14:02:30,679 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (executor-thread-0) Uncaught server error: org.keycloak.models.ModelException: java.lang.IllegalArgumentException: No query defined for that name [findByRealm]
at org.keycloak.connections.jpa.PersistenceExceptionConverter.convert(PersistenceExceptionConverter.java:84)
at org.keycloak.connections.jpa.PersistenceExceptionConverter.invoke(PersistenceExceptionConverter.java:62)
at jdk.proxy2/jdk.proxy2.$Proxy69.createNamedQuery(Unknown Source)
at org.keycloak.examples.domainextension.spi.impl.ExampleServiceImpl.listCompanies(ExampleServiceImpl.java:53)
at org.keycloak.examples.domainextension.rest.CompanyResource.getCompanies(CompanyResource.java:31)
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 org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:170)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:130)
at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:660)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:524)
at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:474)
at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:476)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:434)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:192)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:152)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:183)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:141)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:32)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:492)
at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:261)
at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:161)
at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:164)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:247)
at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:151)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.handle(VertxRequestHandler.java:82)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.handle(VertxRequestHandler.java:42)
at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:173)
at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:84)
at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:71)
at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:173)
at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
at io.quarkus.vertx.http.runtime.VertxHttpRecorder$6.handle(VertxHttpRecorder.java:430)
at io.quarkus.vertx.http.runtime.VertxHttpRecorder$6.handle(VertxHttpRecorder.java:408)
at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:173)
at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
at org.keycloak.quarkus.runtime.integration.web.QuarkusRequestFilter.lambda$createBlockingHandler$0(QuarkusRequestFilter.java:82)
at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:576)
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.IllegalArgumentException: No query defined for that name [findByRealm]
at org.hibernate.internal.AbstractSharedSessionContract.buildQueryFromName(AbstractSharedSessionContract.java:923)
at org.hibernate.internal.AbstractSharedSessionContract.createNamedQuery(AbstractSharedSessionContract.java:1038)
at org.hibernate.internal.AbstractSessionImpl.createNamedQuery(AbstractSessionImpl.java:23)
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 org.keycloak.connections.jpa.PersistenceExceptionConverter.invoke(PersistenceExceptionConverter.java:60)
… 51 more
I’m really stuck on this issue and would greatly appreciate any guidance or suggestions you might have!
@dasniko
I exactly compile this project with no any other changes using mvn clean package and put the domain-extension-example.jar in the providers directory of Keycloak. When I send the request: curl --location 'http://localhost:8080/realms/master/example/companies
I face unknown error with error Caused by: java.lang.IllegalArgumentException: No query defined for that name [findByRealm].
Hm, I unfortunately don’t have time to try to reproduce it.
Not finding a named query and having this “unknown entity” exception yields for me to a missing persistence.xml file. I also can’t find one in the example folder.
But I also never have extended the Keycloak db schema and don’t know what exactly is required or not. Perhaps that’s the reason, as Keycloak doesn’t know that the Company entity exists in the persistence context!?
@dasniko
I’ve already tested adding a persistence.xml file, but it didn’t make any difference. Do you know what should I add to my persistence.xml or how should it be? The new table has been successfully created in my database, so the entity seems to be recognized. However, it appears that there’s an issue accessing the named query itself.
But I also never have extended the Keycloak db schema and don’t know what exactly is required or not.
I’m not that much into JPA persistence and I really don’t know if the XML file is required here or if there’s another way.
The table is not created by JPA itself, it’s done by Liquibase. So, having the table does not mean that there’s a recognized entity. And your mentioned message
points to an unknown entity. An for an unknown entity, JPA can’t find a named query.
IMHO the named query error is “just” a follow up of the root cause that there’s no entity recognized.
And now I’m out.
@dasniko
Thanks a lot for your reply!
I was able to fix the previous issue with the “unknown entity of Company.” I tested it with a simple snippet like this: Company c = new Company();, and it worked fine without any errors.
Now, I’m running into a different problem. When I call this API:
curl -i --request GET http://localhost:8080/realms/master/example/companies --header "Accept: application/json"
I get the following error:
Caused by: java.lang.IllegalArgumentException: No query defined for that name [findByRealm]
Any idea what might be causing this? I’d really appreciate your help again!