2012-10-04 9 views
17

これはかなり素朴でなければなりませんが、私は@Entity@Embeddableをいつ使うべきか疑問に思っています。@embeddableとコレクションのマッピングのための@entity

私はUserNotificationクラスがあります。

@Entity 
public class User{ 
    //other properties 
    @onetomany 
    private List<Notification> notifications; 
} 

@Entity 
public class Notification{ 
    //properties 
} 

は、私はクラスUserNotification、およびマッピングのための第三のテーブル用のテーブルがあることを理解しています。 このようにすればどうなりますか?

@Entity 
public class User { 
    //other properties 
    @ElementCollection 
    private List<Notification> notifications; 
} 

@Embeddable 
public class Notification{ 
    //properties 
} 

Notificationの表は作成されません。しかし、私はまだ私の通知オブジェクトを格納することができます。私はdocumentationて行きましたが、疑問のカップル:

  1. は、それは私が別々のテーブルとしてクラスBを見たいかどうかに基づいてますか?
  2. テーブルと埋め込み可能なオブジェクトを作成する際のパフォーマンスの違いはありますか?
  3. テーブルに直接クエリする以外のテーブルで行うことができる埋め込み可能なオブジェクトでは、私は何ができませんか?この質問を読んだ人のため

NOTES

、このquestionはあまりにもあなたを助けるかもしれません。

答えて

8
  1. クラスBを別のテーブルとして見たいかどうかに基づいていますか?

あなたが@Embeddedを使用するときにはい、あなたはそれが@Entityクラスの同じテーブルに埋め込まれたエンティティのために列を追加することができ@Entityクラスにその@Embeddable実体を埋め込みます。

  1. テーブルと埋め込みオブジェクトを作成する際のパフォーマンスの違いはありますか?

テーブルの作成では、@Embeddedを使用すると、行の挿入と選択にも1つのクエリが必要です。しかし、あなたがそれを使用しない場合は、複数のクエリが必要です。したがって、@Embeddedを使用すると、より多くのパフォーマンスが得られます。

  1. 表に直接問合せする以外の表で行うことはできますが、埋め込み可能なオブジェクトでできないことはありますか?

それぞれの埋め込みエンティティが削除されている可能性がありますが、これには整合性制約違反がある可能性があります。

+0

私はElementCollectionでEmbeddableを使うことができると思います。 @埋め込みRTを使用する必要はありませんか? – shazinltc

+0

私は3点目を得ていませんでした。 – shazinltc

+0

第3ポイント:PersonにはAddress(埋め込み)が含まれているとみなされます。両方に別のテーブルがある場合は、関連付けられたアドレスを直接削除できます。解決するために、整合性制約違反が発生する可能性があります。 – deepakraut

0

JPAには、複合キーフィールドを作成するいくつかの方法があります。 @Embeddable annotationを使用する方法を見てみましょう。
Entityクラスから始めましょう。

@Entity 
@Table 
public class TraceRecord { 
    @Id 
    private TraceRecordPk id; 

    @Version 
    @Transient 
    private int version; 

    @Column(columnDefinition = "char") 
    private String durationOfCall; 

    @Column(columnDefinition = "char") 
    private String digitsDialed; 

    @Column(columnDefinition = "char") 
    private String prefixCalled; 

    @Column(columnDefinition = "char") 
    private String areaCodeCalled; 

    @Column(columnDefinition = "char") 
    private String numberCalled; 
} 

これは、@Idと@Versionフィールドといくつかの@Column定義を持つ非常に単純なEntityクラスです。あまり詳しく説明しなくても、@Versionフィールドには@Transientも注釈されています。私のテーブルもバージョンを追跡するための列がないので、私はこれをやったが、私のデータベースはジャーナリングされているので、私はバージョン管理についてあまり心配していない。 @ColumnフィールドのcolumnDefinition属性には "char"という値が設定されています。これは、私のテーブル内のフィールドがvarcharではなくcharとして定義されているためです。それらがvarcharの場合、Stringはデフォルトでvarcharフィールドにマップされるため、これを行う必要はありません。

@Idフィールドは私が今興味を持っているものです。これは標準のJava型ではありませんが、自分で定義したクラスです。ここにそのクラスがあります。

@Embeddable 
public class TraceRecordPk implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Temporal(TemporalType.DATE) 
    @Column 
    private Date dateOfCall; 

    @Column(columnDefinition="char") 
    private String timeOfCall; 

    @Column(columnDefinition="char") 
    private String callingParty; 

    /** 
    * Constructor that takes values for all 3 members. 
    * 
    * @param dateOfCall Date the call was made 
    * @param timeOfCall Time the call was made 
    * @param callingParty Extension from which the call originated 
    */ 
    public TraceRecordPk(Date dateOfCall, String timeOfCall, String callingParty) { 
     this.dateOfCall = dateOfCall; 
     this.timeOfCall = timeOfCall; 
     this.callingParty = callingParty; 
    } 
} 

Entityクラスの@Idフィールドであることのこのクラスができるようにするに私は前に述べたように、それは@Embeddableの注釈が付けする必要があります。コンポジットキーのために選択した3つのフィールドは、通常の@Column定義です。フィールドごとにgetter/setterを作成するのではなく、すべての3つのフィールドの値を取るコンストラクタを実装して、インスタンスを不変にしました。 @Embeddableでクラスに注釈を付けるとき、そのクラスはSerializableを実装する必要があります。そこで、デフォルトのserialVersionUIDを追加しました。

クラスを作成し、@Embeddableという注釈を付けたので、これをEntityクラスの@Idフィールドの型として使用できるようになりました。シンプルなものね。

+0

ありがとうございますが、私はこの記事を読んでいます(http://jpgmr.wordpress.com/2011/03/27/using-the-jpa-embeddable-annotation-to-create-your-own-composite-keys /)。それは私の質問に答えるものではありません。私の質問は、とにかくコンポジットキーには関係しません。 – shazinltc

関連する問題