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.