SuperAPI AI Directory

lombok-patterns

Data & analytics

View repository

Updated 10-16 08:47

About this skill

Lombok annotation usage rules

Source:https://projectlombok.org/features/
GitHub:https://github.com/projectlombok/lombok

Capability Boundaries

✅ Strong Suits

  1. @Data/@Builder/@Slf4j combination rules — when to use which, and when they cannot be combined
  2. @EqualsAndHashCode(callSuper=true) — the correct way to write it with inheritance
  3. @Builder + inheritance — pitfalls of the Builder pattern in subclasses and the solution (@SuperBuilder)
  4. @Jacksonized + @Builder — correct configuration for Jackson deserializing Builder objects
  5. MyBatis-Plus entity annotation rules — compatibility of @Data/@Builder with MyBatis
  6. @Value — best practices for immutable objects (DTO/VO)
  7. @Builder.Default — default values are correctly preserved in Builder mode
  8. @With — "modified" copies of immutable objects

❌ Out of Scope

  1. Lombok installation and configuration → refer to the official documentation
  2. Java Records (Java 16+) → alternative for immutable data carriers

The mistakes LLMs make most often

# Mistake Correct approach
1 Subclass @Data does not write callSuper=true @EqualsAndHashCode(callSuper = true)
2 @Data + @Builder together (MyBatis entity) Entities should not use @Builder (it breaks the no-args constructor, which MyBatis needs)
3 Jackson fails to deserialize a @Builder object (no default constructor) Add the @Jacksonized annotation
4 Parent class fields do not participate in hashCode/equals Add to the subclass callSuper=true
5 Using @Builder in the subclass, parent class fields cannot be built Use @SuperBuilder instead (must be added to both parent and subclass)
6 @Builder default values are ignored (field initialization does not take effect) Use @Builder.Default to annotate fields with default values
7 DTO uses @Data(setters expose modification) Use @Value(immutable) or @Getter only
8 @Data generated toString causes circular reference StackOverflow @ToString.Exclude exclude associated fields
9 JPA entity @Data causes lazy-loading N+1 For JPA entities use @Getter @Setter + handwritten equals/hashCode
10 @AllArgsConstructor + @Builder duplicate @Builder comes with an all-args constructor, @AllArgsConstructor is not needed

Core rules quick reference

Entity objects (MyBatis/MyBatis-Plus)

// ✅ MyBatis 实体: 用 @Data,不加 @Builder
@Data
@TableName("sys_user")
public class SysUser extends BaseEntity<SysUser> {
    // ⚠️ 继承时 BaseEntity 已声明 @EqualsAndHashCode(callSuper=false)
    private String username;
    // ❌ 不要加 @Builder — MyBatis 需要无参构造器
    // ❌ 不要加 @AllArgsConstructor — @Data 已含 @RequiredArgsConstructor
}

// ✅ 如果必须用 Builder + 实体(需要加所有构造器)
@Data
@Builder
@NoArgsConstructor      // ← MyBatis 需要
@AllArgsConstructor     // ← @Builder 需要
public class UserEntity {
    private String name;
    private Integer age;
}

DTO/VO (immutable objects)

// ✅ DTO/VO — 不可变,适合 API 返回值
@Value
@Builder
@Jacksonized            // ← Jackson 反序列化支持(Lombok 1.18.14+)
public class UserDTO {
    Long id;
    String username;
    @Builder.Default Integer age = 0;  // ← 默认值必须加 @Builder.Default!
}

Inheritance + Builder

// ✅ @SuperBuilder — 继承场景的 Builder 方案
@SuperBuilder
@Data
public class Parent {
    private String parentField;
}

@SuperBuilder        // ← 父类和子类都必须加 @SuperBuilder
@Data
@EqualsAndHashCode(callSuper = true)
public class Child extends Parent {
    private String childField;
}

Precise annotations (replacing @Data)

// ✅ 精确控制: 用 @Getter @Setter 替代 @Data
@Getter
@Setter
@ToString
@EqualsAndHashCode(onlyExplicitlyIncluded = true)  // ← 只包含指定字段
public class UserEntity {
    @EqualsAndHashCode.Include
    private Long id;              // ← 只以 id 做 equals/hashCode
    private String name;
    @ToString.Exclude
    private String password;      // ← toString 中排除
}

// ✅ @With — 不可变对象的"修改"(返回新对象)
@Value
@Builder
@Jacksonized
public class OrderDTO {
    Long id;
    String status;
    
    public OrderDTO withStatus(String newStatus) {
        return new OrderDTO(this.id, newStatus);
    }
}

// ✅ @With 一行搞定(等同上方法)
@Value
@Builder
@Jacksonized
public class OrderDTO {
    Long id;
    @With String status;  // ← 自动生成 withStatus() 返回新对象
}

Logging

// ✅ @Slf4j
@Slf4j
public class UserService {
    public void doSomething() {
        log.info("处理用户: {}", userId);  // 不用写 LoggerFactory.getLogger
    }
}

Combination decision tree

需要什么?
├── 纯数据类(DTO/VO/返回值)
│   ├── 需要 Builder → @Value + @Builder + @Jacksonized
│   ├── 需要继承   → @SuperBuilder(父+子) + @Value
│   └── 简单数据   → @Value
├── JPA/Hibernate实体
│   ├── 推荐 → @Getter + @Setter + @EqualsAndHashCode(onlyExplicitlyIncluded=true)
│   └── 避免 → @Data (懒加载N+1, toString循环)
├── MyBatis/MyBatis-Plus 实体
│   ├── 无继承 → @Data
│   ├── 有继承 → @Data + @EqualsAndHashCode(callSuper=true)
│   └── 需Builder → @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor
└── 配置类/Service
    └── @Slf4j + @RequiredArgsConstructor (final字段注入)

Gotchas

  1. @Builder breaks the no-args constructor — MyBatis/JPA/Hibernate need a no-args constructor; entities should not use @Builder or should add @NoArgsConstructor
  2. @Data does not include callSuper — subclass equals/hashCode do not compare parent class fields by default; this must be declared explicitly
  3. @Jacksonized only takes effect on @Builder — not adding it will cause Jackson deserialization to fail (no default constructor)
  4. @SuperBuilder requires it to be added to all parent and subclasses — if one is missing, a compilation error occurs
  5. @Builder.Default only takes effect in builder mode — objects created with new return null from getters
  6. @Builder.Default does not affect the no-arg constructor — when created with new, field default values are Java defaults (0/null)
  7. @Slf4j generates a static field — cannot be accessed via this.log
  8. Lombok requires an IDE plugin + annotation processor — otherwise a compile-time error occurs
  9. @Data generates all getters/setters — sensitive fields (passwords, etc.) need to be manually excluded or precisely controlled with @Getter @Setter
  10. All fields of a @Value class are final — cannot have setters, cannot be lazily initialized
  11. @ToString is harmful to JPA entities — lazy-loaded fields trigger extra queries, circular references cause StackOverflow
  12. @With can only be used on non-final fields — when combined with @Value, @With fields cannot be final

Data Privacy

This skill does not collect, store, or transmit any user data.