こんにちは、かつコーチです。
EntityやDTOを作るたびに、getter・setter・コンストラクタを手打ちしていて「これ絶対もっと楽にできるはず」と感じたことはありませんか。
Lombokとは、アノテーションを付けるだけでgetter・setter・コンストラクタなどの定型コードを自動生成してくれるライブラリです。
今回は、Lombokの導入方法とよく使うアノテーション、そして導入時につまずきやすいポイントを解説します。
Lombokとは何か
定型コードが多くなる問題
Spring BootでEntityやDTOを作ると、フィールドの数だけgetter・setterが必要になり、コードがどんどん長くなっていきます。
// Lombokなしの場合
public class Book {
private Long id;
private String title;
private int price;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public int getPrice() { return price; }
public void setPrice(int price) { this.price = price; }
}
フィールドが3つだけでもこの分量で、実際のプロジェクトでは10個以上のフィールドを持つクラスも珍しくありません。
Lombokが解決すること
Lombokは、コンパイル時にアノテーションを解析して、これらの定型コードを自動生成してくれます。
// Lombokありの場合
@Getter
@Setter
public class Book {
private Long id;
private String title;
private int price;
}
見た目上はgetter・setterが消えていますが、コンパイルされたクラスファイルには通常どおり生成されているため、呼び出し側のコードは一切変わりません。
Lombokの導入方法
依存関係の追加
build.gradleに以下を追加します。
dependencies {
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testCompileOnly 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
}
compileOnlyとannotationProcessorの両方が必要な点に注意してください。
IDEへのプラグイン導入
Lombokはコンパイル時にコードを生成する仕組みのため、IntelliJ IDEAなどのIDE上で赤線(エラー)が表示されてしまうことがあります。
IntelliJ IDEAの場合は「Settings → Plugins」からLombokプラグインをインストールし、「Settings → Build → Annotation Processors」で「Enable annotation processing」にチェックを入れる必要があります。
これを忘れると、ビルドは通るのにIDE上ではgetterが「見つからない」というエラー表示が消えず、混乱の原因になります。
よく使うアノテーション
@Getter・@Setter
フィールドまたはクラス全体にgetter・setterを自動生成します。
@Getter
@Setter
public class Book {
private Long id;
private String title;
}
@ToString・@EqualsAndHashCode
デバッグ時に便利なtoString()や、値の比較に使うequals()・hashCode()も自動生成できます。
@Getter
@Setter
@ToString
@EqualsAndHashCode
public class Book {
private Long id;
private String title;
}
@NoArgsConstructor・@AllArgsConstructor
引数なしコンストラクタ、全フィールドを引数に取るコンストラクタをそれぞれ生成します。
@NoArgsConstructor
@AllArgsConstructor
public class Book {
private Long id;
private String title;
}
前回の記事で触れたとおり、JPAのEntityには引数なしコンストラクタが必須なので、@NoArgsConstructorは特に使う機会が多いアノテーションです。
@Data:まとめて楽をする
@Getter・@Setter・@ToString・@EqualsAndHashCode・@RequiredArgsConstructorをまとめて付与してくれるのが@Dataです。
@Data
public class BookDto {
private Long id;
private String title;
private int price;
}
DTOのようにシンプルなクラスでは@Data1つで十分なケースが多く、僕自身もDTOには基本的に@Dataを使っています。
ただしEntityに@Dataを使うと、@EqualsAndHashCodeが全フィールドを比較対象にしてしまい、JPAのリレーション先を巻き込んで無限ループを起こすことがあるため注意が必要です。
つまずきやすいポイント
EntityへのToStringが原因の無限ループ
❌ Before:双方向関連を持つEntityに@Dataを付ける
@Data
@Entity
public class Author {
@Id
private Long id;
private String name;
@OneToMany(mappedBy = "author")
private List<Book> books;
}
@Data
@Entity
public class Book {
@Id
private Long id;
private String title;
@ManyToOne
private Author author;
}
このコードでBookをログに出力しようとすると、次のようなエラーで実行時にスタックオーバーフローが発生します。
Exception in thread "main" java.lang.StackOverflowError
at com.example.demo.entity.Author.toString(Author.java:1)
at com.example.demo.entity.Book.toString(Book.java:1)
at com.example.demo.entity.Author.toString(Author.java:1)
BookのtoString()がAuthorを呼び出し、AuthorのtoString()がまたBook一覧を呼び出す、という無限ループに陥っているのが原因です。
✅ After:関連フィールドをtoString対象から除外する
@Getter
@Setter
@ToString(exclude = "author")
@Entity
public class Book {
@Id
private Long id;
private String title;
@ManyToOne
private Author author;
}
Entityには@Dataを安易に使わず、必要なアノテーションを個別に組み合わせて、関連フィールドはexcludeで明示的に除外するのが安全です。
応用・一歩先の使い方
@Builderでオブジェクト生成を読みやすくする
コンストラクタの引数が増えてくると、どの値がどの引数か分かりにくくなります。
@Builderを使うと、メソッドチェーン形式で値を指定できるため可読性が上がります。
@Getter
@Builder
public class BookDto {
private String title;
private int price;
}
BookDto dto = BookDto.builder()
.title("Spring入門")
.price(2800)
.build();
DTOを組み立てるコードが多いサービスクラスでは、@Builderを使うだけでレビュー時の可読性が大きく変わります。
まとめ
この記事のポイント
- Lombokはgetter・setter・コンストラクタ等をアノテーションで自動生成するライブラリ
- 導入には依存関係の追加とIDEのプラグイン設定の両方が必要
- DTOには
@Dataが便利だが、双方向関連を持つEntityでは無限ループの原因になるため避ける - Entityでは
@ToString(exclude = "...")で関連フィールドを除外する @BuilderはDTO組み立て時の可読性を上げてくれる
次に読むべき記事
- Spring Data JPAの基本とEntityの定義
- @OneToMany・@ManyToOneでリレーションを組む
- SLF4Jでログ出力を整える
タグ: Spring Boot, 初心者向け, エラー解決