在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 当他们有意义的时候可以定义属性. 再一次强调 该结构映射于注释的结构.在描述注释的一章中 你可以找到所有的语义信息.