diff --git a/documentation/manual/src/main/docbook/en-US/content/basic_mapping.xml b/documentation/manual/src/main/docbook/en-US/content/basic_mapping.xml index c8ddb7aba8..9b5523542d 100644 --- a/documentation/manual/src/main/docbook/en-US/content/basic_mapping.xml +++ b/documentation/manual/src/main/docbook/en-US/content/basic_mapping.xml @@ -455,20 +455,20 @@ public class Flight implements Serializable { - polymorphism (defaults to + polymorphisms (defaults to IMPLICIT): determines whether implicit or - explicit query polymorphism is used. Implicit - polymorphism means that instances of the class will be returned by a - query that names any superclass or implemented interface or class, + explicit query polymorphisms is used. Implicit + polymorphisms means that instances of the class will be returned by + a query that names any superclass or implemented interface or class, and that instances of any subclass of the class will be returned by a query that names the class itself. Explicit - polymorphism means that class instances will be returned only by + polymorphisms means that class instances will be returned only by queries that explicitly name that class. Queries that name the class will return only instances of subclasses mapped. For most purposes, - the default polymorphism=IMPLICIT is appropriate. - Explicit polymorphism is useful when two different classes are - mapped to the same table This allows a "lightweight" class that - contains a subset of the table columns. + the default polymorphisms=IMPLICIT is + appropriate. Explicit polymorphisms is useful when two different + classes are mapped to the same table This allows a "lightweight" + class that contains a subset of the table columns. @@ -727,9 +727,9 @@ public class Summary { - polymorphism (optional - defaults to + polymorphisms (optional - defaults to implicit): determines whether implicit or - explicit query polymorphism is used. + explicit query polymorphisms is used. @@ -2154,34 +2154,179 @@ public class Customer implements Serializable { -
- Discriminator +
+ Inheritance strategy - The <discriminator> element is required - for polymorphic persistence using the table-per-class-hierarchy mapping - strategy. It declares a discriminator column of the table. The - discriminator column contains marker values that tell the persistence - layer what subclass to instantiate for a particular row. A restricted - set of types can be used: string, - character, integer, - byte, short, - boolean, yes_no, - true_false. + Java is a language supporting polymorphism: a class can inherit + from another. Several strategies are possible to persist a class + hierarchy: - - - + + + Single table per class hierarchy strategy: a single table + hosts all the instances of a class hierarchy + - + + Joined subclass strategy: one table per class and subclass is + present and each table persist the properties specific to a given + subclass. The state of the entity is then stored in its + corresponding class table and all its superclasses + - + + Table per class strategy: one table per concrete class and + subclass is present and each table persist the properties of the + class and its superclasses. The state of the entity is then stored + entirely in the dedicated table for its class. + + - +
+ Single table per class hierarchy strategy - - + With this approach the properties of all the subclasses in a + given mapped class hierarchy are stored in a single table. - <discriminator + Each subclass declares its own persistent properties and + subclasses. Version and id properties are assumed to be inherited from + the root class. Each subclass in a hierarchy must define a unique + discriminator value. If this is not specified, the fully qualified + Java class name is used. + + @Entity +@Inheritance(strategy=InheritanceType.SINGLE_TABLE) +@DiscriminatorColumn( + name="planetype", + discriminatorType=DiscriminatorType.STRING +) +@DiscriminatorValue("Plane") +public class Plane { ... } + +@Entity +@DiscriminatorValue("A320") +public class A320 extends Plane { ... } + + In hbm.xml, for the table-per-class-hierarchy mapping strategy, + the <subclass> declaration is used. For + example: + + + + + + + + + + + + + <subclass + name="ClassName" + discriminator-value="discriminator_value" + proxy="ProxyInterface" + lazy="true|false" + dynamic-update="true|false" + dynamic-insert="true|false" + entity-name="EntityName" + node="element-name" + extends="SuperclassName"> + + <property .... /> + ..... +</subclass> + + + + name: the fully qualified class name of + the subclass. + + + + discriminator-value (optional - + defaults to the class name): a value that distinguishes + individual subclasses. + + + + proxy (optional): specifies a class or + interface used for lazy initializing proxies. + + + + lazy (optional - defaults to + true): setting + lazy="false" disables the use of lazy + fetching. + + + + + For information about inheritance mappings see . + +
+ Discriminator + + Discriminators are required for polymorphic persistence using + the table-per-class-hierarchy mapping strategy. It declares a + discriminator column of the table. The discriminator column contains + marker values that tell the persistence layer what subclass to + instantiate for a particular row. A restricted set of types can be + used: string, character, + integer, byte, + short, boolean, + yes_no, true_false. + + Use the @DiscriminatorColumn to define + the discriminator column as well as the discriminator type. + Alternatively, you can also use + @DiscriminatorFormula to express in SQL what + would be in a virtual discriminator column. This is particularly + handy when the discriminator value can be extracted from one or more + columns of the table. Both + @DiscriminatorColumn and + @DiscriminatorFormula are to be set on the + root entity (once per persisted hierarchy). + + Finally, use @DiscriminatorValue on + each class of the hierarchy to specify the value stored in the + discriminator column for a given entity. If you do not set + @DiscriminatorValue on a class, the fully + qualified class name is used. + + @Entity +@Inheritance(strategy=InheritanceType.SINGLE_TABLE) +@DiscriminatorColumn( + name="planetype", + discriminatorType=DiscriminatorType.STRING +) +@DiscriminatorValue("Plane") +public class Plane { ... } + +@Entity +@DiscriminatorValue("A320") +public class A320 extends Plane { ... } + + In hbm.xml, the <discriminator> + element is used to define the discriminator column or + formula: + + + + + + + + + + + + + + + <discriminator column="discriminator_column" type="discriminator_type" force="true|false" @@ -2189,58 +2334,548 @@ public class Customer implements Serializable { formula="arbitrary sql expression" /> - - - column (optional - defaults to - class): the name of the discriminator - column. - + + + column (optional - defaults to + class): the name of the discriminator + column. + - - type (optional - defaults to - string): a name that indicates the Hibernate - type - + + type (optional - defaults to + string): a name that indicates the + Hibernate type + - - force (optional - defaults to - false): "forces" Hibernate to specify the - allowed discriminator values, even when retrieving all instances - of the root class. - + + force (optional - defaults to + false): "forces" Hibernate to specify the + allowed discriminator values, even when retrieving all + instances of the root class. + - - insert (optional - defaults to - true): set this to false if - your discriminator column is also part of a mapped composite - identifier. It tells Hibernate not to include the column in SQL - INSERTs. - + + insert (optional - defaults to + true): set this to false + if your discriminator column is also part of a mapped + composite identifier. It tells Hibernate not to include the + column in SQL INSERTs. + - - formula (optional): an arbitrary SQL - expression that is executed when a type has to be evaluated. It - allows content-based discrimination. - - - + + formula (optional): an arbitrary SQL + expression that is executed when a type has to be evaluated. + It allows content-based discrimination. + + + - Actual values of the discriminator column are specified by the - discriminator-value attribute of the - <class> and <subclass> - elements. + Actual values of the discriminator column are specified by the + discriminator-value attribute of the + <class> and + <subclass> elements. - The force attribute is only useful if the table - contains rows with "extra" discriminator values that are not mapped to a - persistent class. This will not usually be the case. + The force attribute is only useful if the + table contains rows with "extra" discriminator values that are not + mapped to a persistent class. This will not usually be the + case. - The formula attribute allows you to declare an - arbitrary SQL expression that will be used to evaluate the type of a - row. For example: + The formula attribute allows you to declare + an arbitrary SQL expression that will be used to evaluate the type + of a row. For example: - <discriminator + <discriminator formula="case when CLASS_TYPE in ('a', 'b', 'c') then 0 else 1 end" type="integer"/> +
+
+ +
+ Joined subclass strategy + + Each subclass can also be mapped to its own table. This is + called the table-per-subclass mapping strategy. An inherited state is + retrieved by joining with the table of the superclass. A discriminator + column is not required for this mapping strategy. Each subclass must, + however, declare a table column holding the object identifier. The + primary key of this table is also a foreign key to the superclass + table and described by the + @PrimaryKeyJoinColumns or the + <key> element. + + @Entity @Table(name="CATS") +@Inheritance(strategy=InheritanceType.JOINED) +public class Cat implements Serializable { + @Id @GeneratedValue(generator="cat-uuid") + @GenericGenerator(name="cat-uuid", strategy="uuid") + String getId() { return id; } + + ... +} + +@Entity @Table(name="DOMESTIC_CATS") +@PrimaryKeyJoinColumn(name="CAT") +public class DomesticCat extends Cat { + public String getName() { return name; } +} + + + The table name still defaults to the non qualified class name. + Also if @PrimaryKeyJoinColumn is not set, the + primary key / foreign key columns are assumed to have the same names + as the primary key columns of the primary table of the + superclass. + + + In hbm.xml, use the <joined-subclass> + element. For example: + + + + + + + + + + + + + <joined-subclass + name="ClassName" + table="tablename" + proxy="ProxyInterface" + lazy="true|false" + dynamic-update="true|false" + dynamic-insert="true|false" + schema="schema" + catalog="catalog" + extends="SuperclassName" + persister="ClassName" + subselect="SQL expression" + entity-name="EntityName" + node="element-name"> + + <key .... > + + <property .... /> + ..... +</joined-subclass> + + + + name: the fully qualified class name of + the subclass. + + + + table: the name of the subclass + table. + + + + proxy (optional): specifies a class or + interface to use for lazy initializing proxies. + + + + lazy (optional, defaults to + true): setting + lazy="false" disables the use of lazy + fetching. + + + + + Use the <key> element to declare the + primary key / foreign key column. The mapping at the start of the + chapter would then be re-written as: + + <?xml version="1.0"?> +<!DOCTYPE hibernate-mapping PUBLIC + "-//Hibernate/Hibernate Mapping DTD//EN" + "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> + +<hibernate-mapping package="eg"> + + <class name="Cat" table="CATS"> + <id name="id" column="uid" type="long"> + <generator class="hilo"/> + </id> + <property name="birthdate" type="date"/> + <property name="color" not-null="true"/> + <property name="sex" not-null="true"/> + <property name="weight"/> + <many-to-one name="mate"/> + <set name="kittens"> + <key column="MOTHER"/> + <one-to-many class="Cat"/> + </set> + <joined-subclass name="DomesticCat" table="DOMESTIC_CATS"> + <key column="CAT"/> + <property name="name" type="string"/> + </joined-subclass> + </class> + + <class name="eg.Dog"> + <!-- mapping for Dog could go here --> + </class> + +</hibernate-mapping> + + For information about inheritance mappings see . +
+ +
+ Table per class strategy + + A third option is to map only the concrete classes of an + inheritance hierarchy to tables. This is called the + table-per-concrete-class strategy. Each table defines all persistent + states of the class, including the inherited state. In Hibernate, it + is not necessary to explicitly map such inheritance hierarchies. You + can map each class as a separate entity root. However, if you wish use + polymorphic associations (e.g. an association to the superclass of + your hierarchy), you need to use the union subclass mapping. + + @Entity +@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) +public class Flight implements Serializable { ... } + + Or in hbm.xml: + + + + + + + + + + + + + <union-subclass + name="ClassName" + table="tablename" + proxy="ProxyInterface" + lazy="true|false" + dynamic-update="true|false" + dynamic-insert="true|false" + schema="schema" + catalog="catalog" + extends="SuperclassName" + abstract="true|false" + persister="ClassName" + subselect="SQL expression" + entity-name="EntityName" + node="element-name"> + + <property .... /> + ..... +</union-subclass> + + + + name: the fully qualified class name of + the subclass. + + + + table: the name of the subclass + table. + + + + proxy (optional): specifies a class or + interface to use for lazy initializing proxies. + + + + lazy (optional, defaults to + true): setting + lazy="false" disables the use of lazy + fetching. + + + + + No discriminator column or key column is required for this + mapping strategy. + + For information about inheritance mappings see . +
+ +
+ Inherit properties from superclasses + + This is sometimes useful to share common properties through a + technical or a business superclass without including it as a regular + mapped entity (ie no specific table for this entity). For that purpose + you can map them as @MappedSuperclass. + + @MappedSuperclass +public class BaseEntity { + @Basic + @Temporal(TemporalType.TIMESTAMP) + public Date getLastUpdate() { ... } + public String getLastUpdater() { ... } + ... +} + +@Entity class Order extends BaseEntity { + @Id public Integer getId() { ... } + ... +} + + In database, this hierarchy will be represented as an + Order table having the id, + lastUpdate and lastUpdater + columns. The embedded superclass property mappings are copied into + their entity subclasses. Remember that the embeddable superclass is + not the root of the hierarchy though. + + + Properties from superclasses not mapped as + @MappedSuperclass are ignored. + + + + The default access type (field or methods) is used, unless you + use the @Access annotation. + + + + The same notion can be applied to + @Embeddable objects to persist properties from + their superclasses. You also need to use + @MappedSuperclass to do that (this should not be + considered as a standard EJB3 feature though) + + + + It is allowed to mark a class as + @MappedSuperclass in the middle of the mapped + inheritance hierarchy. + + + + Any class in the hierarchy non annotated with + @MappedSuperclass nor @Entity + will be ignored. + + + You can override columns defined in entity superclasses at the + root entity level using the @AttributeOverride + annotation. + + @MappedSuperclass +public class FlyingObject implements Serializable { + + public int getAltitude() { + return altitude; + } + + @Transient + public int getMetricAltitude() { + return metricAltitude; + } + + @ManyToOne + public PropulsionType getPropulsion() { + return metricAltitude; + } + ... +} + +@Entity +@AttributeOverride( name="altitude", column = @Column(name="fld_altitude") ) +@AssociationOverride( + name="propulsion", + joinColumns = @JoinColumn(name="fld_propulsion_fk") +) +public class Plane extends FlyingObject { + ... +} + + The altitude property will be persisted in an + fld_altitude column of table + Plane and the propulsion association will be + materialized in a fld_propulsion_fk foreign key + column. + + You can define @AttributeOverride(s) and + @AssociationOverride(s) on + @Entity classes, + @MappedSuperclass classes and properties pointing + to an @Embeddable object. + + In hbm.xml, simply map the properties of the superclass in the + <class> element of the entity that needs to + inherit them. +
+ +
+ Mapping one entity to several tables + + While not recommended for a fresh schema, some legacy databases + force your to map a single entity on several tables. + + Using the @SecondaryTable or + @SecondaryTables class level annotations. To + express that a column is in a particular table, use the + table parameter of @Column or + @JoinColumn. + + @Entity +@Table(name="MainCat") +@SecondaryTables({ + @SecondaryTable(name="Cat1", pkJoinColumns={ + @PrimaryKeyJoinColumn(name="cat_id", referencedColumnName="id") + ), + @SecondaryTable(name="Cat2", uniqueConstraints={@UniqueConstraint(columnNames={"storyPart2"})}) +}) +public class Cat implements Serializable { + + private Integer id; + private String name; + private String storyPart1; + private String storyPart2; + + @Id @GeneratedValue + public Integer getId() { + return id; + } + + public String getName() { + return name; + } + + @Column(table="Cat1") + public String getStoryPart1() { + return storyPart1; + } + + @Column(table="Cat2") + public String getStoryPart2() { + return storyPart2; + } +} + + In this example, name will be in + MainCat. storyPart1 will be in + Cat1 and storyPart2 will be in + Cat2. Cat1 will be joined to + MainCat using the cat_id as a + foreign key, and Cat2 using id + (ie the same column name, the MainCat id column + has). Plus a unique constraint on storyPart2 has + been set. + + In hbm.xml, use the <join> + element. + + + + + + + + + + + + + + + + + <join + table="tablename" + schema="owner" + catalog="catalog" + fetch="join|select" + inverse="true|false" + optional="true|false"> + + <key ... /> + + <property ... /> + ... +</join> + + + + table: the name of the joined + table. + + + + schema (optional): overrides the schema + name specified by the root + <hibernate-mapping> element. + + + + catalog (optional): overrides the + catalog name specified by the root + <hibernate-mapping> element. + + + + fetch (optional - defaults to + join): if set to join, the + default, Hibernate will use an inner join to retrieve a + <join> defined by a class or its + superclasses. It will use an outer join for a + <join> defined by a subclass. If set to + select then Hibernate will use a sequential + select for a <join> defined on a + subclass. This will be issued only if a row represents an + instance of the subclass. Inner joins will still be used to + retrieve a <join> defined by the class + and its superclasses. + + + + inverse (optional - defaults to + false): if enabled, Hibernate will not insert + or update the properties defined by this join. + + + + optional (optional - defaults to + false): if enabled, Hibernate will insert a + row only if the properties defined by this join are non-null. It + will always use an outer join to retrieve the properties. + + + + + For example, address information for a person can be mapped to a + separate table while preserving value type semantics for all + properties: + + <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> + ... + + This feature is often only useful for legacy data models. We + recommend fewer tables than classes and a fine-grained domain model. + However, it is useful for switching between inheritance mapping + strategies in a single hierarchy, as explained later. +
@@ -3270,363 +3905,6 @@ public class Customer implements Serializable { recommended.
-
- Subclass - - Polymorphic persistence requires the declaration of each subclass - of the root persistent class. For the table-per-class-hierarchy mapping - strategy, the <subclass> declaration is used. - For example: - - - - - - - - - - - - - <subclass - name="ClassName" - discriminator-value="discriminator_value" - proxy="ProxyInterface" - lazy="true|false" - dynamic-update="true|false" - dynamic-insert="true|false" - entity-name="EntityName" - node="element-name" - extends="SuperclassName"> - - <property .... /> - ..... -</subclass> - - - - name: the fully qualified class name of - the subclass. - - - - discriminator-value (optional - defaults - to the class name): a value that distinguishes individual - subclasses. - - - - proxy (optional): specifies a class or - interface used for lazy initializing proxies. - - - - lazy (optional - defaults to - true): setting lazy="false" - disables the use of lazy fetching. - - - - - Each subclass declares its own persistent properties and - subclasses. <version> and - <id> properties are assumed to be inherited - from the root class. Each subclass in a hierarchy must define a unique - discriminator-value. If this is not specified, the - fully qualified Java class name is used. - - For information about inheritance mappings see . -
- -
- Joined-subclass - - Each subclass can also be mapped to its own table. This is called - the table-per-subclass mapping strategy. An inherited state is retrieved - by joining with the table of the superclass. To do this you use the - <joined-subclass> element. For example: - - - - - - - - - - - - - <joined-subclass - name="ClassName" - table="tablename" - proxy="ProxyInterface" - lazy="true|false" - dynamic-update="true|false" - dynamic-insert="true|false" - schema="schema" - catalog="catalog" - extends="SuperclassName" - persister="ClassName" - subselect="SQL expression" - entity-name="EntityName" - node="element-name"> - - <key .... > - - <property .... /> - ..... -</joined-subclass> - - - - name: the fully qualified class name of - the subclass. - - - - table: the name of the subclass - table. - - - - proxy (optional): specifies a class or - interface to use for lazy initializing proxies. - - - - lazy (optional, defaults to - true): setting lazy="false" - disables the use of lazy fetching. - - - - - A discriminator column is not required for this mapping strategy. - Each subclass must, however, declare a table column holding the object - identifier using the <key> element. The mapping - at the start of the chapter would then be re-written as: - - <?xml version="1.0"?> -<!DOCTYPE hibernate-mapping PUBLIC - "-//Hibernate/Hibernate Mapping DTD//EN" - "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> - -<hibernate-mapping package="eg"> - - <class name="Cat" table="CATS"> - <id name="id" column="uid" type="long"> - <generator class="hilo"/> - </id> - <property name="birthdate" type="date"/> - <property name="color" not-null="true"/> - <property name="sex" not-null="true"/> - <property name="weight"/> - <many-to-one name="mate"/> - <set name="kittens"> - <key column="MOTHER"/> - <one-to-many class="Cat"/> - </set> - <joined-subclass name="DomesticCat" table="DOMESTIC_CATS"> - <key column="CAT"/> - <property name="name" type="string"/> - </joined-subclass> - </class> - - <class name="eg.Dog"> - <!-- mapping for Dog could go here --> - </class> - -</hibernate-mapping> - - For information about inheritance mappings see . -
- -
- Union-subclass - - A third option is to map only the concrete classes of an - inheritance hierarchy to tables. This is called the - table-per-concrete-class strategy. Each table defines all persistent - states of the class, including the inherited state. In Hibernate, it is - not necessary to explicitly map such inheritance hierarchies. You can - map each class with a separate <class> - declaration. However, if you wish use polymorphic associations (e.g. an - association to the superclass of your hierarchy), you need to use the - <union-subclass> mapping. For example: - - - - - - - - - - - - - <union-subclass - name="ClassName" - table="tablename" - proxy="ProxyInterface" - lazy="true|false" - dynamic-update="true|false" - dynamic-insert="true|false" - schema="schema" - catalog="catalog" - extends="SuperclassName" - abstract="true|false" - persister="ClassName" - subselect="SQL expression" - entity-name="EntityName" - node="element-name"> - - <property .... /> - ..... -</union-subclass> - - - - name: the fully qualified class name of - the subclass. - - - - table: the name of the subclass - table. - - - - proxy (optional): specifies a class or - interface to use for lazy initializing proxies. - - - - lazy (optional, defaults to - true): setting lazy="false" - disables the use of lazy fetching. - - - - - No discriminator column or key column is required for this mapping - strategy. - - For information about inheritance mappings see . -
- -
- Join - - Using the <join> element, it is possible - to map properties of one class to several tables that have a one-to-one - relationship. For example: - - - - - - - - - - - - - - - - - <join - table="tablename" - schema="owner" - catalog="catalog" - fetch="join|select" - inverse="true|false" - optional="true|false"> - - <key ... /> - - <property ... /> - ... -</join> - - - - table: the name of the joined - table. - - - - schema (optional): overrides the schema - name specified by the root - <hibernate-mapping> element. - - - - catalog (optional): overrides the catalog - name specified by the root - <hibernate-mapping> element. - - - - fetch (optional - defaults to - join): if set to join, the - default, Hibernate will use an inner join to retrieve a - <join> defined by a class or its - superclasses. It will use an outer join for a - <join> defined by a subclass. If set to - select then Hibernate will use a sequential - select for a <join> defined on a - subclass. This will be issued only if a row represents an instance - of the subclass. Inner joins will still be used to retrieve a - <join> defined by the class and its - superclasses. - - - - inverse (optional - defaults to - false): if enabled, Hibernate will not insert - or update the properties defined by this join. - - - - optional (optional - defaults to - false): if enabled, Hibernate will insert a row - only if the properties defined by this join are non-null. It will - always use an outer join to retrieve the properties. - - - - - For example, address information for a person can be mapped to a - separate table while preserving value type semantics for all - properties: - - <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> - ... - - This feature is often only useful for legacy data models. We - recommend fewer tables than classes and a fine-grained domain model. - However, it is useful for switching between inheritance mapping - strategies in a single hierarchy, as explained later. -
-
Key