環境
- Java 1.8.0_282
- org.springframework.boot:spring-boot-starter-data-jpa: 2.4.9
現象
以下のModelを実行すると、
@Entity
@Builder
@Table(name="sample_table")
public class SampleModel {
@Id
private Long id;
private String name;
}
以下のエラーが出る。
Caused by: org.springframework.orm.jpa.JpaSystemException: No default constructor for entity: : com.example.bot.spring.models.SampleModel; nested exception is org.hibernate.InstantiationException: No default constructor for entity: : com.example.bot.spring.models.SampleModel
No default constructor for entity とある。
原因
簡単に説明すると、
- デフォルトコンストラクタとは引数なしの空のコンストラクタのこと
-
@Builderが付与されていると、引数ありのコンストラクタが自動生成される - 既にコンストラクタが存在しているとデフォルトコンストラクタは生成されない
詳しく説明すると、今回の例で@Builderが自動生成するコンストラクタは以下。求められているのは public SampleModel() {} のような空のコンストラクタ。
@Entity
@Builder
@Table(name="sample_table")
public class SampleModel {
@Id
private Long id;
private String name;
// このようなコンストラクタを@Builderが自動生成する
public SampleModel(Long id, String name) {
this.id = id;
this.name = name;
}
}
つまり、@Builderが邪魔をしている。しかし@Builderは使いたい。
解決方法
デフォルトコンストラクタを明示的に定義し、@Tolerateを付与することで回避できる。
こうすると、デフォルトコンストラクタが既に存在していても、@Builderが引数ありのコンストラクタを生成してくれる。
@Entity
@Builder
@Table(name="sample_table")
public class SampleModel {
@Id
private Long id;
private String name;
+
+ @Tolerate
+ public TaskCommandModel() {}
}
以上