Claude-skill-registry lombok-patterns
Lombok annotations and best practices for Java 21+ projects. Use when reducing boilerplate, configuring builders, or choosing between Lombok and Records.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/lombok-patterns" ~/.claude/skills/majiayu000-claude-skill-registry-lombok-patterns && rm -rf "$T"
manifest:
skills/data/lombok-patterns/SKILL.mdsource content
Lombok Patterns
This skill provides guidance on using Project Lombok to reduce boilerplate code in Java applications, covering annotations, best practices, and integration patterns.
Note: This guide targets Java 21+ projects. Some Lombok features are now obsolete due to modern Java features (Records,
, try-with-resources). See Java 21+ Considerations below.var
Overview
Lombok is a Java library that automatically generates common code like getters, setters, constructors, builders, and more during compilation. It helps create cleaner, more maintainable code.
Java 21+ Considerations
Some Lombok features are now redundant with modern Java:
| Lombok Feature | Java Alternative | Recommendation |
|---|---|---|
/ | (Java 10+) | Use Java |
| (Java 16+) | Prefer records for simple value objects |
| (Java 16+) | Prefer records for simple DTOs |
| try-with-resources (Java 7+) | Use try-with-resources |
| wither methods | Records can define wither methods |
When Lombok Still Adds Value
- JPA Entities: Records don't work with JPA (need no-arg constructor, mutable state)
: Records don't have built-in builder support@Builder
: No Java equivalent for logger generation@Slf4j
: Useful for Spring dependency injection@RequiredArgsConstructor- Inheritance: Records can't extend classes
Annotation Categories
Core Annotations (Still Valuable)
| Annotation | Purpose | Use Case |
|---|---|---|
/ | Accessor methods | JPA entities, mutable classes |
| No-argument constructor | JPA entities, serialization |
| All-fields constructor | Dependency injection |
| Constructor for final/@NonNull fields | Spring services |
| Builder pattern implementation | Complex object construction |
Consider Java Records Instead
| Lombok | Use Java Record When |
|---|---|
| Simple immutable data carriers |
| Simple DTOs without inheritance |
// ✅ Prefer Java Record for simple value objects public record Money(BigDecimal amount, String currency) {} // ✅ Prefer Java Record for simple DTOs public record CustomerDTO(String name, String email) {} // ✅ Use Lombok for JPA entities (records don't work with JPA) @Entity @Getter @Setter @NoArgsConstructor public class Customer { @Id private Long id; private String name; }
Logging Annotations
| Annotation | Logger Type |
|---|---|
| SLF4J (recommended) |
| Log4j 2 |
| java.util.logging |
| Apache Commons Logging |
Field & Method Annotations
| Annotation | Purpose |
|---|---|
| Null checks on parameters/fields |
| Immutable setters (creates new instance) |
| Throw checked exceptions without declaration |
| Thread-safe method synchronization |
| Customizable toString() generation |
| Customizable equals/hashCode |
Quick Reference
JPA Entities (Lombok Recommended)
@Entity @Getter @Setter @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(onlyExplicitlyIncluded = true) public class Product { @Id @EqualsAndHashCode.Include private Long id; private String name; private BigDecimal price; }
Spring Services
@Service @RequiredArgsConstructor @Slf4j public class OrderService { private final OrderRepository orderRepository; private final PaymentService paymentService; public Order process(Order order) { log.info("Processing order: {}", order.getId()); return orderRepository.save(order); } }
Builder Pattern (Lombok Adds Value)
// Records don't have builder support - use Lombok @Builder public record Email( String to, String subject, String body, @Singular List<String> attachments ) {} // Usage Email email = Email.builder() .to("user@example.com") .subject("Hello") .body("Content") .attachment("file1.pdf") .build();
Best Practices
✅ Do
- Use Java Records for simple value objects and DTOs
- Use
with@RequiredArgsConstructor
fields for dependency injectionfinal - Use
for logging instead of manual logger creation@Slf4j - Use
for classes with many optional fields@Builder - Be explicit with
on JPA entities@EqualsAndHashCode
❌ Avoid
- Using
or@Data
when a Java Record would suffice@Value - Using
on JPA entities (use individual annotations)@Data - Using
with lazy-loaded JPA relationships@EqualsAndHashCode - Overusing
(makes exception handling unclear)@SneakyThrows
Common Pitfalls
| Pitfall | Problem | Solution |
|---|---|---|
on entities | Includes mutable setters, problematic equals/hashCode | Use , , explicit |
Missing | JPA/Jackson need no-arg constructor | Always add with |
Circular | StackOverflow with bidirectional relationships | Use on one side |
| Using Lombok for simple DTOs | Adds unnecessary dependency | Use Java Records instead |
Cookbook Index
Core Annotations
- data-annotation -
(consider Records instead)@Data - value-annotation -
(consider Records instead)@Value - getter-setter -
and@Getter@Setter - constructor-annotations - Constructor generation
- builder-annotation - Builder pattern with
@Builder - logging-annotations - Logger generation
Field & Method Annotations
- non-null - Null checking with
@NonNull - with-annotation - Immutable setters with
@With - sneaky-throws - Checked exception handling
- synchronized-annotation - Thread safety
Integration Patterns
- entity-patterns - JPA/Hibernate best practices
- equals-hashcode-jpa - Entity identity
- dependency-injection - Spring constructor injection
- configuration-properties - Spring Boot configuration