JPA を使用する場合、デフォルトのコンストラクターを空にする必要がありますか? JPA が内部でどのように機能するのか手がかりがないので、デフォルトのコンストラクターが属性にデフォルト値を入力するなどの独自の処理を行うと、オブジェクトが JPA によって誤って初期化される可能性があるのではないかと心配しています。
ありがとう。
JPA を使用する場合、デフォルトのコンストラクターを空にする必要がありますか? JPA が内部でどのように機能するのか手がかりがないので、デフォルトのコンストラクターが属性にデフォルト値を入力するなどの独自の処理を行うと、オブジェクトが JPA によって誤って初期化される可能性があるのではないかと心配しています。
ありがとう。
JPA による実行時のオーバーヘッドを最小限に抑えながら、ユーザー コードで新しいインスタンスを作成するときに制約を適用するには、次のようにします。
短い答えはノーです。空である必要はありません。
ただし、JPA 実装が永続性からインスタンスを具体化する場合、引数なしのコンストラクターが完了した後にインスタンスに対して処理を行うことに注意する必要があります。これにより、コンストラクターが行ったことが取り消される可能性があります。
コンストラクターを空にする必要があるかどうかを理解するには、コンストラクターが 2 つのシナリオで呼び出されることを考慮する必要があります。
「新しい」オブジェクトを作成する場合、コンストラクターは、通常のコードで使用できるように十分に初期化されたオブジェクトを生成する必要があります。デフォルト以外の状態に初期化する必要があるフィールドを処理する必要があります。
JPA が永続ストアからオブジェクトを実体化するとき、実体化は新しく構築されたインスタンスの「詳細を埋める」ことになります。これは通常、構築されたオブジェクトのオブジェクト状態を上書きします。
もちろん、引数なしのコンストラクターを直接使用しないようにコードを設計することもできます。これは、最初のシナリオを無意味にし、発生する可能性のある無駄な「二重初期化」も無意味にします。
より長い答えは、ほとんどの場合、空であってはならないということです。たとえば、次のエンティティを想像してください。
@Entity
public class Team {
@Id
private Long id;
@OneToMany
private Set<Player> players;
// getters
}
インスタンスが JPA によってロードされると、プレイヤー セットが null になることはありません。空にすることはできますが、null にすることはできません。ただし、新しいチームを作成する場合、または単体テストでチーム インスタンスを使用する場合は、この不変条件も確保する必要があります。したがって、クラスは次のように記述する必要があります
@Entity
public class Team {
@Id
private Long id;
@OneToMany
private Set<Player> players = new HashSet<Player>(0);
// getters
}
これはと同等です
@Entity
public class Team {
@Id
private Long id;
@OneToMany
private Set<Player> players;
public Team() {
this.players = new HashSet<Player>(0);
}
// getters
}