web-dev-qa-db-ja.com

1つのエンティティにつき2つのテーブルを休止状態にする

私は1つのエンティティ-Userを持っています。 _User.class_で記述されます。

Hibernateはエンティティごとに1つのテーブルを作成するため、session.save(user)を呼び出すと、データは常にこのテーブルに保存されます。

同じUserタイプのデータ用に別のテーブルが必要になり、エンティティをそのテーブルにのみ保存する必要があります。

データ構造(このようなもの):

_table users_1_table{
  string id;
  string username;
}

table users_2_table{
  string id;
  string username;
}
_

これで作業

_session.save(user1,"users_1_table")
session.save(user2,"users_2_table")
_

その結果、_user1_に_users_1_table_があり、_user2_に_users_2_table_があるはずです。

システムの制限により、これら2つのオブジェクトを1つのテーブルに入れることはできません。 (余分なフィールドを作成することも悪い考えです)。

サブクラス化せずにこれを行うことはできますか?プログラム的に休止状態の構成を使用していますか?

17
msangel

序文:

これはSOでも広く尋ねられた質問であり、回答もSubclassまたは実際にSuperClassアプローチに関連しています(例:[ 1 ])

実際の回答:

これらの投稿[ 2 ]、[]は、EntityNameパラメータを使用したxmlマッピングの使用を提案しています。

したがって、スーパークラスを必要としないxmlでのマッピングは、2つの同一のマッピングにEntityNameパラメータを与えるだけです。

マッピング例:

_<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
   <class name="DomainModel.User, DomainModel"
     table="User1Object" entity-name="User1Object">  
         <id name="_id" access="field" column="id">
             <generator class="assigned"/>
         </id>
        <property name= ...>
 </class>
 <class name="DomainModel.User, DomainModel"
     table="User2Object" entity-name="User2Object">
         <id name="_id" access="field" column="id">
            <generator class="assigned"/>
         </id>
        <property name= ...>
</class>
</hibernate-mapping>
_

次に、必要なエンティティのタイプに応じて、適切なセッションメソッドを次のように呼び出します。

_session.Save("User1Object", user1)

または

_session.Save("User2Object", user2)

投稿2と3は、このスニペットの基礎として使用されました。公式ソース[ 4 ]

試合後:

実際にこの投稿にリンクされている最初の質問に対する1つの回答[ 5 ]異なるアプローチがあります。

オブジェクトの最初のインスタンスに別れを告げ、データを新しいインスタンスに複製し、別の名前で永続化します。したがって、Hibernateロジックおよびすべてのコンテンツに対する違反はありません。2つのテーブルで同じデータが使用され、サブクラスは使用されません。

まあ、そのアプローチの実装やコードや信頼性はそうです、私もそれをテストしていません。

別のケース:

この投稿[ 6 ]では、スーパークラスアプローチにもっと簡単な方法で挑戦しようとしている人がいますが、最も信頼できる回答は、別の方法では不可能だと述べています、公式の非XMLアプローチは、上記のサブクラスアプローチです。

ソース

[1] hibernate/jpaアノテーションを使用して1つのクラスを別のテーブルにマップする方法

[2] 2つの同一のテーブル(同じスキーマ...)をHibernateの同じエンティティにマップ

[3] 2つの同一のテーブル(同じプロパティ)を1つのエンティティにマップする方法

[4] http://docs.jboss.org/hibernate/core/3.2/reference/en/html/mapping.html#mapping-entityname

[5] Hibernate 4:2つのテーブルをマッピングする1つのクラス-両方のテーブルで1つのオブジェクトを永続化する方法?

[6] 複数のカタログに存在するエンティティのHibernate Annotation

34
mico

また、デフォルトのエンティティと代替のエンティティを使用して機能します。

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
   <class name="DomainModel.User, DomainModel"
     table="User1Object">  
         <id name="_id" access="field" column="id">
             <generator class="assigned"/>
         </id>
        <property name= ...>
 </class>
 <class name="DomainModel.User, DomainModel"
     table="User2Object" entity-name="User2Object">
         <id name="_id" access="field" column="id">
            <generator class="assigned"/>
         </id>
        <property name= ...>
</class>
</hibernate-mapping>

デフォルトの場合、メソッドを使用できます

_session.Save(user1)

そして

_session.Save("User2Object", user2)

代わりのもののために。

3
LieT13

設定を使用してそれを行うことができます:

  • 同じエンティティクラスに対して2つのマッピングを作成しますnameですが、それらに異なる論理entity-name、およびtable名前。
  • 次に、Sessionメソッドを使用して、entityNameをパラメーターとして指定し、一方を他方と区別します。

これにより何が達成されますか?

  • 「仮想サブタイピング」
  • データをタイプに取得するときは、1つ指定する必要がありますentity-typeまたはその他(つまり、いずれかのテーブルを意味します)
  • データを変更して保存するときは、同じentity-type-異なるentity-typeはhibernateによって拒否されます。それ以外の場合、変更されたエンティティにはすでに識別子が入力されているため、Hibernateは挿入ではなく更新を試みますが、データベースでは失敗します-テーブルに存在しなかったデータを更新しようとします。
  • これは分離につながります。エンティティまたはエンティティのリストで作業するときは、1つのエンティティタイプにコミットする必要があり、2つを混在させることはできません。つまり、「仮想サブタイピング」

費用はいくらですか?

  • それは非常に弱いタイピングを提供します。コンパイラとランタイムは、真のサブタイプを示していません。エラーは発生を待っているため、デバッグが難しい場合があります。
  • それは非標準です。 JPAはこれを回避しました。私はそれが包含のために、そして正当な理由のためにレーダーにあるわけではないと信じています。
  • アノテーションではなく、XMLを使用する必要があります。
  • 「entity-type」パラメータを含む通常とは異なるメソッドを呼び出す必要があります。

サブタイピングよりもメリットはありますか?

  • 何も見えない

それをしますか?

  • 私はそうは思わない!サブタイピングと標準コードを使用します。
1
Glen Best

私はこの質問がずっと前に尋ねられたことを知っています。しかし、休止状態のものを使用せずに、別の方法を提案したいと思います。 xml設定を使用したくない人のために。

Commun列のゲッターメソッドとセッターメソッドを使用してインターフェイスを宣言し、towエンティティクラスにこのインターフェイスを実装させます。通常どおり、この2つのエンティティクラスにマッピングアノテーションを残します。コードでは、代わりにこのインターフェイスのメソッドを呼び出すことができます。

0
Qianlong

私は使用したことがありませんが、休止状態のセカンダリテーブルの概念があります。また、@ SecondaryTablesは、エンティティが複数のテーブルをマップしてデータをフェッチできるようにするHibernateのアノテーションです。データをフェッチするエンティティには@SecondaryTablesアノテーションが必要です。プライマリテーブルと外部キーに基づいて、また一意の制約に基づいてセカンダリテーブルを関連付けます。

これは私がグーグルをした後に見つけた1つのサンプルです、それがあなたが達成するのに役立つかどうかを確認してください:

http://www.concretepage.com/hibernate/secondarytables_hibernate_annotation.php

0
Juned Ahsan