diff --git a/reference/en/modules/component_mapping.xml b/reference/en/modules/component_mapping.xml index 090506f1eb..4fd1a2379a 100644 --- a/reference/en/modules/component_mapping.xml +++ b/reference/en/modules/component_mapping.xml @@ -236,7 +236,7 @@ Components as Map indices - The <composite-index> element lets you map a + The <composite-map-key> element lets you map a component class as the key of a Map. Make sure you override hashCode() and equals() correctly on the component class. @@ -265,93 +265,111 @@ + + + Note: in Hibernate3, the second requirement is not an absolutely hard + requirement of Hibernate. But do it anyway. + You can't use an IdentifierGenerator to generate composite keys. Instead the application must assign its own identifiers. - - Since a composite identifier must be assigned to the object before saving it, - we can't use unsaved-value of the identifier to distinguish - between newly instantiated transient instances and detached instances from a - previous session. - - - - TODO: document new auto-detect features for assigned IDs in H3 - - - - So, if you wish to use transitive reattachment (you don't have to), you must - either implement Interceptor.isUnsaved() or define the - unsaved-value of a <version> or - <timestamp> element. - - Use the <composite-id> tag (with nested - <key-property> elements) in place of the - usual <id> declaration: + <key-property> elements) in place of the usual + <id> declaration. For example, the + OrderLine class has a primary key that depends upon + the (composite) primary key of Order. - - - - - + + + + + + + + + + + + .... + ]]> - Now, any foreign keys into the table FOOS are also composite. - You must declare this in your mappings for other classes. An association to - Foo would be declared like this: + Now, any foreign keys referencing the OrderLine table are also + composite. You must declare this in your mappings for other classes. An association + to OrderLine would be mapped like this: - + - - - + + + ]]> - - This new <column> tag is also used by multi-column custom types. - Actually it is an alternative to the column attribute everywhere. A - collection with elements of type Foo would use: - - - - - - - - + + (Note that the <column> tag is an alternative to the + column attribute everywhere.) + + + + A many-to-many association to OrderLine also + uses the composite foreign key: + + + + + + + + ]]> - On the other hand, <one-to-many>, as usual, declares no columns. + The collection of OrderLines in Order would + use: + + + + + + +]]> + - If Foo itself contains collections, they will also need a - composite foreign key. + (The <one-to-many> element, as usual, declares no columns.) + + + + If OrderLine itself owns a collection, it also has a composite + foreign key. - + .... .... - + - - - + + + - + + + ... + ]]> @@ -367,7 +385,7 @@ - + ]]> diff --git a/reference/en/modules/example_mappings.xml b/reference/en/modules/example_mappings.xml index 61027dcfab..a45455eeac 100644 --- a/reference/en/modules/example_mappings.xml +++ b/reference/en/modules/example_mappings.xml @@ -154,12 +154,8 @@ create sequence employer_id_seq]]> - - - - - - + + @@ -292,7 +288,7 @@ alter table author_work - + diff --git a/reference/en/modules/inheritance_mapping.xml b/reference/en/modules/inheritance_mapping.xml index 89a2eabaf5..764c95c823 100644 --- a/reference/en/modules/inheritance_mapping.xml +++ b/reference/en/modules/inheritance_mapping.xml @@ -5,12 +5,7 @@ The Three Strategies - TODO: While this is all still supported, many new features would require - a rewrite of this whole chapter - - - - Hibernate supports the three basic inheritance mapping strategies. + Hibernate supports the three basic inheritance mapping strategies: @@ -26,25 +21,45 @@ - table per concrete class (some limitations) + table per concrete class - + - It is even possible to use different mapping strategies for different - branches of the same inheritance hierarchy, but the same limitations - apply as apply to table-per-concrete class mappings. Hibernate does - not support mixing <subclass> mappings and - <joined-subclass> mappings inside the same - <class> element. However, it is possible to - use a <join> element to map this. + In addition, Hibernate supports a fourth, slightly different kind of + polymorphism: + + + + 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). + + + + Table per class hierarchy + Suppose we have an interface Payment, with implementors CreditCardPayment, CashPayment, - ChequePayment. The table-per-hierarchy mapping would + ChequePayment. The table per hierarchy mapping would look like: @@ -56,6 +71,7 @@ ... + ... @@ -67,13 +83,18 @@ ]]> - Exactly one table is required. There is one big limitation of this - mapping strategy: columns declared by the subclasses may not have - NOT NULL constraints. + 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 NULL constraints. + + + + + Table per class subclass - A table-per-subclass mapping would look like: + A table per subclass mapping would look like: @@ -84,6 +105,7 @@ ... + ... @@ -102,34 +124,140 @@ is actually a one-to-one association). + + + + Table per subclass, using a discriminator + - Note that Hibernate's implementation of table-per-subclass requires + 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 + 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. + 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: - - TODO: document usage of join for discriminators in table-per-subclass - + + + + + + + ... + + + + ... + + + + + ... + + + + + ... + + +]]> - TODO: document usage of join for mixing inheritance mapping strategies + The optional fetch="select" declaration tells Hibernate + not to fetch the ChequePayment subclass data using an + outer join when querying the superclass. + + + + Mixing table per class hierarchy with table per subclass + - For either of these two mapping strategies, a polymorphic - association to Payment is mapped using + You may even mix the table per hierarchy and table per subclass strategies + using this approach: + + + + + + + + + ... + + + + ... + + + + ... + + + ... + +]]> + + + For any of these mapping strategies, a polymorphic association to the root + Payment class is mapped using <many-to-one>. - ]]> + ]]> - The table-per-concrete-class strategy is very different. + + + + 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>. + + + + + + + + ... + + + ... + + + ... + + + ... + +]]> + + + Three tables are involved. Each table defines columns for all properties + of the class, including inherited properties. + + + + 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.) + + + + + + Table per concrete class, using implicit polymorphism + + + An alternative approach is to make use of implicit polymorphism: + @@ -156,48 +284,40 @@ ]]> - Three tables were required. Notice that nowhere do we - mention the Payment interface explicitly. - Instead, we make use of Hibernate's implicit - polymorphism. Also notice that properties of - Payment are mapped in each of the - subclasses. + Notice that nowhere do we mention the Payment interface + explicitly. Also notice that properties of Payment are + mapped in each of the subclasses. + + + + The disadvantage of this approach is that Hibernate does not generate SQL + UNIONs when performing polymorphic queries. - In this case, a polymorphic association to Payment - is mapped using <any>. + For this mapping strategy, a polymorphic association to Payment + is usually mapped using <any>. - + + + + ]]> - - It would be better if we defined a UserType - as the meta-type, to handle the mapping from - type discriminator strings to Payment subclass. - + - - - -]]> + + 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 table-per-class - or table-per-subclass inheritance hierarchy! (And you can - still use polymorphic queries against the - Payment interface.) + 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.) @@ -237,10 +357,8 @@ CashPayment and ChequePayment but not instances of NonelectronicTransaction. - - - TODO: Document union-subclass for polymorphic-table-per-concrete-class mappings - + + @@ -249,13 +367,13 @@ There are certain limitations to the "implicit polymorphism" approach to - the table-per-concrete-class mapping strategy. There are somewhat less + the table per concrete-class mapping strategy. There are somewhat less restrictive limitations to <union-subclass> - mappings. (TODO) + mappings. - The following table shows the limitations of table-per-concrete-class + The following table shows the limitations of table per concrete-class mappings, and of implicit polymorphism, in Hibernate. @@ -285,7 +403,7 @@ - table-per-class-hierarchy + table per class-hierarchy <many-to-one> <one-to-one> <one-to-many> @@ -296,7 +414,7 @@ supported - table-per-subclass + table per subclass <many-to-one> <one-to-one> <one-to-many> @@ -307,18 +425,7 @@ supported - table-per-concrete-class (implicit polymorphism) - <any> - not supported - not supported - <many-to-any> - use a query - from Payment p - not supported - not supported - - - table-per-concrete-class (union-subclass) + table per concrete-class (union-subclass) <many-to-one> <one-to-one> <one-to-many> (for inverse="true" only) @@ -328,6 +435,17 @@ from Order o join o.payment p supported + + table per concrete class (implicit polymorphism) + <any> + not supported + not supported + <many-to-any> + s.createCriteria(Payment.class).add( Restrictions.idEq(id) ).uniqueResult() + from Payment p + not supported + not supported +