2017-04-05 18 views
0

この質問がここに寄せられていれば、私は確かにそれを見つけることができなかったし、特に私を助けなかった。継承戦略の選択 - ハイバーネート

私は疑問を解決できなかった継承マッピングのチュートリアルといくつかの質問を読んだことがあります。

ユーザー

そして3つの以上の他のサブクラス:それらのすべてが拡張

ユーザーA、ユーザーB、よびUserC

は、私は抽象クラスを持っていると言いますユーザー。

すべてのサブクラスには独自のテーブルがあり、スーパークラスUserはありません。

私の他のクラスでは、Website私はArrayListを持っていますか、または私はユーザーのコレクションを言うべきですか?

リストには、Websiteのすべてのユーザーを取得する必要があります。

私はどちらの戦略をとるべきですか?私はMappedSuperclassを考えましたが、私のWebsiteクラスではListはユーザタイプのものなので、ここで何をするべきか分かりません。

ありがとうございました!

+0

'すべてのサブクラスには独自のテーブルがありますが、スーパークラスユーザーはその間にはありません。 'これに注意して、スーパークラス内のすべての共通フィールドが各サブクラステーブルで重複して重複する可能性があります。アプローチを再考し、スーパークラス用のテーブルを作成し、さらに特定の拡張データ用のテーブルを追加することを検討してください。 – Jimmy

+0

@Jimmy私のアイデアは共通フィールドを上回っていました。とにかく、私は既存のデータベース以来、構造を変更するcounldnt。あなたの最高の解決策は何でしょうか?ありがとう! –

答えて

1

JPAでは、Javaの実装は常に自分の好みや要件に依存しますが、時には選択の問題です。

はい、@MappedSuperclassが行います。 すべての子供をウェブサイトと一方向の関係にすることができます。次に、Userクラスの中にWebサイトオブジェクトを追加します(注釈付き)。これはforeign_keyフィールドとしてデータベースにマップされます(SQLストレージとJPAの 'リポジトリ' DAO抽象化を使用していると仮定します)。

ウェブサイトクラス内にユーザーのコレクションを格納する必要はありません。ちょうどあなたが本当にそれを必要としていると思ってください。一貫性をサポートするのは難しいかもしれません。 しかし、双方向の関係が必要な場合があります。オブジェクトをメモリに保存するとき(例えばキャッシュ目的のために)、おそらくこのコレクションを持つ必要があります。この場合、なぜ「ユーザー」コレクションを持たないのですか?専用のリポジトリを使用してデータを取得します(または、それらを使用していない場合でも、「ウェブサイト」テーブルではなくforeign_keyを持つ「User」テーブルを使用します)。

たとえば、Spring Data JPAを使用すると、スーパークラスで単方向関係を定義し、次の方法でリポジトリを使用できます(双方向の例はインターネットのどこでも見つけることができます) :

@Entity 
public class SuperUser extends User { 
    ... 
} 

@Entity 
public class BasicUser extends User { 
    ... 
} 

@MappedSuperclass 
public abstract class User implements Serializable {  

    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "website_uuid", nullable = false) 
    protected Website website; 

    ... 
} 

@Entity 
public class Website implements Serializable { 

    ... 
} 


@Repository 
public interface SuperUserRepository extends CrudRepository<SuperUser, Long> { 

    Iterable<SuperUser> findByWebsite(Website website); 

} 

@Repository 
public interface BasicUserRepository extends CrudRepository<BasicUser, Long> { 

    Iterable<BasicUser> findByWebsite(Website website); 

} 
+0

ありがとう!私は今日後でそれを試してみましょう! –

1

あなたが求めているのは、典型的な "コンクリートクラスあたりの"継承戦略のようです。 https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#entity-inheritance-table-per-class

旧バージョンのユーザーガイドでは、非抽象クラスごとに別々のテーブルがマップされることに言及しています。最新の文書では、「抽象的でない」部分は言及されていませんが、私はそれがまだ同様に動作すると信じています。通常、内部的に非効率的なクエリを与えることがunionを使用している

@Entity 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 
abstract class User {...} 

@Entity 
class UserA extends User {...} 

@Entity 
class UserB extends User {...} 

@Entity 
class UserC extends User {...} 

しかし、あなたはこの継承戦略の知っておく必要があります。

だからそれはのようになります。

+0

こんにちは、あなたの答えをありがとうが、私はスーパークラスのためのテーブルを持っていないため、これは動作しないと思う。 –

+0

これは、私が言及したものです。旧式(休止状態の3.3)のドキュメントでは、別の表がそれぞれの具体的(非抽象的)クラスに使用されていることが述べられています。したがって抽象スーパークラスにはテーブルは必要ありません。しかし、行動が変わったならば、Dunno。 –

関連する問題