Hyperjaxb3 Reference - Customizations

There are many ways to express object constructs, properties and associations relationally. Hyperjaxb3 is built with flexibility in mind - it provides well developed means for customization.

Hyperjaxb3 customizations are defined in XML form. There is an XML Schema for customizations
which describes all the cusomization elements. This schema relies on orm_1_0.xsd and persistence_1_0.xsd schemas defined in the JPA specifications. Below are links to these schemas:

In order to customize the mapping of certain XML Schema type, element or attribute you need to attach the appropriate customization element (or elements) to the target construct. You can do this directly in schema or in an external bindings file (*.xjb). Here's how.

Declare Hyperjaxb3 customization namespace

First of all, you need to declare Hyperjaxb3 customization namespace (http://hyperjaxb3.jvnet.org/ejb/schemas/customizations).

If you make your declarations directly in schema, declare the namespace and list the declared prefix in jaxb:extensionBindingPrefixes attribute:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
	xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"

	xmlns:hj="http://hyperjaxb3.jvnet.org/ejb/schemas/customizations"
	xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"

	xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
 
	jaxb:extensionBindingPrefixes="xjc hj"
	jaxb:version="2.0">

	<!-- ... -->

</xs:schema>

In the example above Hyperjaxb3 customization namespace declared next to the XJC. Basically, Hyperjaxb3's customizations are just further vendor extensions.

Note that you will probably also need to define the orm namespace since Hyperjaxb3 customization elements often contain sub-elements from this namespace. You do not need to include orm into jaxb:extensionBindingPrefixes.

If you're using an external bindings file, you have to do exactly the same declarations on the root jaxb:bindings element:

<jaxb:bindings
	version="2.1"
	xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
	xmlns:xs="http://www.w3.org/2001/XMLSchema"
	xmlns:hj="http://hyperjaxb3.jvnet.org/ejb/schemas/customizations"
	xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"

	jaxb:extensionBindingPrefixes="hj">
	<!-- ... -->
</jaxb:bindings>

Declare customization elements

Now when the customization namespace is declared, you can attach customization elements where they belong.

If you are declaring your customizations the the XML Schema itself, use xs:annotation/xs:appinfo elements. For instance, the following declaration wil mark the ignoredType as ignored - Hyperjaxb3 will not generate any annotations in the corresponding derived class. It won't be included in the persistence unit as well.

<xs:complexType name="ignoredType">
	<xs:annotation>
		<xs:appinfo>
			<hj:ignored/>
		</xs:appinfo>
	</xs:annotation>
	<!-- ... -->
</xs:complexType>

You may also declare your customization in an external bindings file, linking customization elements to target constructs via XPath or SCD (schema component descriptors) TODO.

XPath locations are provided in the jaxb:bindings/@node attribute. In the example below we customize table and column names and mark the partNum attribute of the Items type as an identifier (primary key of the entity).

<jaxb:bindings schemaLocation="schema.xsd" node="/xs:schema">
	<jaxb:bindings node="xs:complexType[@name='PurchaseOrderType']">
		<hj:entity>
			<orm:table name="po"/>
		</hj:entity>
	</jaxb:bindings>
	<jaxb:bindings node="xs:complexType[@name='USAddress']">
		<hj:entity>
			<orm:table name="address"/>
		</hj:entity>
	</jaxb:bindings>
	<jaxb:bindings node="xs:complexType[@name='Items']//xs:complexType">
		<hj:entity>
			<orm:table name="item"/>
		</hj:entity>
	</jaxb:bindings>
	<jaxb:bindings node="xs:complexType[@name='Items']//xs:attribute[@name='partNum']">
		<hj:id/>
	</jaxb:bindings>
	<jaxb:bindings node="xs:complexType[@name='Items']//xs:element[@name='USPrice']">
		<hj:basic>
			<orm:column name="Price"/>
		</hj:basic>
	</jaxb:bindings>
</jaxb:bindings>

See the full bindings.xjb from the ejb/tests/po-customized test.

Global customizations

If you want to apply a customization globally - for instance customize all the one-to-many mappings at once, include a hj:persistence element into the schema customizations. This element contains sub-elements like hj:default-one-to-many or hj:default-many-to-one etc. which define default mappings for the corresponding cases.

For instance, if you want one-to-many to be mapped with a join table (instead of a join column by default), include the following definition:

<xs:schema
	xmlns:xs="http://www.w3.org/2001/XMLSchema" ...>

	<xs:annotation>
		<xs:appinfo>
			<hj:persistence>
				<hj:default-one-to-many>
					<orm:join-table/>
				</hj:default-one-to-many>
			</hj:persistence>
		</xs:appinfo>
	</xs:annotation>
	<!-- ... -->
</xs:schema>

Actually, Hyperaxb3 stores such default mapings in a similar resource internally, so what you in fact do with the schema-wide customization described above is override internal definitions.

Here's another example. By default complex single properties are mapped as many-to-one, complex collection properties as one-to-many (as defined in DefaultCustomizations.xml). You can easily change these defaults to one-to-one and many-to-many:

<hj:persistence>
	<hj:default-to-one>
		<hj:one-to-one/>
	</hj:default-to-one>
	<hj:default-to-many>
		<hj:many-to-many/>
	</hj:default-to-many>
</hj:persistence>

For more examples of customizations check the schema from the ejb/tests/cu-one test and other ejb/tests.