5

アプリケーションのすべてのテーブルに単一テーブル継承を使用します。これにより、同じアプリケーションスタックの異なるインスタンスが同じDAOで動作できるようになりますが、エンティティはわずかに異なる可能性があり、そのインスタンスに固有の情報が含まれている可能性があります。抽象クラスは基本的なテーブル構造を定義し、拡張機能はそのインスタンスで必要な場合は追加の列を定義します。

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "client")
public abstract class Client extends AbstractPersistable<Long> {
    // ...
}

アプリケーションA:

@Entity
public class ClientSimple extends Client {
    private String name;
    // getter, setter
}

アプリケーションB:

@Entity
public class ClientAdvanced extends Client {
    private String description;
    // getter, setter
}

これで、DAOはClientアプリケーションAおよびBのオブジェクトを操作できますが、アプリケーションBは、アプリケーションBに固有のマネージャーメソッドによって読み取られる可能性のあるクライアントオブジェクトの追加情報を定義できます。

アプリケーションA:

Client client = new ClientSimple();
clientDao.save(client);

アプリケーションB:

Client client = new ClientAdvanced();
clientDao.save(client);

残念ながら、これはすべてのテーブル(または私が選択する可能性のある他の名前)にDTYPE列があることを意味します。これを取り除く方法はありますか?私たちはそれを必要とせず、それはDBスペースを使い果たしています...

ありがとう!


編集

注意すべき重要な点:機能し@MappedSuperclassません。HQL抽象化レイヤーとしてQueryDSLを使用しています。これには、タイプ保存クエリ用に自動的に生成されたクエリタイプクラスが必要です。ただし、これらは、抽象クラスに。の注釈が付けられている場合にのみ正しく生成され@Entityます。

アプリケーションAとアプリケーションBClientで実際にクエリを実行しているときに、抽象クラスに対してクエリを実行する必要があるため、これは必要です。ClientSimpleClientAdvanced

したがって、どのアプリケーションでもこれは機能します。

query.where(QClient.client.name.equals("something");

アプリケーションBでは、これは機能します。

query.where(QClientSimple.client.description.equals("something else");

EDIT2-ボイルダウン

つまり、デプロイ時にHibernateを構成して、継承されたエンティティのディスクリミネータータイプを固定値に設定できますか?それで、私の例では、aClientは常にClientSimple一方のアプリケーションともう一方のアプリケーションClientAdvancedにあるので、その情報をデータベースに保存する必要はありませんか?

私が言ったように:各アプリケーションはベースアプリケーションスタックのインスタンスになります。各アプリケーションはローカルデータベースに追加の列を定義する場合がありますが、すべてのオブジェクトはそのインスタンスに対して同じタイプになるため、ディスクリミネーターが常に同じであり、データベース内で冗長になり、休止状態の構成のユースケースになることが保証されます。

4

3 に答える 3

2

同じアプリケーションで と のClientSimple両方を使用する必要がない場合は、ではなくとして宣言できます。ClientAdvancedClient@MappedSuperclass@Entity

于 2012-01-02T15:37:20.527 に答える
1

Hibernate では、1 つの階層内のすべてのクラスが 1 つのテーブルに格納されるため、エンティティを区別するために、クラス階層ごとに単一のテーブルが常に必要になります。クラス階層ごとの Hibernate Single Table の例を次に示します。

ただし、以下のような別の階層スキームを検討することもできます。

サブクラスごとの Hibernate 単一テーブル

利点

  • この階層を使用すると、単一の親クラスが変更されたときに、データベース スキーマに複雑な変更を加える必要がなくなります。
  • 浅い階層でうまく機能します。

短所

  • 階層が大きくなると、パフォーマンスが低下する可能性があります。
  • サブクラスを構築するために必要な結合の数も増えます。

Concrete クラスごとの Hibernate Single Table

利点

  • これは、実装が最も簡単な継承マッピングの方法です。

短所

  • 親クラスに属するデータは、具体的なクラスを表す多数のサブクラス テーブルに分散しています。
  • ほとんどの場合、この階層は推奨されません。
  • 親クラスへの変更が多数のテーブルに反映される
  • 親クラスの用語で表されたクエリは、多数の選択操作を引き起こす可能性があります

Single Table Per Subclass スキームをご覧になることをお勧めします。あなたの正確な要件についてはわかりませんが。しかし、これは役立つかもしれません。

于 2012-01-03T04:26:51.317 に答える