データClassを入れ子にしてコンストラクタを使うと便利

データClassを入れ子にしてコンストラクタを使ったら大変便利でしたのでご紹介します。

コンストラクタはかなり便利です。

まずは、呼び出される側のソースコードです。

import javax.persistence.Embeddable;
import lombok.Getter;

@Embeddable
@Data
public class Sample {

  private String sampleId;
  private String samplePartId;

  public Sample() {
  }

  public Sample(String sampleId) {
    this.sampleId = sampleId;
    this.samplePartId = sampleId.substring(0, 4);
  }
}

要注意なポイントは2つあって、1つめは@Embeddableを付与すること。これが無いとエラーになります。

2つめに要注意なポイントは必要なコンストラクタの他に、デフォルトコンストラクタ(引数無しのコンストラクタ)を用意すること。これが結構ハマったのですがデフォルトコンストラクタが無いと次のようなエラーになります。

No default constructor for entity

続いて、呼び出す側のソースコードです。

import java.util.List;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.Id;

import lombok.Data;

@Entity
@Data
public class InfoUser {
  @Id
  private String userId;
  @ElementCollection
  private List<Sample> sampleId;
  private String name;
  private String email;
  private String role;
}

要注意ポイントはListには@ElementCollectionを付与すること。これが無いとエラーになります。

処理

サービスClassやコントロールClassなどからこのような感じで呼び出します。

Sample sample = new Sample("AAAAAAAA");

全体を通しての要注意ポイントはテーブルとして明示的に保存していませんがトランザクションデータがテーブルとして保存されます。

@ManyToOne, @OneToMany, mappedByを使用して明示的に保存したテーブルのみ保存することもできます。

しかし、今回はマスターデータを変更したくなかったので上記のようにトランザクションデータとして別出しする方法を選択しました。