Spring Data中QueryDSL无法为嵌套嵌入对象生成Q类求助
QueryDSL未生成嵌入类AddressDetails的Q类问题解决
问题场景
定义了MongoDB集合及嵌入文档结构如下:
PersonDetails.java
@Data @Builder @NoArgsConstructor @AllArgsConstructor @JsonInclude(JsonInclude.Include.NON_NULL) @Document(collection = "person_details") public class PersonDetails { @MongoId(FieldType.OBJECT_ID) private String managerId; @QueryInit("addressDetails.*") private List<ContactDetails> contactDetails; }
ContactDetails.java
@Data @Builder @NoArgsConstructor @AllArgsConstructor @JsonInclude(JsonInclude.Include.NON_NULL) public class ContactDetails { private AddressDetails addressDetails; private StateDetails stateDetails; }
AddressDetails.java
@Data @Builder @NoArgsConstructor @AllArgsConstructor @JsonInclude(JsonInclude.Include.NON_NULL) public class AddressDetails { private String address; @Field(targetType = FieldType.STRING) private AddressTypeEnum addressType; }
StateDetails.java
@Data @Builder @NoArgsConstructor @AllArgsConstructor @JsonInclude(JsonInclude.Include.NON_NULL) @Document(collection = "statedetails") public class StateDetails { @MongoId(FieldType.OBJECT_ID) private String stateId; private String stateName; }
构建项目后,QueryDSL仅生成了QPersonDetails和QContactDetails,但未生成QAddressDetails,导致构建Predicate时无法访问AddressDetails的字段(QContactDetails中addressDetails是SimplePath<AddressDetails>类型,无法链式调用内部字段)。尝试修改@QueryInit注解参数为*.*也未解决问题,且不想给AddressDetails添加@Document注解。
问题原因
QueryDSL默认仅会为标注了@Document的实体类生成Q类,对于普通的嵌入类(如AddressDetails),如果没有明确标记为可嵌入的持久化类,QueryDSL不会为其生成对应的Q类,仅会将其处理为SimplePath类型,无法展开内部字段。@QueryInit注解的作用是初始化路径层级,但不会触发Q类的生成。
解决方案
1. 给AddressDetails添加@Embeddable注解
@Embeddable是用于标记嵌入类的注解,QueryDSL会识别该注解并为类生成对应的Q类:
@Data @Builder @NoArgsConstructor @AllArgsConstructor @JsonInclude(JsonInclude.Include.NON_NULL) @Embeddable // 关键注解 public class AddressDetails { private String address; @Field(targetType = FieldType.STRING) private AddressTypeEnum addressType; }
2. 调整@QueryInit配置确保路径初始化
可以选择以下两种方式之一:
- 在
PersonDetails的contactDetails字段上更新@QueryInit:@QueryInit("*.addressDetails.*") private List<ContactDetails> contactDetails; - 或者在
ContactDetails的addressDetails字段上添加@QueryInit:@QueryInit("*") private AddressDetails addressDetails;
3. 重新构建项目
执行项目构建命令(如mvn clean compile或gradle build)后,QueryDSL会生成QAddressDetails,同时QContactDetails中的addressDetails会变为QAddressDetails类型的路径,此时即可正常链式调用AddressDetails的字段构建Predicate,例如:
QPersonDetails person = QPersonDetails.personDetails; Predicate predicate = person.contactDetails.any().addressDetails.address.eq("某地址");
内容的提问来源于stack exchange,提问作者Krishna
相关产品推荐
相关产品推荐

