Hibernate.org社区文档

第 3 章。通过 XML 覆盖元数据

3.1. 原则
3.1.1. 全局级别元数据
3.1.2. 实体级别元数据
3.1.3. 属性级别元数据
3.1.4. 关联级别元数据

EJB3 中元数据的首要目标是注释,但是 EJB3 规范提供了一种方法,可以通过 XML 部署描述符来覆盖或替换注释中定义的元数据。在当前版本中,仅支持纯 EJB3 注释覆盖。如果您希望在某些实体中使用 Hibernate 特定功能,则必须使用注释或退回到 hbm 文件。您当然可以在 hbm 文件中混合匹配带注释的实体和实体说明。

单元测试套件显示了一些其他 XML 文件示例。

XML 部署描述符结构经过设计来反映注释结构。因此,如果您了解注释结构,则使用 XML 架构对您来说将非常简单。

您可以定义一个或多个 XML 文件来描述元数据,这些文件将由覆盖引擎合并。

您可以定义或覆盖给定实体上的元数据信息。

<?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 是所有 XML 文件的根元素。您必须声明 XML 模式,模式文件包含在 hibernate-annotations.jar 文件中,Hibernate Annotations 将处理任何 Internet 访问。

2

package(可选):用于给定部署描述符文件中所有不合格类名的默认包。

3

entity:描述一个实体。

metadata-complete 定义此元素的元数据说明是否完整(换句话说,是否应考虑类级别存在的注释)。

一个实体必须有一个 class 属性,该属性引用应用元数据的 Java 类。

name 属性中可以覆盖实体名称,如果没有定义并且存在 @Entity.name,则会使用它(前提是未设置元数据的完整性)。

对于元数据完整(见下文)元素,可以定义 访问FIELDPROPERTY(默认))。对于非元数据完整元素,如果没有定义 访问,@Id 位置将引导位置,如果定义了 访问,则会使用该值。

4

:可以声明表属性(名称、架构、目录),如果没有定义,则使用 Java 注解。

可以定义一个或多个唯一约束,如示例所示

5

辅助表:定义辅助表非常类似于普通表,不同之处在于可以通过 主键外键列 元素定义主键/外键列。在非元数据完整的表中,只有在没有 辅助表 定义的情况下,才使用注解辅助表,否则将忽略注解。

6

ID 类:以类似于 @IdClass 的方式定义 ID 类

7

继承:定义继承策略(JOINEDTABLE_PER_CLASSSINGLE_TABLE),仅在根实体级别可用

8

序列生成器:定义序列生成器

9

表生成器:定义表生成器

10

主键外键列:当使用 JOINED 继承策略时,定义子实体的主键外键列

<?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

鉴别器值/鉴别器列:定义鉴别器值以及当选择 SINGLE_TABLE 继承策略时保存它的列

2

命名查询:定义命名查询以及可能与它们关联的提示。这些定义是注解中定义的定义的补充,如果两个定义具有相同的名称,则 XML 定义具有更高的优先级。

3

命名的原生查询:定义命名的原生查询及其 SQL 结果集映射。还可以定义 结果类。这些定义是注解中定义的定义的补充,如果两个定义具有相同的名称,则 XML 定义具有更高的优先级。

4

SQL 结果集映射:描述结果集映射结构。可以定义实体和列映射。这些定义是注解中定义的定义的补充,如果两个定义具有相同的名称,则 XML 定义具有更高的优先级

5

属性覆盖/关联覆盖:定义列或外键列覆盖。此覆盖是注解中定义的覆盖的补充

同样的规则适用于 <可嵌入的><映射的超类>

当然,您可以定义属性的 XML 覆盖。如果定义元数据完成,则会忽略其他属性(即在 Java 级别)。否则,一旦开始覆盖属性,则会忽略给定属性上的所有注释。所有属性级别元数据在 实体/属性映射超级类/属性可嵌入/属性 中的行为相同。


    <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>

您可以通过 idembedded-idversionembeddedbasic 覆盖属性。每个元素都可以有相应的子元素:lobtemporalenumeratedcolumn

您可以定义关联的 XML 覆盖。所有关联级别元数据在 实体/属性映射超级类/属性可嵌入/属性 中的行为相同。


    <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>

您可以通过 one-to-manyone-to-onemany-to-onemany-to-many 覆盖关联。每个元素都可以有相应的子元素:join-table(可以有 join-columninverse-join-column)、join-columnsmap-keyorder-by。如果合理,mapped-bytarget-entity 可以定义为属性。结构再次反映注释结构。您可以在描述注释的章节中找到所有语义信息。