LoginSignup
0
0

More than 1 year has passed since last update.

エンティティを不変(イミュータブル)にする実装

Posted at

はじめに

SpringBootのエンティティは便利だが、可変(ミュータブル)な実装になりがちなので、
不変(イミュータブル)にできないか検討する。

ありがちな実装

  • エンティティ
@Entity
@Table(name = "company")
@Getter
@Setter
public class Company {

    @Id
    private String companyId;
    private String companyName;
}
  • 呼び出し元
Company company = new Company();

晴れて、生焼けオブジェクトのできあがり!!
変数companyがどのような状態かよく分からない。。
この状態を避けるために、Companyエンティティを不変にしてみる。

エンティティの制約

エンティティには、引数を持たないコンストラクタが必要。
引数を持たないコンストラクタが存在しないと、
リポジトリのfindByIdとか実行すると、下記のように例外が発生する。

org.hibernate.InstantiationException: No default constructor for entity:  : ~~~

引数を持たなければアクセス修飾子は何でもよく、privateでも実行できる。
試しにprivateな引数なしのコンストラクタにブレークポイントを設定したところ、
下記のようにリフレクションで呼ばれていることが確認できる。

image.png

リフレクションでsetAccessible(true)をされたらどうしようも無いが、
こればかりは諦める。

実装例

@Setterを削除し、privateな引数なしコンストラクタと、引数ありコンストラクタを用意。
フィールドが多くなると引数渡しは呼び出し元がツライため、ビルダーにした。

  • エンティティ
@Entity
@Table(name = "company")
@Getter
public class Company {

    @Id
    private String companyId;
    private String companyName;

    private Company() {}

    private Company(final String companyId, final String companyName) {
        this.companyId = companyId;
        this.companyName = companyName;
    }

    public static class CompanyBuilder {

        private String companyId;
        private String companyName;

        public CompanyBuilder companyId(final String companyId) {
            this.companyId = companyId;
            return this;
        }

        public CompanyBuilder companyName(final String companyName) {
            this.companyName = companyName;
            return this;
        }

        public Company build() {
            return new Company(companyId, companyName);
        }
    }
}
  • 呼び出し元
Company company = new CompanyBuilder()
                        .companyId("12345")
                        .companyName("株式会社ほげ")
                        .build();

最後に

もっといい実装方法があれば教えてください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0