[解決済み] Lombokの@BuilderとJPAのデフォルトコンストラクタ
質問
Spring Data JPAと一緒にLombokプロジェクトを使っています。
LombokとSpring Data JPAを接続する方法はありますか?
@Builder
をJPAのデフォルトコンストラクタに接続する方法はありますか?
コードです。
@Entity
@Builder
class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
}
私の知る限り、JPAはデフォルトのコンストラクタを必要とし、それは
@Builder
アノテーションで上書きされます。そのためのワークアラウンドはありますか?
このコードは私にエラーを与える。
org.hibernate.InstantiationException: No default constructor for entity: : app.domain.model.Person
どのように解決するのですか?
更新
フィードバックと John の
回答
を使用しないよう、回答を更新しました。
@Tolerate
または
@Data
で、代わりにアクセッサとミューテータを
@Getter
と
@Setter
で、デフォルトのコンストラクタを作成します。
@NoArgsConstructor
そして最後に、ビルダーが要求するすべての引数のコンストラクタを
@AllArgsConstructor
.
ビルダーパターンを使用したいので、コンストラクタとミューテータのメソッドの可視性を制限したいのだと思います。
これを実現するために、可視性を
package private
を介して
access
属性で
@NoArgsConstructor
と
@AllArgsConstructor
アノテーションと
value
属性は
@Setter
アノテーションを使用します。
重要な
を適切にオーバーライドすることを忘れないでください。
toString
,
equals
そして
hashCode
.
詳しくはVlad Mihalcea氏による以下の投稿をご覧ください。
- the-best-way to implement-equals-hashcode-and-tostring-with-jpa-and-hibernate (ベストウエイトゥーインプリメントイコールハッシュコードアンドトストリングウィズジャパアンドヒバーネイト)
- 等号とハッシュコードの実装方法-jpa-エンティティ識別子を使用する方法
- hibernate-facts-equals-and-hashcode (ハイバーネート・ファクト・イコールズ・アンド・ハッシュコード)
package com.stackoverflow.SO34299054;
import static org.junit.Assert.*;
import java.util.Random;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import org.junit.Test;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@SuppressWarnings("javadoc")
public class Answer {
@Entity
@Builder(toBuilder = true)
@AllArgsConstructor(access = AccessLevel.PACKAGE)
@NoArgsConstructor(access = AccessLevel.PACKAGE)
@Setter(value = AccessLevel.PACKAGE)
@Getter
public static class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
/*
* IMPORTANT:
* Set toString, equals, and hashCode as described in these
* documents:
* - https://vladmihalcea.com/the-best-way-to-implement-equals-hashcode-and-tostring-with-jpa-and-hibernate/
* - https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/
* - https://vladmihalcea.com/hibernate-facts-equals-and-hashcode/
*/
}
/**
* Test person builder.
*/
@Test
public void testPersonBuilder() {
final Long expectedId = new Random().nextLong();
final Person fromBuilder = Person.builder()
.id(expectedId)
.build();
assertEquals(expectedId, fromBuilder.getId());
}
/**
* Test person constructor.
*/
@Test
public void testPersonConstructor() {
final Long expectedId = new Random().nextLong();
final Person fromNoArgConstructor = new Person();
fromNoArgConstructor.setId(expectedId);
assertEquals(expectedId, fromNoArgConstructor.getId());
}
}
旧バージョンの使用
@Tolerate
と
@Data
:
使用方法
@Tolerate
を使うことで、noargコンストラクタを追加できるようになりました。
ビルダーパターンを使用したいので、セッターメソッドの可視性を制御したいのだと思います。
そのため
@Data
アノテーションは、生成されたセッターを
public
を適用します。
@Setter(value = AccessLevel.PROTECTED)
を適用すると、フィールドは
protected
.
を適切にオーバーライドすることを忘れないでください。
toString
,
equals
そして
hashCode
.
詳しくはVlad Mihalcea氏による以下の投稿をご覧ください。
- the-best-way to implement-equals-hashcode-and-tostring-with-jpa-and-hibernate (ベストウエイトゥーインプリメントイコールハッシュコードアンドトストリングウィズジャパアンドヒバーネイト)
- 等号とハッシュコードの実装方法-jpa-エンティティ識別子を使用する方法
- hibernate-facts-equals-and-hashcode (ハイバーネート・ファクト・イコールズ・アンド・ハッシュコード)
package lombok.javac.handlers.stackoverflow;
import static org.junit.Assert.*;
import java.util.Random;
import javax.persistence.GenerationType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.Setter;
import lombok.experimental.Tolerate;
import org.junit.Test;
public class So34241718 {
@Builder
@Data
public static class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Setter(value = AccessLevel.PROTECTED)
Long id;
@Tolerate
Person() {}
/* IMPORTANT:
Override toString, equals, and hashCode as described in these
documents:
- https://vladmihalcea.com/the-best-way-to-implement-equals-hashcode-and-tostring-with-jpa-and-hibernate/
- https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/
- https://vladmihalcea.com/hibernate-facts-equals-and-hashcode/
*/
}
@Test
public void testPersonBuilder() {
Long expectedId = new Random().nextLong();
final Person fromBuilder = Person.builder()
.id(expectedId)
.build();
assertEquals(expectedId, fromBuilder.getId());
}
@Test
public void testPersonConstructor() {
Long expectedId = new Random().nextLong();
final Person fromNoArgConstructor = new Person();
fromNoArgConstructor .setId(expectedId);
assertEquals(expectedId, fromNoArgConstructor.getId());
}
}
関連
-
[解決済み] Spring Data JPAにおけるCrudRepositoryとJpaRepositoryのインターフェースの違いは何ですか?
-
Junitのユニットテストはjava.lang.Testを報告します。
-
ecplise プロンプトが表示されます。"選択したものは起動できません。" "最近の起動はありません。"
-
Java JDKのダイナミックプロキシ(AOP)の使用と実装の原理分析
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Javaにおけるpublic、protected、package-private、privateの違いは何ですか?
-
[解決済み] serialVersionUIDとは何ですか、またなぜそれを使用する必要がありますか?
-
[解決済み] Java で、あるコンストラクタを別のコンストラクタから呼び出すにはどうすればよいですか?
-
[解決済み] Javaで配列を宣言し、初期化する方法は?
-
[解決済み] Javaはパラメータのデフォルト値をサポートしていますか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Eclipse問題 アクセス制限。タイプ 'SunJCE' が API でないことを解決し、/jdk ディレクトリにある /jre と jre の違いについて理解を深める。
-
executeQuery()でデータ操作文が発行できない。解決方法
-
java.sql.SQLException: executeQuery()でデータ操作文を発行できません。
-
スレッド "main" での例外 java.lang.ArrayIndexOutOfBoundsException:5 エラー
-
Uncaught ReferenceError: は定義されていません。
-
Javaがテキストファイルを読み込む
-
XXX型を囲むインスタンスがJavaでアクセスできない
-
Javaがリソースリークに遭遇した:'input'が閉じない 解決方法
-
eclipse にリソースリーク:'in' が閉じない
-
Spring Bootは、Tomcatの組み込みのmaxPostSizeの値を設定します。