CustomerCondition customerCondition = new CustomerCondition();
customerCondition.setId(condition.getCustomerId());
customerCondition.setKeyword(condition.getCustomerKeyword());
customerCondition.setPageNum(1);
customerCondition.setPageSize(Integer.MAX_VALUE);
List<CustomerResponse> customerResponseList = customerService.getPage(
CustomerCondition.defaultBuilder()
.id(condition.getCustomerId())
.keyword(condition.getCustomerKeyword())
.build()
).getRecords();
为什么build注解设置父类字段的值,会爆红
根据你提供的代码,问题在于 CustomerCondition.defaultBuilder() 创建的构建器可能没有包含父类 PageRequest 的字段。这是 Lombok @Builder 注解的一个常见限制。
问题分析
-
父类字段不可见 :Lombok 的
@Builder默认只处理当前类中声明的字段,不包含父类字段 -
构建器方法缺失 :
defaultBuilder()返回的构建器可能没有父类的pageNum、pageSize等方法
解决方案
方案一:使用 @SuperBuilder(推荐)
这是 Lombok 专门用于处理继承关系的构建器注解。
修改 PageRequest 类:
java
package com.admin.common;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
@Getter
@Setter
@SuperBuilder // 添加这个注解
public class PageRequest {
private Integer pageNum = 1;
private Integer pageSize = 20;
private String keyword;
// ... 其他字段
}
修改 CustomerCondition 类:
java
package com.admin.condition;
import com.admin.common.PageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.io.Serializable;
import java.util.List;
@Data
@Schema(description = "客户表")
@SuperBuilder(toBuilder = true) // 将 @Builder 改为 @SuperBuilder
@AllArgsConstructor
@NoArgsConstructor
public class CustomerCondition extends PageRequest implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "客户id")
private Long id;
@Schema(description = "主键列表")
private List<Long> ids;
@Schema(description = "客户状态")
private String customerStatus;
@Schema(description = "是否查询客户账户")
private Boolean isQueryAccount = false;
@Schema(description = "客户账户条件")
private CustomerAccountCondition accountCondition;
// 删除之前的 defaultBuilder() 方法,使用 @SuperBuilder 提供的构建器
}
使用方式:
java
List<CustomerResponse> customerResponseList = customerService.getPage(
CustomerCondition.builder() // 直接使用 @SuperBuilder 生成的构建器
.pageNum(1)
.pageSize(Integer.MAX_VALUE)
.id(condition.getCustomerId())
.keyword(condition.getCustomerKeyword())
.build()
).getRecords();
方案二:手动添加父类字段到构建器(如果无法使用 @SuperBuilder)
修改 CustomerCondition 类:
java
@Data
@Schema(description = "客户表")
@Builder(builderClassName = "CustomerConditionBuilder", builderMethodName = "hiddenBuilder")
@AllArgsConstructor
@NoArgsConstructor
public class CustomerCondition extends PageRequest implements Serializable {
// ... 字段定义
// 自定义构建器类
public static class CustomerConditionBuilder {
// 添加父类字段
private Integer pageNum = 1;
private Integer pageSize = 20;
private String keyword;
// 其他父类字段...
// 添加父类字段的设置方法
public CustomerConditionBuilder pageNum(Integer pageNum) {
this.pageNum = pageNum;
return this;
}
public CustomerConditionBuilder pageSize(Integer pageSize) {
this.pageSize = pageSize;
return this;
}
public CustomerConditionBuilder keyword(String keyword) {
this.keyword = keyword;
return this;
}
// 修改 build 方法以包含父类字段
public CustomerCondition build() {
CustomerCondition condition = new CustomerCondition();
// 设置父类字段
condition.setPageNum(this.pageNum);
condition.setPageSize(this.pageSize);
condition.setKeyword(this.keyword);
// 设置当前类字段
condition.setId(this.id);
condition.setIds(this.ids);
condition.setContractArea(this.contractArea);
condition.setCustomerCategory(this.customerCategory);
condition.setCustomerStatus(this.customerStatus);
condition.setIsQueryAccount(this.isQueryAccount);
condition.setAccountCondition(this.accountCondition);
return condition;
}
}
// 提供公共的构建器方法
public static CustomerConditionBuilder builder() {
return new CustomerConditionBuilder();
}
}
方案三:使用组合代替继承
如果父类字段不多,可以考虑使用组合:
java
@Data
@Schema(description = "客户表")
@Builder(toBuilder = true)
@AllArgsConstructor
@NoArgsConstructor
public class CustomerCondition implements Serializable {
private static final long serialVersionUID = 1L;
// 包含 PageRequest 的字段
@Schema(description = "页码")
@Builder.Default
private Integer pageNum = 1;
@Schema(description = "每页条数")
@Builder.Default
private Integer pageSize = 20;
@Schema(description = "关键词")
private String keyword;
// 原有的字段
@Schema(description = "客户id")
private Long id;
@Schema(description = "主键列表")
private List<Long> ids;
// ... 其他字段
}
方案四:简化代码,不使用构建器
既然你之前的代码可以工作,可以直接使用:
java
CustomerCondition customerCondition = new CustomerCondition();
customerCondition.setId(condition.getCustomerId());
customerCondition.setKeyword(condition.getCustomerKeyword());
customerCondition.setPageNum(1);
customerCondition.setPageSize(Integer.MAX_VALUE);
List<CustomerResponse> customerResponseList = customerService.getPage(customerCondition).getRecords();
或者在类中添加一个便捷方法:
java
// 在 CustomerCondition 类中添加
public static CustomerCondition createDefault() {
CustomerCondition condition = new CustomerCondition();
condition.setPageNum(1);
condition.setPageSize(20);
condition.setIsQueryAccount(false);
return condition;
}
// 使用方式
CustomerCondition customerCondition = CustomerCondition.createDefault();
customerCondition.setId(condition.getCustomerId());
customerCondition.setKeyword(condition.getCustomerKeyword());
customerCondition.setPageSize(Integer.MAX_VALUE);
推荐方案
-
首选方案一 (使用
@SuperBuilder):-
最符合 Lombok 的设计理念
-
代码最简洁
-
完全支持继承
-
-
如果无法升级 Lombok 版本(需要 1.18.2+):
-
使用方案四,保持简单
-
或者使用方案二的变体
-
注意事项
-
Lombok 版本要求 :
@SuperBuilder需要 Lombok 1.18.2 或更高版本 -
依赖更新 :确保所有相关类都正确导入
@SuperBuilder -
编译插件 :确保 IDE 的 Lombok 插件已更新到支持
@SuperBuilder的版本
选择适合你项目情况的方案。如果项目 Lombok 版本较低且无法升级,建议使用方案四(简化代码)。如果可以升级 Lombok,强烈推荐使用方案一。