Thursday, May 15, 2008

HIBERNATE - Relational Persistence for Idiomatic Java - 9

HIBERNATE - Relational Persistence for Idiomatic Java
Hibernate Reference Documentation
Hibernateレファレンスドキュメンテーション
3.2.2

Table of Contents(コンテンツテーブル)
Preface(序文)
1. Introduction to Hibernate(Hibernateの紹介)
2. Architecture(アーキテクチャ)
3. Configuration(設定)
4. Persistent Classes(永続クラス)
5. Basic O/R Mapping(基本的なO/Rマッピング)
6. Collection Mapping(コレクションのマッピング)
7. Association Mappings(関連マッピング)
8. Component Mapping(コンポーネントのマッピング)
9. Inheritance Mapping(継承マッピング)
9.1. The Three Strategies(3つの戦略)
9.1.1. Table per class hierarchy(クラス階層ごとのテーブル)
9.1.2. Table per subclass(サブクラスごとのテーブル)
9.1.3. Table per subclass, using a discriminator(弁別子を用いた table-per-subclass)
9.1.4. Mixing table per class hierarchy with table per subclass(table-per-subclass  table-per-class-hierarchy の混合)
9.1.5. Table per concrete class(具象クラスごとのテーブル)
9.1.6. Table per concrete class, using implicit polymorphism(暗黙的ポリモーフィズムを用いた table-per-concrete-class)
9.1.7. Mixing implicit polymorphism with other inheritance mappings(他の継承マッピングと暗黙的ポリモーフィズムの組み合わせ)
9.2. Limitations(制限)

Chapter 9. Inheritance Mapping(9章:継承マッピング)
9.1. The Three Strategies(3つの戦略)
Hibernate supports the three basic inheritance mapping strategies:
Hibernate3つの基本的な継承のマッピング戦略をサポートします。
?         table per class hierarchy
クラス階層ごとテーブル
?         table per subclass
サブクラスごとのテーブル
?         table per concrete class
具象クラスごとのテーブル
In addition, Hibernate supports a fourth, slightly different kind of polymorphism:
加えて4つ目に、Hibernateはわずかに異なる性質を持ったポリモーフィズムをサポートします。
?         implicit polymorphism
暗黙的ポリモーフィズム
It is possible to use different mapping strategies for different branches of the same inheritance hierarchy, and then make use of implicit polymorphism to achieve polymorphism across the whole hierarchy. However, Hibernate does not support mixing<subclass>, and <joined-subclass> and <union-subclass> mappings under the same root<class> element. It is possible to mix together the table per hierarchy and table per subclass strategies, under the the same <class> element, by combining the <subclass>and <join> elements (see below).
同一の継承階層の異なるブランチに対して異なるマッピング戦略を使うことができます。その場合には全体の階層に渡るポリモーフィズムを実現するために暗黙的ポリモーフィズムを使用します。しかし、Hibernateは同じルート<class>要素内で<subclass>マッピング、<joined-subclass>マッピング、<union-subclass>マッピングの同時使用をサポートしていません。<subclass>要素と<join>要素を組み合わせることで、同一<class>要素内でのtable-per-hierarchy 戦略とtable-per-subclass 戦略の同時使用は可能です。次の例を見てください。
It is possible to define subclassunion-subclass, and joined-subclass mappings in separate mapping documents, directly beneath hibernate-mapping. This allows you to extend a class hierachy just by adding a new mapping file. You must specify an extendsattribute in the subclass mapping, naming a previously mapped superclass. Note: Previously this feature made the ordering of the mapping documents important. Since Hibernate3, the ordering of mapping files does not matter when using the extends keyword. The ordering inside a single mapping file still needs to be defined as superclasses before subclasses.
subclass,union-subclass joined-subclassマッピングを複数のマッピングドキュメントに定義することが出来、hibernate-mappingの直下に配置します。これは新しいマッピングファイルを追加するだけで、クラス階層を拡張できるということです。あらかじめマップしたスーパークラスを指定して、サブクラスマッピングにextends属性を記述しなければなりません。注意:この特徴により、以前はマッピング・ドキュメントの順番が重要でした。Hibernate3からは、extendsキーワードを使う場合、マッピングドキュメントの順番は問題になりません。1つのマッピングファイル内で順番付けを行うときは、依然として、サブクラスを定義する前にスーパークラスを定義する必要があります。)

 <hibernate-mapping>
     <subclass name="DomesticCat" extends="Cat" discriminator-value="D">
          <property name="name" type="string"/>
     </subclass>
 </hibernate-mapping>
9.1.1. Table per class hierarchy(クラス階層ごとのテーブル)
Suppose we have an interface Payment, with implementors CreditCardPayment,CashPaymentChequePayment. The table per hierarchy mapping would look like:
例えば、インターフェイスPaymentと、それを実装したCreditCardPaymentCashPaymentChequePaymentがあるとします。階層ごとのテーブルマッピングは以下のようになります。
<class name="Payment" table="PAYMENT">
    <id name="id" type="long" column="PAYMENT_ID">
        <generator class="native"/>
    </id>
    <discriminator column="PAYMENT_TYPE" type="string"/>
    <property name="amount" column="AMOUNT"/>
    ...
    <subclass name="CreditCardPayment" discriminator-value="CREDIT">
        <property name="creditCardType" column="CCTYPE"/>
        ...
    </subclass>
    <subclass name="CashPayment" discriminator-value="CASH">
        ...
    </subclass>
    <subclass name="ChequePayment" discriminator-value="CHEQUE">
        ...
    </subclass>
</class>
Exactly one table is required. There is one big limitation of this mapping strategy: columns declared by the subclasses, such as CCTYPE, may not have NOT NULLconstraints.
ちょうど一つのテーブルが必要です。このマッピング戦略には一つ大きな制限があります。CCTYPEのような、サブクラスで宣言されたカラムはNOT NULL制約を持てません。
9.1.2. Table per subclass(サブクラスごとのテーブル)
A table per subclass mapping would look like:
able-per-subclass マッピングは以下のようになります。
<class name="Payment" table="PAYMENT">
    <id name="id" type="long" column="PAYMENT_ID">
        <generator class="native"/>
    </id>
    <property name="amount" column="AMOUNT"/>
    ...
    <joined-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
        <key column="PAYMENT_ID"/>
        <property name="creditCardType" column="CCTYPE"/>
        ...
    </joined-subclass>
    <joined-subclass name="CashPayment" table="CASH_PAYMENT">
        <key column="PAYMENT_ID"/>
        ...
    </joined-subclass>
    <joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
        <key column="PAYMENT_ID"/>
        ...
    </joined-subclass>
</class>
Four tables are required. The three subclass tables have primary key associations to the superclass table (so the relational model is actually a one-to-one association).
このマッピングには4つのテーブルが必要です。3つのサブクラステーブルはスーパークラステーブルとの関連を示す主キーを持っています(実際、関係モデル上は一対一関連です)。
9.1.3. Table per subclass, using a discriminator(弁別子を用いた table-per-subclass)
Note that Hibernate's implementation of table per subclass requires no discriminator column. Other object/relational mappers use a different implementation of table per subclass which requires a type discriminator column in the superclass table. The approach taken by Hibernate is much more difficult to implement but arguably more correct from a relational point of view. If you would like to use a discriminator column with the table per subclass strategy, you may combine the use of <subclass> and <join>, as follow:
Hibernate table-per-subclass 実装は、discriminatorカラムを必要としないことを覚えておいてください。Hibernate以外のO/Rマッパーは、table-per-subclass に異なる実装を用います。それは、スーパークラスのテーブルにタイプdiscriminatorカラムを必要とします。このアプローチは実装が困難になりますが、関係の視点から見ると、より正確なものです。table-per-subclass 戦略でdiscriminatorカラムを使いたければ、<subclass><join>を以下のように組み合わせて使ってください。
<class name="Payment" table="PAYMENT">
    <id name="id" type="long" column="PAYMENT_ID">
        <generator class="native"/>
    </id>
    <discriminator column="PAYMENT_TYPE" type="string"/>
    <property name="amount" column="AMOUNT"/>
    ...
    <subclass name="CreditCardPayment" discriminator-value="CREDIT">
        <join table="CREDIT_PAYMENT">
            <key column="PAYMENT_ID"/>
            <property name="creditCardType" column="CCTYPE"/>
            ...
        </join>
    </subclass>
    <subclass name="CashPayment" discriminator-value="CASH">
        <join table="CASH_PAYMENT">
            <key column="PAYMENT_ID"/>
            ...
        </join>
    </subclass>
    <subclass name="ChequePayment" discriminator-value="CHEQUE">
        <join table="CHEQUE_PAYMENT" fetch="select">
            <key column="PAYMENT_ID"/>
            ...
        </join>
    </subclass>
</class>
The optional fetch="select" declaration tells Hibernate not to fetch the ChequePaymentsubclass data using an outer join when querying the superclass.
オプションのfetch="select"宣言は、スーパークラスのクエリ実行時に外部結合を使って、サブクラスのChequePaymentデータを取得しないように指定するためのものです。
9.1.4. Mixing table per class hierarchy with table per subclass(table-per-subclass table-per-class-hierarchy の混合)
You may even mix the table per hierarchy and table per subclass strategies using this approach:
このアプローチを使用すると、table-per-hierarchy  table-per-subclass 戦略を組み合わせる事も可能です。
<class name="Payment" table="PAYMENT">
    <id name="id" type="long" column="PAYMENT_ID">
        <generator class="native"/>
    </id>
    <discriminator column="PAYMENT_TYPE" type="string"/>
    <property name="amount" column="AMOUNT"/>
    ...
    <subclass name="CreditCardPayment" discriminator-value="CREDIT">
        <join table="CREDIT_PAYMENT">
            <property name="creditCardType" column="CCTYPE"/>
            ...
        </join>
    </subclass>
    <subclass name="CashPayment" discriminator-value="CASH">
        ...
    </subclass>
    <subclass name="ChequePayment" discriminator-value="CHEQUE">
        ...
    </subclass>
</class>
For any of these mapping strategies, a polymorphic association to the root Payment class is mapped using <many-to-one>.
いずれのマッピング戦略であっても、ルートであるPaymentクラスへのポリモーフィックな関連は<many-to-one>を使ってマッピングします。
<many-to-one name="payment" column="PAYMENT_ID" class="Payment"/>
9.1.5. Table per concrete class(具象クラスごとのテーブル)
There are two ways we could go about mapping the table per concrete class strategy. The first is to use <union-subclass>.
table-per-concrete-class 戦略のマッピングに対するアプローチは、2つあります。1つ目は<union-subclass>を利用する方法です。
<class name="Payment">
    <id name="id" type="long" column="PAYMENT_ID">
        <generator class="sequence"/>
    </id>
    <property name="amount" column="AMOUNT"/>
    ...
    <union-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
        <property name="creditCardType" column="CCTYPE"/>
        ...
    </union-subclass>
    <union-subclass name="CashPayment" table="CASH_PAYMENT">
        ...
    </union-subclass>
    <union-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
        ...
    </union-subclass>
</class>
Three tables are involved for the subclasses. Each table defines columns for all properties of the class, including inherited properties.
サブクラスごとに3つのテーブルが必要です。それぞれのテーブルは、継承プロパティを含んだ、クラスの全てのプロパティに対するカラムを定義します。
The limitation of this approach is that if a property is mapped on the superclass, the column name must be the same on all subclass tables. (We might relax this in a future release of Hibernate.) The identity generator strategy is not allowed in union subclass inheritance, indeed the primary key seed has to be shared accross all unioned subclasses of a hierarchy.
このアプローチには制限があります。それは、プロパティがスーパークラスにマッピングされていた場合、全てのサブクラスにおいてカラム名が同じでなければならないというものです。Hibernateの今後のリリースで緩和されるかもしれません)。<union-subclass>を使った table-per-concrete-class 戦略では識別子生成戦略を使用できません。主キーを生成するためのシードは、全ての union subclass の階層内で共有する必要があるからです。
If your superclass is abstract, map it with abstract="true". Of course, if it is not abstract, an additional table (defaults to PAYMENT in the example above) is needed to hold instances of the superclass.
もしスーパークラスが抽象クラスなら、abstract="true"とマッピングします。もちろん、スーパークラスが抽象クラスでないなら、スーパークラスのインスタンスを保持するためのテーブルの追加が必要となります(上の例でのデフォルトはPAYMENT)
9.1.6. Table per concrete class, using implicit polymorphism(暗黙的ポリモーフィズムを用いた table-per-concrete-class)
An alternative approach is to make use of implicit polymorphism:
もう一つのアプローチは暗黙的ポリモーフィズムの使用です。
<class name="CreditCardPayment" table="CREDIT_PAYMENT">
    <id name="id" type="long" column="CREDIT_PAYMENT_ID">
        <generator class="native"/>
    </id>
    <property name="amount" column="CREDIT_AMOUNT"/>
    ...
</class>

<class name="CashPayment" table="CASH_PAYMENT">
    <id name="id" type="long" column="CASH_PAYMENT_ID">
        <generator class="native"/>
    </id>
    <property name="amount" column="CASH_AMOUNT"/>
    ...
</class>

<class name="ChequePayment" table="CHEQUE_PAYMENT">
    <id name="id" type="long" column="CHEQUE_PAYMENT_ID">
        <generator class="native"/>
    </id>
    <property name="amount" column="CHEQUE_AMOUNT"/>
    ...
</class>
Notice that nowhere do we mention the Payment interface explicitly. Also notice that properties of Payment are mapped in each of the subclasses. If you want to avoid duplication, consider using XML entities (e.g. [ <!ENTITY allproperties SYSTEM "allproperties.xml"> ] in the DOCTYPE declartion and &allproperties; in the mapping).
Paymentインターフェイスがどこにも明示的に示されていないことに注意してください。そして、Paymentプロパティがそれぞれのサブクラスにマッピングされていることにも注意してください。もし重複を避けたいのであれば、XMLエンティティの利用を考えてください。(例:DOCTYPE宣言における[ <!ENTITY allproperties SYSTEM "allproperties.xml"> ]と、マッピングにおける&amp;allproperties;
The disadvantage of this approach is that Hibernate does not generate SQL UNIONs when performing polymorphic queries.
このアプローチの欠点は、Hibernateがポリモーフィックなクエリの実行時にSQLUNIONを生成しない点です。
For this mapping strategy, a polymorphic association to Payment is usually mapped using<any>.
このマッピング戦略に対しては、Paymentへのポリモーフィックな関連は通常、<any>を使ってマッピングされます。
<any name="payment" meta-type="string" id-type="long">
    <meta-value value="CREDIT" class="CreditCardPayment"/>
    <meta-value value="CASH" class="CashPayment"/>
    <meta-value value="CHEQUE" class="ChequePayment"/>
    <column name="PAYMENT_CLASS"/>
    <column name="PAYMENT_ID"/>
</any>
9.1.7. Mixing implicit polymorphism with other inheritance mappings(他の継承マッピングと暗黙的ポリモーフィズムの組み合わせ)
There is one further thing to notice about this mapping. Since the subclasses are each mapped in their own <class> element (and since Payment is just an interface), each of the subclasses could easily be part of another inheritance hierarchy! (And you can still use polymorphic queries against the Payment interface.)
このマッピングについての更なる注意点があります。サブクラスが自身を<class>要素としてマッピングしているので、(かつPaymentは単なるインターフェイスなので)、それぞれのサブクラスは簡単にその他の継承階層の一部となります。(しかも、今までどおりPaymentインターフェイスに対するポリモーフィックなクエリを使用することができます)
<class name="CreditCardPayment" table="CREDIT_PAYMENT">
    <id name="id" type="long" column="CREDIT_PAYMENT_ID">
        <generator class="native"/>
    </id>
    <discriminator column="CREDIT_CARD" type="string"/>
    <property name="amount" column="CREDIT_AMOUNT"/>
    ...
    <subclass name="MasterCardPayment" discriminator-value="MDC"/>
    <subclass name="VisaPayment" discriminator-value="VISA"/>
</class>

<class name="NonelectronicTransaction" table="NONELECTRONIC_TXN">
    <id name="id" type="long" column="TXN_ID">
        <generator class="native"/>
    </id>
    ...
    <joined-subclass name="CashPayment" table="CASH_PAYMENT">
        <key column="PAYMENT_ID"/>
        <property name="amount" column="CASH_AMOUNT"/>
        ...
    </joined-subclass>
    <joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
        <key column="PAYMENT_ID"/>
        <property name="amount" column="CHEQUE_AMOUNT"/>
        ...
    </joined-subclass>
</class>
Once again, we don't mention Payment explicitly. If we execute a query against thePayment interface - for example, from Payment - Hibernate automatically returns instances of CreditCardPayment (and its subclasses, since they also implementPayment), CashPayment and ChequePayment but not instances ofNonelectronicTransaction.
もう一度述べますが、Paymentは明示的に定義されません。もし、Paymentインターフェイスに対してクエリを実行するなら(例えばfrom Payment節を使って)、Hibernateは自動的にCreditCardPayment(とCreditCardPaymentのサブクラス、Paymentの実装であるため)、および、CashPaymentChequePaymentのインスタンスを返します。NonelectronicTransactionインスタンスは返しません。
9.2. Limitations(制限)
There are certain limitations to the "implicit polymorphism" approach to the table per concrete-class mapping strategy. There are somewhat less restrictive limitations to<union-subclass> mappings.
table-per-concrete-class マッピング戦略への「暗黙的ポリモーフィズム」アプローチにはいくつかの制限があります。<union-subclass>マッピングに対しても少し弱めの制限があります。
The following table shows the limitations of table per concrete-class mappings, and of implicit polymorphism, in Hibernate.
次のテーブルに、Hibernateにおけるtable-per-concrete-classマッピングの制限や暗黙的ポリモーフィズムの制限を示します。
Table 9.1. Features of inheritance mappings(継承マッピングの機能)
Inheritance strategy
Polymorphic many-to-one
Polymorphic one-to-one
Polymorphic one-to-many
Polymorphic many-to-many
Polymorphic load()/get()
Polymorphic queries
Polymorphic joins
Outer join fetching
table per class-hierarchy
<many-to-one>
<one-to-one>
<one-to-many>
<many-to-many>
s.get(Payment.class, id)
from Payment p
from Order o join o.payment p
supported
table per subclass
<many-to-one>
<one-to-one>
<one-to-many>
<many-to-many>
s.get(Payment.class, id)
from Payment p
from Order o join o.payment p
supported
table per concrete-class (union-subclass)
<many-to-one>
<one-to-one>
<one-to-many> (forinverse="true"only)
<many-to-many>
s.get(Payment.class, id)
from Payment p
from Order o join o.payment p
supported
table per concrete class (implicit polymorphism)
<any>

No comments:

Post a Comment