【问题标题】:java.lang.NullPointerException: while filtering data using QueryDsljava.lang.NullPointerException:使用 QueryDsl 过滤数据时
【发布时间】:2026-01-07 06:25:01
【问题描述】:

我正在使用 Spring data jpa 来创建服务。在以下代码中,我使用 Querydsl 在网格上实现搜索过滤器。但是对于建筑物名称,我无法过滤网格。我收到 java.lang.NullPointerException: null

因为网格数据来自多个表。我没有为此使用加入。我将模型类相互映射

@Service
public class RoomTransferService {

    @Autowired
    RoomTransferRepository roomTransferRepo;

    @PersistenceContext
    EntityManager em;

    public List<RoomTransfer> findRoomTransfer(String sStatus, String sBuildName, String deptFrom, String deptTo) {

        QRoomTransfer roomTransfer = QRoomTransfer.roomTransfer;

        JPAQuery<RoomTransfer> query = new JPAQuery<RoomTransfer>(em);

        query.from(roomTransfer);

        // filter the details
        if (sStatus != null) {          
            query.where(roomTransfer.sStatus.eq(sStatus));
        }

        // not filtering
        if(sBuildName !=null) {     

            query.where(roomTransfer.roomDeptMap.room.building.sBuildName.eq(sBuildName));
        }
       List<RoomTransfer> QueryResultRoomTramsfer=query.fetch();
       Return QueryResultRoomTramsfer;

房间类

@Entity
@Table(name = "room")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Room implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "room_seq_generator")
    @SequenceGenerator(name = "room_seq_generator", sequenceName = "room_seq")
    @Column(name = "nroom_id")
    public Integer nRoomId;

    @Column(name = "ncampus_id")
    public Integer nCampusId;

    @Column(name = "nbuild_id")
    public Integer nBuildId;

    @Column(name = "ninst_id")
    public Integer nInstId;

    @Column(name = "sfloor")
    public String sFloor;

    @Column(name = "sroom_number")
    public String sRoomNumber;

    @Column(name = "sroom_desc")
    public String sRoomDesc;

    @Column(name = "scomments")
    public String sComments; 

    @Column(name = "daccepted_date")
    public Timestamp dAcceptedDate;

    @Column(name = "ssurveyor")
    public String sSurveyor;

    @Column(name = "narea")
    public Integer nArea;

    @Column(name = "ncrt_code_id")
    public Integer nCRTCodeId;

    @Column(name = "ncmn_room_bln")
    public Integer nCMNRoomBln;

    @Column(name = "nunvalidated_bln")
    public Integer nUnvalidatedBln;

    @Column(name = "sbfr_field")
    public String sBfrField;

    @Column(name = "ntemp_room_id")
    public Integer nTempRoomId;

    @Column(name = "bis_active")
    public Boolean bIsActive;

    @Column(name = "bis_jointuse")
    public Boolean bIsJointuse;

    @Column(name = "sstations_desc")
    public String sStationsDesc;

    @Column(name = "ddeleted_on")
    public Timestamp dDeletedOn;

    @Column(name = "ndeleted_by")
    public Integer nDeletedBy;

    @Column(name = "bis_incluster")
    public Boolean bIsIncluster;

    @Column(name = "bis_service_center_activity")
    public Boolean bisServiceCenterActivity;

    @Column(name = "service_center_comments")
    public String serviceCenterComments;

    @ManyToOne(optional = true)
    @JoinColumn(name = "nbuild_id", insertable = false, updatable = false)
    public Building building;

【问题讨论】:

  • 你调试过你的代码吗?什么是空? roomTransfer.roomDeptMap.room.building.sBuildName 这里有很多可能的空值...

标签: spring-data-jpa querydsl


【解决方案1】:

你得到的NPE可能和QueryDsl的限制有关,不能超过四级。

您的代码超过了四个级别。

roomTransfer.roomDeptMap.room.building.sBuildName

您可以在official documentation 或相关*'s question 上阅读更多信息。

在第一个链接中,有一个解决方案可以使用QueryInit 注释来解决此问题。

如果您不想更改实体类,您可以使用前 2 或 3 级的别名执行连接(如果可能),然后使用此别名完成查询。

【讨论】:

  • 我添加了 Room 类你能告诉我如何使用QueryInit
  • 我可以像这样使用@QueryInit("building.sBuildName") @ManyToOne(optional = true) @JoinColumn(name = "nbuild_id", insertable = false, updatable = false) public Building building;
  • 我之前没用过这个注解,但是你可以试试你上面问的。因为我不想更改我的实体类,所以我总是执行连接。所以试试这个:query.join(roomTransfer.roomDeptMap,someAlias).where(someAlias.room.building...)。我不知道您的 RoomTransfer 课程,因此您必须根据您的课程编辑加入。