web-dev-qa-db-ja.com

エンティティIDとしてのボックス型とプリミティブ型

JPA(Hibernate実装)で、エンティティーIDとして使用するのに適しているタイプは、ボックス型(例:Integer)または非ボックス型(例:int)ですか?

プログラムで新しいエンティティを作成すると、HibernateはIDがnullであることを認識し、データベースに新しい行を作成する必要があることを理解しているため(IDがそうでない場合とは対照的に) null Hibernateはデータベースの既存の行を更新する場合があります)。

しかし、私のエンティティのIDはintであり、エラーなく正常に機能し、プリミティブインスタンス変数のデフォルト値は0であることがわかっています。そのため、彼は、おそらく休止状態が0を特別なものとして扱い、オブジェクトが新しいものであると想定していると述べました。

23
Mahozad

まあ、私たちは非プリミティブを使用しており、それには大きな理由があります。たとえば、int/Integerである多くのフィールドは、完全に有効であるためにzeroの絶対的なビジネス値を持っています。たとえば、借金フィールドについて考えてみましょう。フィールドがzeroである場合は問題ありません。つまり、借金がないことを意味します。

問題は、プリミティブの場合、ゼロがデフォルト値であることです。たとえば、誤ってsetDebtを介して設定することを忘れる可能性があります。つまり、might絶対にしない値でデータベースに到達しますそこに行くつもりでした。このため、たとえばIntegerを使用して、たとえばnullにしてはならない検証をいくつか行います。しかし、適切な検証を追加し忘れた場合でも、そのコードはNullPointerExceptionbreakを使用して(できればテストで)可能性があり、データベース内の値の一貫性よりも例外が好きです。

7
Eugene

現在のドキュメントボックス化されたタイプを使用することをお勧めします

永続クラスで一貫した名前の識別子属性を宣言し、null許容(つまり、プリミティブでない)型を使用することをお勧めします。

10
gtgaxiola

エンティティIDのプリミティブ(例:int)とそのラッパー(例:Integer)の間に違いはありません。どちらもJPA仕様に従って有効です。 JPAプロバイダーは、エンティティーの状態とライフサイクルを追跡するのに十分スマートです。エンティティIDが0(プリミティブタイプ)またはNULL(ラッパータイプ)の場合、IDジェネレーターが構成されていれば、JPAプロバイダーはエンティティのIDを生成します。 idが自動生成される場合、ゼロは有効なエンティティIDとは見なされません。

両方のケースをCmobilecom JPAでテストしましたが、同じように機能します。もちろん、パフォーマンスの違いに気付くことはありません。

免責事項:私は Cmobilecom JPA の開発者です。JavaとAndroidの両方の軽量JPA実装です。

2
John

ジェネリックで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;
1
Pradip Karki

エンティティとコレクションの一意の識別子は、バイナリ、blob、およびclobを除く任意の基本的なタイプにすることができます。 (複合識別子も許可されています。以下を参照してください。)

基本的な値の型には、org.hibernate.Hibernateで定義された対応するType定数があります。たとえば、Hibernate.STRINGは文字列型を表します。

0
Angad Bansode