You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JDK11下Querydsl @QueryInit(*.*)失效引发空指针异常

JDK11下Querydsl @QueryInit访问第三层嵌套属性触发NullPointerException问题

问题描述

项目从JDK8迁移至JDK11后,使用Querydsl的@QueryInit(*.*)注解时,前两层嵌套属性(SpeedViolation.fact1.car)可正常访问,但调用第三层属性vrp时抛出NullPointerException。该问题仅在JDK11环境下出现,JDK8环境运行完全正常。

相关代码

实体类代码

SpeedViolation类

@Document(collection = "speed_violation")
@Getter
@Setter
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SpeedViolation {
    // ...
    @NotNull
    @QueryEmbedded
    @QueryInit("*.*")
    protected Fact fact1;
    // ...
}

Fact类

@Data
@EqualsAndHashCode(of = "id")
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Fact {
    // ...
    @QueryEmbedded
    private Car car;
    // ...
}

Car类

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Car {
    @QueryEmbedded
    private Vrp vrp;
}

Vrp类

@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "number")
@Builder
public class Vrp {
    @NotNull
    private String number;
}

业务使用代码

@Override
public Optional<SpeedViolation> findPendingForFactViolation(String vrp,
                                                           Long complexId,
                                                           Long camera2Id,
                                                           LocalDateTime secondFactPhotoDate,
                                                           LocalDateTime maxFirstFactPhotoDate,
                                                           LocalDateTime minFirstFactPhotoDate) {
    QSpeedViolation speedViolation = QSpeedViolation.speedViolation;

    // 此处访问vrp时抛出NullPointerException
    Predicate predicate = speedViolation.fact1.car.vrp.number.eq(vrp);
    // ...
}

项目依赖配置(pom.xml)

<properties>
    <!-- ... -->
    <java.version>11</java.version>
    <spring-boot.version>2.1.6.RELEASE</spring-boot.version>
    <querydsl.version>4.2.2</querydsl.version>
    <lombok.version>1.18.16</lombok.version>
    <!-- ... -->
</properties>

<dependencies>
    <!-- ... -->
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-mongodb</artifactId>
        <version>2.1.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.querydsl</groupId>
        <artifactId>querydsl-mongodb</artifactId>
        <version>${querydsl.version}</version>
    </dependency>
    <!-- ... -->
</dependencies>

<build>
    <!-- ... -->
    <plugins>
        <plugin>
            <groupId>com.mysema.maven</groupId>
            <artifactId>apt-maven-plugin</artifactId>
            <version>1.1.3</version>
            <executions>
                <execution>
                    <goals>
                        <goal>process</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>target/generated-sources/java</outputDirectory>
                        <processor>
                            org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor
                        </processor>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <!-- ... -->
    </plugins>
</build>

解决方案

1. 调整@QueryInit注解的初始化深度

原注解@QueryInit("*.*")仅能初始化两层嵌套属性,需要明确指定三层初始化:

// 在SpeedViolation类的fact1字段上修改
@NotNull
@QueryEmbedded
@QueryInit("*.*.*")
protected Fact fact1;

或者在中间层Fact类的car字段上添加注解,显式初始化下一层:

// 在Fact类的car字段上添加
@QueryEmbedded
@QueryInit("*")
private Car car;

2. 升级依赖版本以兼容JDK11

原项目使用的Spring Boot 2.1.6和Querydsl 4.2.2对JDK11的兼容性较差,建议升级到更稳定的版本:

  • 将Spring Boot版本升级至2.7.x及以上(该版本全面支持JDK11)
  • 同步升级Querydsl至5.x系列,确保与Spring Data MongoDB版本匹配
  • 升级spring-data-mongodb到对应Spring Boot管理的版本,避免版本冲突

3. 替换旧的APT注解处理器

原项目使用的com.mysema.maven:apt-maven-plugin是旧版插件,JDK11的注解处理机制已发生变化,建议改用maven-compiler-plugin内置的注解处理:

  1. 移除apt-maven-plugin配置
  2. 在maven-compiler-plugin的annotationProcessorPaths中添加Querydsl的Mongo处理器:
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>${maven-compiler-plugin.version}</version>
    <configuration>
        <source>${java.version}</source>
        <target>${java.version}</target>
        <annotationProcessorPaths>
            <!-- 原有注解处理器 -->
            <path>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-configuration-processor</artifactId>
                <version>${spring-boot.version}</version>
            </path>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </path>
            <!-- 添加Querydsl MongoDB处理器 -->
            <path>
                <groupId>com.querydsl</groupId>
                <artifactId>querydsl-apt</artifactId>
                <version>${querydsl.version}</version>
                <classifier>mongodb</classifier>
            </path>
            <!-- ...其他处理器 -->
        </annotationProcessorPaths>
    </configuration>
</plugin>

内容的提问来源于stack exchange,提问作者Шатов Данил

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 13:15:32