1

ビークル クラスと武器クラスの 2 つのエンティティがあります。これらは、Vehicle.hbm.xml と Weapon.hbm.xml にそれぞれマップされます。どちらにもそれぞれの DAO があります。すべて正常に動作しています。

これが私の考えです。Vehicle エンティティと Weapon エンティティのすべてのプロパティを持つ VehicleWeapon クラスを作成したいと考えています。Hibernate マッピング ファイルを宣言したい: VehicleWeapon.hbm.xml。マッピング ファイルのプロパティを、武器エンティティと車両エンティティのプロパティと一致させたいと考えています。

VehicleWeapon エンティティを追加、削除、または保存すると、対応する変更がバッキングの Vehicle テーブルと Weapon テーブルに反映されます。(私はおそらく HQL クエリを実行できますが、私が求めているアイデアが実行可能かどうかを最初に知りたいです)。

これは可能ですか?はいの場合、例を示してもらえますか? (もちろん、Vehicle クラスと Weapon クラスは架空のクラスです。このアイデアを実装する必要がある実際のシナリオがあります)。

または、どのようなより良いオプションがありますか? 直接リンクまたは具体的な例を提供できますか? どうもありがとう。

4

4 に答える 4

1

<join>Hibernate は、要素 (または@SecondaryTableアノテーションを使用する場合はアノテーション) を使用して、複数のテーブルにわたって 1 つのエンティティ クラスを永続化するためのサポートを提供します。ドキュメントから:

5.1.20. 加入

この<join>要素を使用すると、1 つのクラスのプロパティを、1 対 1 の関係を持つ複数のテーブルにマップできます。例えば:

<join
        table="tablename"                        (1)
        schema="owner"                           (2)
        catalog="catalog"                        (3)
        fetch="join|select"                      (4)
        inverse="true|false"                     (5)
        optional="true|false">                   (6)

        <key ... />

        <property ... />
        ...
</join>
  1. table: 結合されたテーブルの名前。
  2. schema(オプション): ルート要素で指定されたスキーマ名をオーバーライドします。
  3. catalog(オプション): ルート <hibernate-mapping>要素で指定されたカタログ名をオーバーライドします。
  4. fetch(オプション - デフォルトはjoin): デフォルトの join に設定されている場合、Hibernate は内部結合を使用し<join>て、クラスまたはそのスーパークラスによって定義された を取得します。サブクラスで定義された に対して外部結合を使用します。選択するように設定すると、Hibernate は<join>サブクラスで定義された に対して順次選択を使用します。これは、行がサブクラスのインスタンスを表す場合にのみ発行されます。<join>内部結合は、クラスとそのスーパークラスによって定義されたを取得するために引き続き使用されます。
  5. inverse(オプション - デフォルトはfalse): 有効にすると、Hibernate はこの結合によって定義されたプロパティを挿入または更新しません。
  6. optional(オプション - デフォルトはfalse): 有効にすると、Hibernate は、この結合によって定義されたプロパティが null でない場合にのみ行を挿入します。プロパティの取得には常に外部結合が使用されます。

たとえば、すべてのプロパティの値の型のセマンティクスを保持しながら、個人の住所情報を別のテーブルにマップできます。

<class name="Person"
    table="PERSON">

    <id name="id" column="PERSON_ID">...</id>

    <join table="ADDRESS">
        <key column="ADDRESS_ID"/>
        <property name="address"/>
        <property name="zip"/>
        <property name="country"/>
    </join>
    ...

この機能は、多くの場合、レガシー データ モデルにのみ役立ちます。クラスよりも少ないテーブルと、きめの細かいドメイン モデルをお勧めします。ただし、後で説明するように、単一の階層内の継承マッピング戦略を切り替えるのに役立ちます。

あなたが行ったように構成を使用することは別のオプションですが、明らかに別のテーブルが導入されます(「集約」エンティティ用)。

于 2010-09-06T21:54:28.497 に答える
1

私は実用的な解決策を見つけました。前述したように、Vehicle エンティティと Weapon エンティティ、および対応するマッピング ファイルを変更することは許可されていません。単一の注釈すら許可されません。

上記のベンの提案をグーグルで検索してこの回答を見つけたところ、次の記事にたどり着き まし。 /hibernate/hibernate-example/hibernate-mapping-one-to-one-1.html

mkyong からの提案は良いですが、Vehicle クラスと Weapon クラスのマッピング ファイルを編集する方法がないため、主キーを保持して両方の方法で割り当てるという考えは気に入りませんでした。コメントを参照してください「1対1の関係の主な問題は、両方に同じ主キーが割り当てられるようにすることです」

vaannila からの提案は、なんとなく興味をそそられます。1 対 1 の関係になりますが、他のマッピング ファイルを編集する必要はありません。

まず、VehicleWeapon.hbm.xml を次のように宣言しました。

<hibernate-mapping package="com.armory">

    <id name="id" type="long" >
        <column name="id"  />
        <generator class="native" />
    </id>

    <many-to-one name="vehicle" class="Vehicle" 
            column="vehicle_column"  cascade="all" unique="true" />

    <many-to-one name="weapon" class="Weapon" 
            column="weapon_column"  cascade="all" unique="true" />

次に、標準の VehicleWeapon POJO クラスを宣言しました。そして対応するDAOの実装。

Junit/Spring テストをいくつか実行します。問題なく保存、削除、取得できました。すべてのアクションは、対応する武器テーブルと車両テーブルにカスケードします。

この方法の唯一の欠点は、Hibernate がビークル テーブルと武器テーブルの ID をそれぞれ参照として含む 3 番目のテーブル vehicle_weapon を作成することです。

良いことは、既存のエンティティやマッピング ファイルを編集していないことです。新しいオブジェクトを作成し、2 つのテーブルから新しいオブジェクトを作成しました。

私は、武器とビークルのエンティティに直接マッピングするのではなく、武器とビークルのプロパティに直接マッピングできるようにしたいと思っています。しかし、今のところ、これは許容できると思います。

于 2010-09-06T17:19:12.677 に答える
0

2つのテーブル(VehicleとWeapon)を結合するためにjoincolumnおよびinverseJoincolumnアノテーションを使用し、それらをトランザクションテーブル(VehicleWeapon)に配置します。任意のマッピング(onetoone、onetomanyなど)を使用して、ondeletecascadeおよびfetchを使用して車両とwaeponテーブルをマッピングします。

于 2011-12-15T19:11:55.283 に答える
0

これが答えかどうかはわかりませんが、Hibernateは「複合」関係を許可します。これにより、あるクラスを別のクラスに埋め込み、それをマップします。

たとえば、ここでは「埋め込み可能」クラス(Vehicle)を作成し、それをVehicleWeaponに「埋め込み」ます。

import javax.persistence.Embeddable;

@Embeddable
public class Vehicle
{
    ...
}

ここに埋め込まれています:

@Entity
public class VehicleWeapon
{
  private long id;  
  private String name;
  private Vehicle vehicle;

  ...

    @Embedded
    public Vehicle getVehicle()
    {
      return vehicle;
    }

    public void setVehicle(Vehicle vehicle)
    {
        this.vehicle = vehicle;
    }

    ...
}

それはあなたのシナリオに役立ちますか?

于 2010-09-06T15:14:21.000 に答える