Skip to content

Possible shared state / unexpected data mixing when using static Q-types in Spring Boot + Tomcat (QueryDSL 6.5) #1575

@zio0911

Description

@zio0911

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.

I am willing to investigate and submit a PR if this behavior is confirmed or guidance is provided.

Describe the bug

In a production environment (Spring Boot + Tomcat, QueryDSL 6.5), we observed unexpected data mixing between concurrent requests when QueryDSL Q-classes were referenced via import static.

Although Q-types are generally documented and understood as stateless, under multi-threaded runtime conditions some query results appeared to be affected by other concurrent requests.
This issue was not reproducible in local or low-concurrency environments, but occurred consistently under load (EC2 + Tomcat).

This issue is reported mainly to request official clarification, rather than to assert a definite framework bug.

To Reproduce

Reproduction is difficult in a minimal local setup, but the behavior can be summarized as follows:

Use QueryDSL 6.5 (OpenFeign) with Spring Boot (Servlet stack) and Tomcat

Reference Q-types using static imports, for example:

import static com.example.domain.QMember.member;
import static com.example.domain.QTeam.team;

Build dynamic queries using these Q-types

Deploy the application to a multi-threaded environment (e.g. EC2 with Tomcat)

Under concurrent request load, observe that:

Query results from different requests appear to be mixed

Conditions from one request seem to affect another

Expected behavior

Each request should execute its QueryDSL query independently, without any shared state or interference from other concurrent requests, regardless of how Q-types are referenced.

Actual behavior

Under concurrent load:

Query results appeared to be mixed across requests

The issue only occurred when Q-types were referenced via import static

When Q-types were declared inside the class or inside repository methods, the issue did not occur

Screenshots

Not applicable.

Desktop (please complete the following information)

OS: Linux (EC2)

Application Server: Tomcat

Java: 17

Spring Boot: 3.x

QueryDSL: 6.5 (OpenFeign)

JPA Provider: Hibernate

Additional context
Clarification Request (Key Point of This Issue)

The main reason for opening this issue is that some official guides and examples demonstrate the use of import static for Q-types.

In our case:

Declaring Q-types inside a class or inside repository methods worked correctly and did not reproduce the issue.

However, referencing Q-types via import static consistently caused data mixing issues under concurrent load.

This suggests that the issue may not be the Q-types themselves, but rather how static imports interact with query construction and lifecycle in a multi-threaded runtime environment.

Because import static is used in official guides and examples, we would like to ask for an official position on the following points:

Is the use of import static for Q-types considered fully safe and recommended in high-concurrency environments?

Are there any known caveats, limitations, or edge cases related to static imports versus method-local Q-type usage?

If method-local or non-static usage is preferred in certain scenarios, should this be documented more explicitly?

Workaround / Mitigation

The issue was resolved by:

Removing all import static usage for Q-types

Declaring Q-types inside repository methods, for example:

QMember member = new QMember("member");
QTeam team = new QTeam("team");

After applying this change:

The data mixing issue no longer occurred

The behavior remained stable under concurrent load

Notes

We understand that Q-types are designed to be stateless and reusable.

The issue may involve interaction with:

Predicate / BooleanBuilder

JPAQuery lifecycle

Alias reuse under concurrent execution

However, from an operational standpoint, eliminating static Q-type references completely resolved the problem.

Compiled class files did not show meaningful differences, suggesting this is a runtime concurrency-related issue, not a compilation issue.

Thank you for maintaining the project and for any clarification or guidance you can provide.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions