環境
- 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() {}
}
以上