Hibernate.orgCommunity Documentation

Chapter 3. Overriding metadata through XML

3.1. Principles
3.1.1. Global level metadata
3.1.2. Entity level metadata
3.1.3. Property level metadata
3.1.4. Association level metadata

The primary target for metadata in EJB3 is annotations, but the EJB3 specification provides a way to override or replace the annotation defined metadata through an XML deployment descriptor. In the current release only pure EJB3 annotations overriding are supported. If you wish to use Hibernate specific features in some entities, you'll have to either use annotations or fallback to hbm files. You can of course mix and match annotated entities and entities describes in hbm files.

The unit test suite shows some additional XML file samples.

The XML deployment descriptor structure has been designed to reflect the annotations one. So if you know the annotations structure, using the XML schema will be straightforward for you.

You can define one or more XML files describing your metadata, these files will be merged by the overriding engine.

You can either define or override metadata informations on a given entity.

<?xml version="1.0" encoding="UTF-8"?>

<entity-mappin(1)gs 
  xmlns="http://java.sun.com/xml/ns/persistence/orm"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
  version="2.0">

    <package>o(2)rg.hibernate.test.annotations.reflection</package>
    <entity cl(3)ass="Administration" access="PROPERTY" metadata-complete="true">
        <table(4) name="tbl_admin">
            <unique-constraint>
                <column-name>firstname</column-name>
                <column-name>lastname</column-name>
            </unique-constraint>
        </table>
        <secon(5)dary-table name="admin2">
            <primary-key-join-column name="admin_id" referenced-column-name="id"/>
            <unique-constraint>
                <column-name>address</column-name>
            </unique-constraint>
        </secondary-table>
        <id-cl(6)ass class="SocialSecurityNumber"/>
        <inher(7)itance strategy="JOINED"/>
        <seque(8)nce-generator name="seqhilo" sequence-name="seqhilo"/>
        <table(9)-generator name="table" table="tablehilo"/>
        ...
    </entity>

    <entity class="PostalAdministration">
        <prima(10)ry-key-join-column name="id"/>
        ...
    </entity>
</entity-mappings>

1

entity-mappings: entity-mappings is the root element for all XML files. You must declare the xml schema, the schema file is included in the hibernate-annotations.jar file, no internet access will be processed by Hibernate Annotations.

2

package (optional): default package used for all non qualified class names in the given deployment descriptor file.

3

entity: desribes an entity.

metadata-complete defines whether the metadata description for this element is complete or not (in other words, if annotations present at the class level should be considered or not).

An entity has to have a class attribute refering the java class the metadata applies on.

You can overrides entity name through the name attribute, if none is defined and if an @Entity.name is present, then it is used (provided that metadata complete is not set).

For metadata complete (see below) element, you can define an access (either FIELD or PROPERTY (default)). For non medatada complete element, if access is not defined, the @Id position will lead position, if access is defined, the value is used.

4

table: you can declare table properties (name, schema, catalog), if none is defined, the java annotation is used.

You can define one or several unique constraints as seen in the example

5

secondary-table: defines a secondary table very much like a regular table except that you can define the primary key / foreign key column(s) through the primary-key-join-column element. On non metadata complete, annotation secondary tables are used only if there is no secondary-table definition, annotations are ignored otherwise.

6

id-class: defines the id class in a similar way @IdClass does

7

inheritance: defines the inheritance strategy (JOINED, TABLE_PER_CLASS, SINGLE_TABLE), Available only at the root entity level

8

sequence-generator: defines a sequence generator

9

table-generator: defines a table generator

10

primary-key-join-column: defines the primary key join column for sub entities when JOINED inheritance strategy is used

<?xml version="1.0" encoding="UTF-8"?>

<entity-mappings 
  xmlns="http://java.sun.com/xml/ns/persistence/orm"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
  version="2.0">

    <package>org.hibernate.test.annotations.reflection</package>
    <entity class="Music" access="PROPERTY" metadata-complete="true">
        <discr(1)iminator-value>Generic</discriminator-value>
        <discriminator-column length="34"/>
        ...
    </entity>

    <entity class="PostalAdministration">
        <primary-key-join-column name="id"/>
        <named(2)-query name="adminById">
            <query>select m from Administration m where m.id = :id</query>
            <hint name="org.hibernate.timeout" value="200"/>
        </named-query>
        <named(3)-native-query name="allAdmin" result-set-mapping="adminrs">
            <query>select *, count(taxpayer_id) as taxPayerNumber 
            from Administration, TaxPayer
            where taxpayer_admin_id = admin_id group by ...</query>
            <hint name="org.hibernate.timeout" value="200"/>
        </named-native-query>
        <sql-r(4)esult-set-mapping name="adminrs">
            <entity-result entity-class="Administration">
                <field-result name="name" column="fld_name"/>
            </entity-result>
            <column-result name="taxPayerNumber"/>
        </sql-result-set-mapping>
        <attri(5)bute-override name="ground">
            <column name="fld_ground" unique="true" scale="2"/>
        </attribute-override>
        <association-override name="referer">
            <join-column name="referer_id" referenced-column-name="id"/>
        </association-override>
        ...
    </entity>
</entity-mappings>

1

discriminator-value / discriminator-column: defines the discriminator value and the column holding it when the SINGLE_TABLE inheritance strategy is chosen

2

named-query: defines named queries and possibly the hints associated to them. Those definitions are additive to the one defined in annotations, if two definitions have the same name, the XML one has priority.

3

named-native-query: defines an named native query and its sql result set mapping. Alternatively, you can define the result-class. Those definitions are additive to the one defined in annotations, if two definitions have the same name, the XML one has priority.

4

sql-result-set-mapping: describes the result set mapping structure. You can define both entity and column mappings. Those definitions are additive to the one defined in annotations, if two definitions have the same name, the XML one has priority

5

attribute-override / association-override: defines a column or join column overriding. This overriding is additive to the one defined in annotations

Same applies for <embeddable> and <mapped-superclass>.

You can of course defines XML overriding for properties. If metadata complete is defined, then additional properties (ie at the Java level) will be ignored. Otherwise, once you start overriding a property, all annotations on the given property are ignored. All property level metadata behave in entity/attributes, mapped-superclass/attributes or embeddable/attributes.


    <attributes>
        <id name="id">
            <column name="fld_id"/>
            <generated-value generator="generator" strategy="SEQUENCE"/>
            <temporal>DATE</temporal>
            <sequence-generator name="generator" sequence-name="seq"/>
        </id>
        <version name="version"/>
        <embedded name="embeddedObject">
            <attribute-override name"subproperty">
                <column name="my_column"/>
            </attribute-override>
        </embedded>
        <basic name="status" optional="false">
            <enumerated>STRING</enumerated>
        </basic>
        <basic name="serial" optional="true">
            <column name="serialbytes"/>
            <lob/>
        </basic>
        <basic name="terminusTime" fetch="LAZY">
            <temporal>TIMESTAMP</temporal>
        </basic>
    </attributes>

You can override a property through id, embedded-id, version, embedded and basic. Each of these elements can have subelements accordingly: lob, temporal, enumerated, column.

You can define XML overriding for associations. All association level metadata behave in entity/attributes, mapped-superclass/attributes or embeddable/attributes.


    <attributes>
        <one-to-many name="players" fetch="EAGER">
            <map-key name="name"/>
            <join-column name="driver"/>
            <join-column name="number"/>
        </one-to-many>
        <many-to-many name="roads" target-entity="Administration">
            <order-by>maxSpeed</order-by>
            <join-table name="bus_road">
                <join-column name="driver"/>
                <join-column name="number"/>
                <inverse-join-column name="road_id"/>
                <unique-constraint>
                    <column-name>driver</column-name>
                    <column-name>number</column-name>
                </unique-constraint>
            </join-table>
        </many-to-many>
        <many-to-many name="allTimeDrivers" mapped-by="drivenBuses">
    </attributes>

You can override an association through one-to-many, one-to-one, many-to-one, and many-to-many. Each of these elements can have subelements accordingly: join-table (which can have join-columns and inverse-join-columns), join-columns, map-key, and order-by. mapped-by and target-entity can be defined as attributes when it makes sense. Once again the structure is reflects the annotations structure. You can find all semantic informations in the chapter describing annotations.