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

Lombok @AllArgsConstructor未包含父类属性的泛型抽象类继承问题

解决方案:泛型抽象父类继承下的Lombok+JPA配置优化

1. 修正主键字段映射(解决emp_id映射问题)

父类的id字段需要映射到数据库的emp_id列,无需修改父类字段名(避免破坏通用Service复用逻辑),直接在子类使用JPA的@AttributeOverride注解覆盖字段映射配置即可:

@Entity
@Table(name = "employee")
@EqualsAndHashCode(callSuper = true)
@Getter
@Setter
@NoArgsConstructor
public class Employee extends GenericEntity<Employee> implements Serializable {

    // 覆盖父类id字段的映射规则,指定对应数据库列名emp_id
    @AttributeOverride(name = "id", column = @Column(name = "emp_id", nullable = false, updatable = false))
    private Long id;

    @Column(name = "first_name", nullable = false)
    private String firstName;
    @Column(name = "last_name", nullable = false)
    private String lastName;
    // 其余映射字段...
}

2. 用Lombok生成目标构造器

方式一:生成指定参数的构造器(匹配需求)

如果需要生成Employee(Long empId, String firstName, String lastName)这类构造器,可结合@RequiredArgsConstructor和@NonNull实现:

@Entity
@Table(name = "employee")
@EqualsAndHashCode(callSuper = true)
@Getter
@Setter
@NoArgsConstructor
@RequiredArgsConstructor // 生成包含所有@NonNull字段的构造器
public class Employee extends GenericEntity<Employee> implements Serializable {

    @AttributeOverride(name = "id", column = @Column(name = "emp_id", nullable = false, updatable = false))
    @NonNull
    private Long id;

    @Column(name = "first_name", nullable = false)
    @NonNull
    private String firstName;

    @Column(name = "last_name", nullable = false)
    @NonNull
    private String lastName;
    // 其余映射字段...
}

Lombok会自动生成如下构造器(自动调用父类的@AllArgsConstructor构造器传入id):

public Employee(@NonNull Long id, @NonNull String firstName, @NonNull String lastName) {
    super(id);
    this.id = id;
    this.firstName = firstName;
    this.lastName = lastName;
}

调用时用变量名empId即可保证可读性:

Long empId = 1L;
Employee emp = new Employee(empId, "John", "Doe");

方式二:用@Builder生成灵活构造器

如果需要更灵活的对象构建方式,推荐使用@Builder,支持任意参数组合:

@Entity
@Table(name = "employee")
@EqualsAndHashCode(callSuper = true)
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder(toBuilder = true)
public class Employee extends GenericEntity<Employee> implements Serializable {

    @AttributeOverride(name = "id", column = @Column(name = "emp_id", nullable = false, updatable = false))
    private Long id;

    @Column(name = "first_name", nullable = false)
    private String firstName;
    @Column(name = "last_name", nullable = false)
    private String lastName;
    // 其余映射字段...
}

调用示例:

Employee emp = Employee.builder()
        .id(1L) // 对应数据库emp_id列
        .firstName("John")
        .lastName("Doe")
        .build();

3. 保障通用Service复用性

由于子类保留了父类id字段的定义(仅覆盖映射规则),通用Service可直接基于GenericEntity<T>编写:

public abstract class GenericService<T extends GenericEntity<T>> {
    public T findById(Long id) {
        // 通用查询逻辑
        return null;
    }
    // 其他通用方法:save、delete等
}

@Service
public class EmployeeService extends GenericService<Employee> {
    // 复用父类方法,按需添加自定义逻辑
}

关键注意事项

  • 父类必须保留@AllArgsConstructor,否则子类Lombok构造器无法自动调用父类构造器传入id
  • @AttributeOverride是JPA规范写法,不会破坏继承结构,完美适配通用代码复用场景
  • 若无需非空校验,可去掉@NonNull,改用@AllArgsConstructor+@Builder组合实现灵活构造

内容的提问来源于stack exchange,提问作者AbdoCherry

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 20:13:23