JPAエンティティに少なくとも1つの空のコンストラクターとパブリックセッターを持たせるという要件は好きではありません。EntityManager 側の問題は理解していますが、これによりクラスの不変条件が無効になります。
誰かがこれに対する解決策を持っていますか(デザインパターンまたはイディオムレベル)?
ありがとう!
イゴール
JPAエンティティに少なくとも1つの空のコンストラクターとパブリックセッターを持たせるという要件は好きではありません。EntityManager 側の問題は理解していますが、これによりクラスの不変条件が無効になります。
誰かがこれに対する解決策を持っていますか(デザインパターンまたはイディオムレベル)?
ありがとう!
イゴール
JPA では、デフォルトのコンストラクターが必要ですが、セッターを使用する必要はありません。注釈を配置する場所に基づいて、プロパティ アクセス戦略 (フィールドまたはメソッド) を選択できます。
次のコードは直接フィールド アクセスを使用し、setter なしでエンティティの一部として機能します。
@Column(name = DESCRIPTION)
private String description;
public String getDescription() { return description; }
セッターを使用したメソッド アクセスとの比較:
private String description;
@Column(name = DESCRIPTION)
public void setDescription(String description) {
this.description = description;
}
public String getDescription() { return description; }
実際には、引数なしのコンストラクターと getter および setter メソッドの両方が必要です。要件は、仕様のセクション 2.1 に示されています。
引数なしのコンストラクターの要件は、私のコピーの 17 ページにあります。
エンティティ クラスには、引数なしのコンストラクターが必要です。エンティティ クラスには、他のコンストラクタもある場合があります。引数のないコンストラクターは、パブリックまたは保護されている必要があります。
ページ 18 には、アクセサ メソッドの要件があります。
エンティティの永続的な状態は、JavaBeans プロパティに対応するインスタンス変数によって表されます。インスタンス変数は、エンティティ インスタンス自体によってエンティティのメソッド内からのみ直接アクセスできます。エンティティのクライアントがインスタンス変数にアクセスしてはなりません。エンティティの状態は、エンティティのアクセサ メソッド (getter/setter メソッド) またはその他のビジネス メソッドを介してのみクライアントに提供されます。インスタンス変数は、プライベート、保護、またはパッケージの可視性である必要があります。
フィールド アクセスとプロパティ アクセスは、クライアント アプリケーションがエンティティと対話する方法ではなく、JPA プロバイダーがエンティティと対話する方法を示します。クライアントは常に get メソッドと set メソッドを使用する必要があります。
一部の JPA プロバイダーはこれらの要件に対してより寛大であり、特定のベンダーでコンストラクターを非公開にすることができる場合があります (上記で提案されているように)。ただし、アプリケーションは移植可能ではない可能性があるため、将来移行する場合は驚くかもしれません.
したがって、メソッドを完全に省略することはお勧めしません。この問題を解決するために、public no-arg ctor を非推奨としてマークします (JPA プロバイダー専用であることについて Javadoc に何かを記載します)。set メソッドには、不変条件を維持するロジックを含めることができます。
理想的ではありませんが、間違った ctor が誤って使用されるのを防ぐ必要があります (不変条件を設定する ctor があると仮定しています)。
OpenJPAは、エンティティーの拡張の一部として引数なしのコンストラクターを追加できます。
明確にするために、この要件はJPA仕様で義務付けられています。前の回答は、引数なしのコンストラクターをプライベートにすることができると言っていますが、それは仕様に準拠していません(リンクがHibernate固有のページを指していることがわかります)。仕様では、エンティティにはパブリックまたは保護された引数なしのコンストラクターが必要であると規定されています。
-リック
DataNucleus を使用すると、デフォルトのコンストラクターを追加したくない場合でも追加する必要はありません。バイトコード拡張によって自動的に追加されます。また、プロパティの代わりにフィールドを永続化できるため、パブリック セッターは必要ありません。
-- アンディ ( DataNucleus )
はい、プロパティの代わりにフィールドを永続化しますが、デフォルトのコンストラクターが必要ない場合は、通常 (バイトコードエンハンサーが何らかのトリックを行わない限り)、それから逃れることはできません。
jpa 実装でクラスをインスタンス化できるようにする必要があるため、パブリックのデフォルト コンストラクターが必須です。