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

Querydsl collections fails to generate and execute query in spring web projects #853

Open
1 task done
rnilss47 opened this issue Jan 29, 2025 · 3 comments
Open
1 task done

Comments

@rnilss47
Copy link

Important Notice

Thank you for opening an issue! Please note that, as outlined in the README, I currently only work on feature requests or bug fixes when sponsored. Balancing this project with professional and personal priorities means I have a very limited amount of effort I can divert to this project.

You must put in the work to address this issue, or it won't be addressed.

  • I am willing to put in the work and submit a PR to resolve this issue.

Querydsl fails to generate and execute queries inside threads used by Spring to handle requests. The following simple code:

@RestController
@SpringBootApplication
public class TestApplication {
    private static final List<Cat> CATS = List.of(new Cat("Felix"), new Cat("Garfield"));

    public static void main(final String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }

    @RequestMapping("/")
    public List<Cat> home() {
        return CollQueryFactory.from(QCat.cat, CATS)
                .where(QCat.cat.name.eq("Garfield"))
                .stream()
                .toList();
    }
}

produces this error:

2025-01-29T09:42:03.822+01:00 ERROR 1190827 --- [test] [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: com.querydsl.codegen.utils.CodegenException: Compilation of public class Q_252532505_1275614662_1275614662_1195259493 {

    public static Iterable<com.example.Cat> eval(Iterable<com.example.Cat> cat_, String a1) {
java.util.List<com.example.Cat> rv = new java.util.ArrayList<com.example.Cat>();
for (com.example.Cat cat : cat_) {
    try {
        if (com.querydsl.collections.CollQueryFunctions.equals(cat.getName(), a1)) {
            rv.add(cat);
        }
    } catch (NullPointerException npe) { }
}
return rv;    }

}

 failed.
/Q_252532505_1275614662_1275614662_1195259493.java:3: error: package com.example does not exist
    public static Iterable<com.example.Cat> eval(Iterable<com.example.Cat> cat_, String a1) {
                                                                     ^
/Q_252532505_1275614662_1275614662_1195259493.java:3: error: package com.example does not exist
    public static Iterable<com.example.Cat> eval(Iterable<com.example.Cat> cat_, String a1) {
                                      ^
/Q_252532505_1275614662_1275614662_1195259493.java:4: error: package com.example does not exist
java.util.List<com.example.Cat> rv = new java.util.ArrayList<com.example.Cat>();
                          ^
/Q_252532505_1275614662_1275614662_1195259493.java:4: error: package com.example does not exist
java.util.List<com.example.Cat> rv = new java.util.ArrayList<com.example.Cat>();
                                                                        ^
/Q_252532505_1275614662_1275614662_1195259493.java:5: error: package com.example does not exist
for (com.example.Cat cat : cat_) {
                ^
/Q_252532505_1275614662_1275614662_1195259493.java:7: error: package com.querydsl.collections does not exist
        if (com.querydsl.collections.CollQueryFunctions.equals(cat.getName(), a1)) {
                                    ^
6 errors
] with root cause

com.querydsl.codegen.utils.CodegenException: Compilation of public class Q_252532505_1275614662_1275614662_1195259493 {

    public static Iterable<com.example.Cat> eval(Iterable<com.example.Cat> cat_, String a1) {
java.util.List<com.example.Cat> rv = new java.util.ArrayList<com.example.Cat>();
for (com.example.Cat cat : cat_) {
    try {
        if (com.querydsl.collections.CollQueryFunctions.equals(cat.getName(), a1)) {
            rv.add(cat);
        }
    } catch (NullPointerException npe) { }
}
return rv;    }

}

 failed.
/Q_252532505_1275614662_1275614662_1195259493.java:3: error: package com.example does not exist
    public static Iterable<com.example.Cat> eval(Iterable<com.example.Cat> cat_, String a1) {
                                                                     ^
/Q_252532505_1275614662_1275614662_1195259493.java:3: error: package com.example does not exist
    public static Iterable<com.example.Cat> eval(Iterable<com.example.Cat> cat_, String a1) {
                                      ^
/Q_252532505_1275614662_1275614662_1195259493.java:4: error: package com.example does not exist
java.util.List<com.example.Cat> rv = new java.util.ArrayList<com.example.Cat>();
                          ^
/Q_252532505_1275614662_1275614662_1195259493.java:4: error: package com.example does not exist
java.util.List<com.example.Cat> rv = new java.util.ArrayList<com.example.Cat>();
                                                                        ^
/Q_252532505_1275614662_1275614662_1195259493.java:5: error: package com.example does not exist
for (com.example.Cat cat : cat_) {
                ^
/Q_252532505_1275614662_1275614662_1195259493.java:7: error: package com.querydsl.collections does not exist
        if (com.querydsl.collections.CollQueryFunctions.equals(cat.getName(), a1)) {
                                    ^
6 errors

	at com.querydsl.codegen.utils.JDKEvaluatorFactory.compile(JDKEvaluatorFactory.java:83) ~[querydsl-codegen-utils-6.10.1.jar:na]
	at com.querydsl.codegen.utils.AbstractEvaluatorFactory.createEvaluator(AbstractEvaluatorFactory.java:146) ~[querydsl-codegen-utils-6.10.1.jar:na]
	at com.querydsl.collections.DefaultEvaluatorFactory.createEvaluator(DefaultEvaluatorFactory.java:164) ~[querydsl-collections-6.10.1.jar:na]
	at com.querydsl.collections.DefaultQueryEngine.evaluateSingleSource(DefaultQueryEngine.java:175) ~[querydsl-collections-6.10.1.jar:na]
	at com.querydsl.collections.DefaultQueryEngine.list(DefaultQueryEngine.java:89) ~[querydsl-collections-6.10.1.jar:na]
	at com.querydsl.collections.AbstractCollQuery.fetch(AbstractCollQuery.java:195) ~[querydsl-collections-6.10.1.jar:na]
	at com.querydsl.collections.AbstractCollQuery.stream(AbstractCollQuery.java:188) ~[querydsl-collections-6.10.1.jar:na]
	at com.example.TestApplication.home(TestApplication.java:29) ~[classes/:na]
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:257) ~[spring-web-6.2.2.jar:6.2.2]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:190) ~[spring-web-6.2.2.jar:6.2.2]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.2.2.jar:6.2.2]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:986) ~[spring-webmvc-6.2.2.jar:6.2.2]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:891) ~[spring-webmvc-6.2.2.jar:6.2.2]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.2.2.jar:6.2.2]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1088) ~[spring-webmvc-6.2.2.jar:6.2.2]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:978) ~[spring-webmvc-6.2.2.jar:6.2.2]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.2.2.jar:6.2.2]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) ~[spring-webmvc-6.2.2.jar:6.2.2]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) ~[tomcat-embed-core-10.1.34.jar:6.0]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.2.2.jar:6.2.2]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.34.jar:6.0]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.2.2.jar:6.2.2]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.2.jar:6.2.2]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.2.2.jar:6.2.2]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.2.jar:6.2.2]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.2.2.jar:6.2.2]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.2.jar:6.2.2]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at java.base/java.lang.Thread.run(Thread.java:1583) ~[na:na]

I found one workaround that seems to fix the issue. That is to run a dummy query in the main thread at the startup of the application. If I modify the main method like this then the issue goes away.

  public static void main(final String[] args) {
      SpringApplication.run(TestApplication.class, args);

      CollQueryFactory.from(QCat.cat, CATS)
              .where(QCat.cat.name.eq("Garfield"))
              .stream()
              .toList();
  }

I'm not sure what the issue is, but the workaround I found seems to indicate that this has something to do with threads and possible classpaths and classloaders.

Here is a repository that contains the minimal code required to reproduce this bug: https://github.com/rnilss47/querydsl-reproduce-collections-bug.

I am willing to put in the work and fix the issue, but I am not sure what change needs to be made.

@dev-jonghoonpark
Copy link

The above issue seems to be related to the issue below.
querydsl/querydsl#2964

ECJEvaluatorFactory is used when called from the main statement.
Otherwise, it uses JDKEvaluatorFactory, and this causes problems.

@rnilss47
Copy link
Author

rnilss47 commented Feb 3, 2025

Yes that seems to be the reason. Is it possible to move over to ECJEvaluatorFactory entirely?

kamilkrzywanski added a commit to kamilkrzywanski/querydsl_feign that referenced this issue Feb 6, 2025
@kamilkrzywanski
Copy link
Contributor

kamilkrzywanski commented Feb 6, 2025

Classpath of tomcat is empty with this fix it shoud work fine :)
#870
@rnilss47
@velo

kamilkrzywanski added a commit to kamilkrzywanski/querydsl_feign that referenced this issue Feb 6, 2025
kamilkrzywanski added a commit to kamilkrzywanski/querydsl_feign that referenced this issue Feb 6, 2025
velo pushed a commit to kamilkrzywanski/querydsl_feign that referenced this issue Feb 7, 2025
kamilkrzywanski added a commit to kamilkrzywanski/querydsl_feign that referenced this issue Feb 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants