在EJB3中元数据的主要目标是使用注释,但是EJB3规范也提供通过XML部署文件来覆写或者替换元数据注释. 在当前的发布版本仅仅支持EJB3注释的覆写,如果你想使用Hibernate特有的一些实体注释, 你有两种选择:一,只使用注释;二,使用原来的hbm 映射文件.你当然还是可以同时使用注释实体和hbm XML映射文件的实体.
在测试套件中有一些附加的XML文件的样例.
XML部署文件结构被设计为直接映射注释结构,所以如果你知道注释的结构,那么使用XML语法是很简单的.
你可以定义一个或者多个XML文件来描述你的元数据,这些文件会被覆写引擎合并(merged).
你可以使用XML文件来定义全局元数据,对每一个部署文件你不能定义多于一个的元数据.
<?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_1_0.xsd"
version="1.0">
<persistence-unit-metadata>
<xml-mapping-metadata-complete/>
<persistence-unit-defaults>
<schema>myschema</schema>
<catalog>mycatalog</catalog>
<cascade-persist/>
</persistence-unit-defaults>
</persistence-unit-metadata>xml-mapping-metadata-complete 意味着所有的实体,mapped-superclasses和嵌套的元数据应该从XML文件中启用(忽略注释).
schema / catalog 将覆写所有在元数据中默认定义的schema 和 catalog(包括XML和注释).
cascade-persist 意味着所有注释作为一个 cascade type 都是PERSIST的. 我们推荐你不要使用该特性.
你也可以在一个给定的实体上定义或者覆写元数据
<?xml version="1.0" encoding="UTF-8"?> <entity-mappings (1) 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_1_0.xsd" version="1.0"> <package>org.hibernate.test.annotations.reflection</package> (2) <entity class="Administration" access="PROPERTY" metadata-complete="true"> (3) <table name="tbl_admin"> (4) <unique-constraint> <column-name>firstname</column-name> <column-name>lastname</column-name> </unique-constraint> </table> <secondary-table name="admin2"> (5) <primary-key-join-column name="admin_id" referenced-column-name="id"/> <unique-constraint> <column-name>address</column-name> </unique-constraint> </secondary-table> <id-class class="SocialSecurityNumber"/> (6) <inheritance strategy="JOINED"/> (7) <sequence-generator name="seqhilo" sequence-name="seqhilo"/> (8) <table-generator name="table" table="tablehilo"/> (9) ... </entity> <entity class="PostalAdministration"> <primary-key-join-column name="id"/> (10) ... </entity> </entity-mappings>
| (1) | entity-mappings:entity-mappings 是所有XML文件的根元素.你必须定义XML Schema, 该文件包含在hibernate-annotations.jar中,使用Hibernate Annotations 不需要访问网络. |
| (2) | package (可选的): 作为默认的package用于在一个给定的部署描述文件中所有没有限定的类. |
| (3) | entity: 描述一个实体. metadata-complete 定义对于该元素是否全部使用元数据(换句话来说就是,如果注释出现在类级别应该考虑或者忽略). 一个实体不得不有一个 class 属性来引用 元数据所应用的类. 通过name属性你可以覆写实体的名字, 如果没有定义并且@Entity.name出现了的话,那么就使用该注释(假如metadata complete 没有被设置). 对于metadata complete (参考下面)元素, 你可以定义一个 access(FIELD 或者 PROPERTY(默认值)), 对于非metadata complete 元素,使用注释的access type. |
| (4) | table: 你可以声明table 属性(name, schema, catalog), 如果没有定义, 将使用Java注释. 就象例子中所示的那样你可以定义一个或者多个unique constraints |
| (5) | secondary-table: 定义一个secondary-table,除了你可以通过primary-key-join-column 元素定义 primary key / foreign key 列以外是和一般的table一样的. 在非metadata complete下, annotation secondary tables 仅仅在没有secondary-table 定义的情况下使用, 否则 注释将被忽略. |
| (6) | id-class: 和@IdClass一样定义一个id class. |
| (7) | inheritance: 定义继承策略(JOINED, TABLE_PER_CLASS, SINGLE_TABLE), 仅仅在根实体级别可以使用. |
| (8) | sequence-generator: 定义一个序列产生器. |
| (9) | table-generator: 定义一个table generator |
| (10) | primary-key-join-column: 当 JOINED 继承策略使用时,为sub entities定义一个 primary key join column. |
<?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_1_0.xsd"
version="1.0">
<package>org.hibernate.test.annotations.reflection</package>
<entity class="Music" access="PROPERTY" metadata-complete="true">
<discriminator-value>Generic</discriminator-value> (1)
<discriminator-column length="34"/>
...
</entity>
<entity class="PostalAdministration">
<primary-key-join-column name="id"/>
<named-query name="adminById"> (2)
<query>select m from Administration m where m.id = :id</query>
<hint name="org.hibernate.timeout" value="200"/>
</named-query>
<named-native-query name="allAdmin" result-set-mapping="adminrs"> (3)
<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-result-set-mapping name="adminrs"> (4)
<entity-result entity-class="Administration">
<field-result name="name" column="fld_name"/>
</entity-result>
<column-result name="taxPayerNumber"/>
</sql-result-set-mapping>
<attribute-override name="ground"> (5)
<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: 当SINGLE_TABLE继承策略使用时,定义鉴别器值 和 保存该值的列. |
| (2) | named-query: 定义命名查询和一些相关的可能的线索. 该定义附加在注释的定义中,如果两个都定义了相同的名字,那么XML将优先考虑. |
| (3) | named-native-query: 定义一个命名本地查询 和他的 sql result set 映射. 作为另外一种选择,你可以定义result-class. 这些定义附加在注释的定义中.如果两个定义了同样的名字,XML文件优先考虑. |
| (4) | sql-result-set-mapping: 描述了 result set mapping 的结构. 你可以定义 实体和列映射. 这些定义附加在注释的定义中,如果定义了同样的名字,XML文件优先考虑. |
| (5) | attribute-override / association-override: 定义一列或者join column overriding. 该overriding 附加在注释的定义中. |
一些应用于 <embeddable> 和 <mapped-superclass>.
你当然可以定义XML来覆写属性. 如果metadata complete 给定义了,那么附加的属性(如: 在Java 级别的)将被忽略. 另外,一旦你开始覆写一个属性,在该属性上的所有注释都会被忽略.所有属性级别的元数据应用于entity/attributes, mapped-superclass/attributes 或 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>通过 id, embedded-id, version, embedded 和 basic你可以覆写一个属性, 这些元素中的每一个元素都有相应的subelements:lob, temporal, enumerated, column.
你可以定义XML覆写关联注释. 所有的关联级别的元数据作用于 entity/attributes, mapped-superclass/attributes 或 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>通过one-to-many, one-to-one, many-to-one, 和 many-to-many. 你可以重写一个关联关系.这些元素中的每一个都有相应的subelements. join-table (可以有 join-column和 inverse-join-column), join-column, map-key, 和 order-by. mapped-by 和 target-entity 当他们有意义的时候可以定义属性. 再一次强调 该结构映射于注释的结构.在描述注释的一章中 你可以找到所有的语义信息.