| この記事の要点 |
|
本稿は Spring Framework(Spring Boot)の開発でよく使われる @Data について説明します。
@Data とは
@Data は Lombok のアノテーションで、以下のアノテーションをすべて付けることと同義です。
| アノテーション | 生成されるもの |
|---|---|
| @Getter | すべてのフィールドの getter(getName()、boolean なら isActive()) |
| @Setter | final でないすべてのフィールドの setter |
| @ToString | 全フィールドを含む toString() |
| @EqualsAndHashCode | 全フィールド(static と transient を除く)を比較する equals() と hashCode() |
| @RequiredArgsConstructor | final フィールドと @NonNull フィールドを引数に取るコンストラクタ |
Lombok はコンパイル時にアノテーションを読み取り、これらのメソッドをクラスファイルに直接追加します。ソースコード上には現れませんが、普通に customer.getCustomerId() のように呼び出せます。
使用例
以下、JPA のエンティティに付けたサンプルです(Spring Boot 3 以降は javax.persistence ではなく jakarta.persistence を使います)。
package com.sample.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Data;
@Data
@Entity
@Table(name="CUSTOMER")
public class Customer {
@Id
@Column
private String customer_id;
....
}
@Data を付けない場合、同じことをするにはフィールドごとの getter / setter に加えて、toString、equals、hashCode を手で書く必要があり、フィールドが 10 個あれば 100 行を超えることも珍しくありません。
DTO(画面やAPI とのデータの受け渡し用クラス)であれば、@Data は特に便利です。
@Data
public class CustomerForm {
private String name;
private String email;
private Integer age;
}
CustomerForm form = new CustomerForm();
form.setName("山田");
System.out.println(form); // CustomerForm(name=山田, email=null, age=null)
導入方法
Spring Initializr でプロジェクトを作る場合は、依存関係で「Lombok」を選ぶだけです。既存のプロジェクトに追加する場合は次のように書きます。Spring Boot を使っていればバージョンは Spring Boot 側で管理されるので省略できます。
<!-- Maven (pom.xml) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
// Gradle (build.gradle)
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
IDE 側の対応も必要です。IntelliJ IDEA は Lombok プラグインが標準で同梱されており、「Annotation Processing」を有効にします。Eclipse / Spring Tool Suite は Lombok の jar を実行してインストーラーで IDE に組み込みます。IDE が対応していないと、コンパイルは通るのにエディタ上で「getter が無い」というエラー表示が出ます。
注意点・落とし穴
JPA エンティティに @Data を付ける問題
@Data は手軽ですが、JPA(Hibernate)のエンティティに付けると次の問題が起きることがあります。
- 双方向の関連で StackOverflowError: 親が子のリスト、子が親を持つ関係で、toString や hashCode が互いを呼び合い無限に再帰する
- LazyInitializationException: toString や equals が遅延読み込みの関連フィールドにアクセスし、トランザクション外だと例外になる。また、ログ出力しただけで想定外の SQL が大量に発行されることもある
- equals / hashCode が変わる: 全フィールドで比較するため、保存前後で ID が変わったり値を更新したりすると、HashSet に入れたエンティティが見つからなくなる
エンティティでは、@Data の代わりに必要なものだけを付け、関連フィールドを toString から除外するのが一般的です。
@Entity
@Getter
@Setter
@NoArgsConstructor
@ToString(exclude = "orders")
public class Customer {
@Id
private Long id;
private String name;
@OneToMany(mappedBy = "customer")
private List<Order> orders;
}
その他の注意点
- コンストラクタ: @RequiredArgsConstructor は final フィールドが無ければ引数なしのコンストラクタになります。final フィールドがあると引数なしコンストラクタが無くなり、JPA や JSON ライブラリが必要とするデフォルトコンストラクタが不足することがあります。その場合は @NoArgsConstructor を併用します。また、自分でコンストラクタを書いたクラスでは @Data によるコンストラクタは生成されません
- 継承: 親クラスを持つクラスでは、生成される equals / hashCode に親のフィールドが含まれません。必要なら
@EqualsAndHashCode(callSuper = true)を指定します - 不変オブジェクト: setter を作らない読み取り専用のクラスには @Value を使います。Java 16 以降なら、単純なデータの入れ物は record で書くこともできます
- パスワードなどの機密項目: toString に含まれるとログに出力されてしまうため、
@ToString.Excludeを付けて除外します
生成内容の確認方法
Lombok が実際にどんなコードを生成したかは、IDE のアウトライン(構造)表示でメソッド一覧を見るか、delombok ツールで展開後のソースを出力すると確認できます。コンパイル後のクラスに対して javap -p Customer.class を実行してメソッド一覧を見る方法もあります。
関連
- 【Spring Boot (JPA編)】DB 接続設定からエンティティおよびリポジトリの作成、値の取得まで
- Hibernate とは|Java の ORM ライブラリの基礎
- Java String.equals の使い方|== との違い・null 回避・Objects.equals
- Java クラス完全ガイド
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- プロジェクトをTomcatプロジェクトとして認識させる方法 2026-10-07 22:32:50
- MySQLの1366 Incorrect string value|Laravelの文字コード・絵文字エラー 2026-10-07 21:54:03
- curlの証明書ホスト名不一致|旧エラー51・現行60の確認と対処 2026-10-07 21:54:03
- LaravelのMassAssignmentException|fillableの原因と安全な対処 2026-10-07 21:54:03
- Eclipse で Tomcat の起動ログがコンソールに出ない時の確認手順 2026-10-07 21:54:02
- MySQLにおける中央値(Median)の導き方(バージョン8未満) 2026-10-07 13:49:45
- getInputForward 2026-10-07 13:41:15
- JSONから配列に変換 2026-10-07 13:41:15
- ビューから値をモデルに格納しコントローラーで受け取る方法 2026-10-07 13:23:41
- Laravelのテーブル作成と定義変更|マイグレーション・up/down・注意点 2026-10-07 13:23:41
- NumPy 配列に要素を追加する方法 (append / concatenate) 2026-10-07 13:23:41
- MariaDB・MySQLで現在日時を取得する方法|NOW・タイムゾーン・保存型 2026-10-07 13:13:36
- 【django】テンプレートで定数を使用する方法 2026-10-07 13:10:15
- Spring BootにおけるApplication.propertiesの環境依存設定の分割方法 2026-10-07 12:09:35
- Not supported for DML operations【Springエラー】 2026-10-07 11:09:38