JPA(Hibernate実装)で、エンティティーIDとして使用するのに適しているタイプは、ボックス型(例:Integer
)または非ボックス型(例:int
)ですか?
プログラムで新しいエンティティを作成すると、HibernateはIDがnull
であることを認識し、データベースに新しい行を作成する必要があることを理解しているため(IDがそうでない場合とは対照的に) null
Hibernateはデータベースの既存の行を更新する場合があります)。
しかし、私のエンティティのIDはint
であり、エラーなく正常に機能し、プリミティブインスタンス変数のデフォルト値は0
であることがわかっています。そのため、彼は、おそらく休止状態が0
を特別なものとして扱い、オブジェクトが新しいものであると想定していると述べました。
まあ、私たちは非プリミティブを使用しており、それには大きな理由があります。たとえば、int/Integer
である多くのフィールドは、完全に有効であるためにzero
の絶対的なビジネス値を持っています。たとえば、借金フィールドについて考えてみましょう。フィールドがzero
である場合は問題ありません。つまり、借金がないことを意味します。
問題は、プリミティブの場合、ゼロがデフォルト値であることです。たとえば、誤ってsetDebt
を介して設定することを忘れる可能性があります。つまり、might絶対にしない値でデータベースに到達しますそこに行くつもりでした。このため、たとえばInteger
を使用して、たとえばnullにしてはならない検証をいくつか行います。しかし、適切な検証を追加し忘れた場合でも、そのコードはNullPointerException
でbreakを使用して(できればテストで)可能性があり、データベース内の値の一貫性よりも例外が好きです。
現在のドキュメントボックス化されたタイプを使用することをお勧めします。
永続クラスで一貫した名前の識別子属性を宣言し、null許容(つまり、プリミティブでない)型を使用することをお勧めします。
エンティティIDのプリミティブ(例:int)とそのラッパー(例:Integer)の間に違いはありません。どちらもJPA仕様に従って有効です。 JPAプロバイダーは、エンティティーの状態とライフサイクルを追跡するのに十分スマートです。エンティティIDが0(プリミティブタイプ)またはNULL(ラッパータイプ)の場合、IDジェネレーターが構成されていれば、JPAプロバイダーはエンティティのIDを生成します。 idが自動生成される場合、ゼロは有効なエンティティIDとは見なされません。
両方のケースをCmobilecom JPA
でテストしましたが、同じように機能します。もちろん、パフォーマンスの違いに気付くことはありません。
免責事項:私は Cmobilecom JPA の開発者です。JavaとAndroidの両方の軽量JPA実装です。
ジェネリックでBoxed Typeを柔軟に使用できるため、エンティティモデルではBoxed Typeを使用します。たとえば、ここでのエンティティモデルは、IDのSerializableに拡張されるタイプのみを持つことができます。これは、主キーに対してさまざまな操作を実行できるサービス層で後で役立ちます。
public interface BaseEntity<E extends Serializable> extends Serializable {
E getId();
}
エンティティモデルは次のようになります。
@Entity
public class PhoneNumber implements BaseEntity<Long> {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "PHONE_NUMBER_ID")
private Long id;
エンティティとコレクションの一意の識別子は、バイナリ、blob、およびclobを除く任意の基本的なタイプにすることができます。 (複合識別子も許可されています。以下を参照してください。)
基本的な値の型には、org.hibernate.Hibernateで定義された対応するType定数があります。たとえば、Hibernate.STRINGは文字列型を表します。