JPA 2 Support

JPA 2 support

Hyperjaxb3 supports JPA 2 since version 0.5.6.

Generating JPA 2 metadata

Use the jpa2 variant to generate JPA 2 annotations:

Maven:

<plugin>
	<groupId>org.jvnet.hyperjaxb3</groupId>
	<artifactId>maven-hyperjaxb3-plugin</artifactId>
	<configuration>
		<variant>jpa2</variant>
	</configuration>
</plugin>

Ant:

<xjc destdir="${basedir}/target/generated-sources/xjc" extension="true">
	<arg line="
		-Xhyperjaxb3-jpa2
		-Xhyperjaxb3-jpa2-roundtripTestClassName=RoundtripTest
		-Xequals
		-Xinheritance
		-XhashCode
		-XtoString"/>
	<binding dir="${basedir}/src/main/resources">
	 	<include name="**/*.xjb"/>
	</binding>
	<schema dir="${basedir}/src/main/resources">
	 	<include name="**/*.xsd"/>
	</schema>
	<classpath>
		<fileset dir="${basedir}/lib">
			<include name="*.jar"/>
		</fileset>
	</classpath>
</xjc>
Hyperjaxb3 can generate JPA 2 annotations as well as XML mapping files according to the JPA 2 according to the JPA 2 orm_2_0.xsd XML schema. Use <result>mappingFiles</result> or -Xhyperjaxb3-jpa2-result=mappingFiles configuration items accordingly.

Supported JPA 2 features

Collections of simple types

JPA 2 supports collections of simple types using the @ElementCollection annotation.
Hyperjaxb3 uses this feature to improve mapping of the repeatable simple type elements.

Example:

<xsd:complexType name="HJIII-63-Alpha">
	<xsd:sequence>
		<xsd:element name="stringElements" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
		<xsd:element name="dateElements" type="xsd:date" minOccurs="0" maxOccurs="unbounded"/>
	</xsd:sequence>
</xsd:complexType>

Generates:

    @ElementCollection
    @OrderColumn(name = "HJINDEX")
    @Column(name = "HJVALUE", length = 255)
    @CollectionTable(name = "HJIII63ALPHA_STRINGELEMENTS", joinColumns = {
        @JoinColumn(name = "HJID")
    })
    public List<String> getStringElements() { ... }


    @ElementCollection
    @OrderColumn(name = "HJINDEX")
    @Column(name = "HJVALUE", precision = 20, scale = 10)
    @CollectionTable(name = "HJIII63ALPHA_DECIMALELEMENTS", joinColumns = {
        @JoinColumn(name = "HJID")
    })
    public List<BigDecimal> getDecimalElements() { ... }

Improved embedding

In JPA 2, @Embeddable mechanism is much more powerful when compared to to JPA 1. Embeddable classes can now have complex properties, associations, collections - and even nested embeddables.
Hyperjaxb3 now supportes @Embeddable features.

Example:

	<xs:element name="unit" type="UnitType"/>

	<xs:complexType name="UnitType">
		<xs:sequence>
			<xs:element name="head" type="PersonType"/>
			<xs:element name="address" type="AddressType"/>
		</xs:sequence>
	</xs:complexType>   

	<xs:complexType name="PersonType">
		<xs:annotation>
			<xs:appinfo>
				<hj:embeddable/>
			</xs:appinfo>
		</xs:annotation>
		<xs:sequence>
			<xs:element name="name" type="xs:string"/>
			<xs:element name="address" type="AddressType"/>
		</xs:sequence>
	</xs:complexType>   

	<xs:complexType name="AddressType">
		<xs:annotation>
			<xs:appinfo>
				<hj:embeddable/>
			</xs:appinfo>
		</xs:annotation>
		<xs:sequence>
			<xs:element name="street" type="xs:string"/>
			<xs:element name="city" type="xs:string"/>
			<xs:element name="state" type="xs:string" minOccurs="0"/>
			<xs:element name="zip" type="xs:string"/>
			<xs:element name="country" type="xs:string"/>
		</xs:sequence>
	</xs:complexType>   

Note that both PersonType as well as AddressType are embeddable. Moreover, PersonType has a nested embeddable (address).

Generates:

    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name = "name", column = @Column(name = "HEAD_NAME", length = 255)),
        @AttributeOverride(name = "address.street", column = @Column(name = "HEAD_ADDRESS_STREET", length = 255)),
        @AttributeOverride(name = "address.city", column = @Column(name = "HEAD_ADDRESS_CITY", length = 255)),
        @AttributeOverride(name = "address.state", column = @Column(name = "HEAD_ADDRESS_STATE", length = 255)),
        @AttributeOverride(name = "address.zip", column = @Column(name = "HEAD_ADDRESS_ZIP", length = 255)),
        @AttributeOverride(name = "address.country", column = @Column(name = "HEAD_ADDRESS_COUNTRY", length = 255))
    })
    public PersonType getHead() { ... }

    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name = "street", column = @Column(name = "ADDRESS_STREET", length = 255)),
        @AttributeOverride(name = "city", column = @Column(name = "ADDRESS_CITY", length = 255)),
        @AttributeOverride(name = "state", column = @Column(name = "ADDRESS_STATE", length = 255)),
        @AttributeOverride(name = "zip", column = @Column(name = "ADDRESS_ZIP", length = 255)),
        @AttributeOverride(name = "country", column = @Column(name = "ADDRESS_COUNTRY", length = 255))
    })
    public AddressType getAddress() { ... }

Here's how it looks like in the database:

create table UNITTYPE (
    HJID bigint generated by default as identity (start with 1),
    ADDRESS_CITY varchar(255),
    ADDRESS_COUNTRY varchar(255),
    ADDRESS_STATE varchar(255),
    ADDRESS_STREET varchar(255),
    ADDRESS_ZIP varchar(255),
    HEAD_ADDRESS_CITY varchar(255),
    HEAD_ADDRESS_COUNTRY varchar(255),
    HEAD_ADDRESS_STATE varchar(255),
    HEAD_ADDRESS_STREET varchar(255),
    HEAD_ADDRESS_ZIP varchar(255),
    HEAD_NAME varchar(255), primary key (HJID))

Note that column names for both embeddable AddressType fields do not collide.


Browse Space

- Pages
- News
- Labels
- Attachments
- Bookmarks
- Mail
- Advanced
- Activity

Explore Confluence

- Popular Labels
- Notation Guide

Your Account

Log In

 

Other Features

Add Content