HyperJaxb is a Jaxb plugin that creates classes that are:
HyperJaxb permits then to have Jaxb + Jpa in one API.
JAXB vs. JPA - JAXB is not 100% compatible with JPA
Hyperjaxb3 is a code generator. It provides a JAXB 2 plugin which participates in JAXB's code generation - and produces all necessary JPA annotations as well as the supporting code to make the class JAXB and JPA compatible.
From the XML Schema Primer, download the purchase order schema example:
Download the basic project templates for Ant (hyperjaxb3-ejb-template-basic-0.5.6-ant-src.zip)
ant clean install
Buildfile: D:\workspace\HyperJaxb2\build.xml
clean:
generate-sources:
[mkdir] Created dir: D:\workspace\HyperJaxb2\target\generated-sources\xjc
[xjc] Consider using <depends>/<produces> so that XJC won't do unnecessary compilation
[xjc] Compiling file:/D:/workspace/HyperJaxb2/src/main/resources/po.xsd
[xjc] Writing output to D:\workspace\HyperJaxb2\target\generated-sources\xjc
compile:
[mkdir] Created dir: D:\workspace\HyperJaxb2\target\classes
[javac] D:\workspace\HyperJaxb2\build.xml:142: warning: 'includeantruntime' was not set, default
ing to build.sysclasspath=last; set to false for repeatable builds
[javac] Compiling 5 source files to D:\workspace\HyperJaxb2\target\classes
[copy] Copying 3 files to D:\workspace\HyperJaxb2\target\classes
test-compile:
[mkdir] Created dir: D:\workspace\HyperJaxb2\target\test-classes
[javac] D:\workspace\HyperJaxb2\build.xml:158: warning: 'includeantruntime' was not set, default
ing to build.sysclasspath=last; set to false for repeatable builds
[javac] Compiling 5 source files to D:\workspace\HyperJaxb2\target\test-classes
[copy] Copying 3 files to D:\workspace\HyperJaxb2\target\test-classes
test:
[mkdir] Created dir: D:\workspace\HyperJaxb2\target\junit-reports
[junit] Running RoundtripTest
[junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 1.372 sec
package:
[jar] Building jar: D:\workspace\HyperJaxb2\target\hyperjaxb3-ejb-template-basic-ant-0.5.6.jar
install:
BUILD SUCCESSFUL
Total time: 9 seconds
We got produced from the XJC schema compiler and Hyperjaxb3 plugin:
The class contains @Entity, @Table, @ManyToOne and few other annotations generated by the Hyperjaxb3 plugin. These annotations turn this class into an entity which can be persisted with JPA.
Persistence.xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence version="1.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd
http://java.sun.com/xml/ns/persistence/orm
http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<persistence-unit name="generated">
<class>generated.Items</class>
<class>generated.Items$Item</class>
<class>generated.PurchaseOrderType</class>
<class>generated.USAddress</class>
</persistence-unit>
</persistence>
// Context with the package name of the generated class as parameter
context = JAXBContext.newInstance("generated");
// A context with the class name of the root element is also possible
context = JAXBContext.newInstance(PurchaseOrderType.class);
// Creation of an Unmarshaller
final Unmarshaller unmarshaller = context.createUnmarshaller();
// The Unmarshaller unmarshal
final Object object = unmarshaller.unmarshal(new File("src/test/samples/po.xml"));
// With a cast, we retrieve the final object (data type)
@SuppressWarnings("unchecked")
final PurchaseOrderType purchaseOrder = ((JAXBElement<PurchaseOrderType>) object).getValue();
// Test
System.out.println("Purchase Order Comment "+purchaseOrder.getComment());
An instance of the generated ObjectFactory is only needed to create objects (to marshall).Creation of an entity manager factory by passing:
You can define the database connection in the persistence unit itself but to keep ORM mappings should be generic, case-specific. They are be kept separately.
final Properties persistenceProperties = new Properties();
InputStream is = null;
try {
is = getClass().getClassLoader().getResourceAsStream("persistence.properties");
persistenceProperties.load(is);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ignored) {
}
}
}
entityManagerFactory = Persistence.createEntityManagerFactory(
"generated", persistenceProperties);
persistence.properties are database and JPA provider specific. See: JPA - Persistence Properties
/**
*
*/
package main.java;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import generated.ObjectFactory;
import generated.PurchaseOrderType;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
/**
* @author gerard
*
*/
public class Main {
private static JAXBContext context;
private static EntityManagerFactory entityManagerFactory;
/**
* @param args
* @throws JAXBException
* @throws IOException
*/
public static void main(String[] args) throws JAXBException, IOException {
context = JAXBContext.newInstance("generated");
new ObjectFactory();
// Unmarshaller
final Unmarshaller unmarshaller = context.createUnmarshaller();
// Unmarshal
final Object object = unmarshaller.unmarshal(new File("src/test/samples/po.xml"));
// Cast
@SuppressWarnings("unchecked")
final PurchaseOrderType purchaseOrder = ((JAXBElement<PurchaseOrderType>) object).getValue();
System.out.println("Purchase Order Comment "+purchaseOrder.getComment());
final Properties persistenceProperties = new Properties();
InputStream is = null;
try {
is = new FileInputStream("src/resources/persistence.properties");
persistenceProperties.load(is);
} finally {
if (is != null) {
is.close();
}
}
System.out.println("Url "+persistenceProperties.getProperty("hibernate.connection.url"));
entityManagerFactory = Persistence.createEntityManagerFactory(
"generated", persistenceProperties);
final EntityManager saveManager = entityManagerFactory
.createEntityManager();
saveManager.getTransaction().begin();
saveManager.persist(purchaseOrder);
saveManager.getTransaction().commit();
saveManager.close();
final Long id = purchaseOrder.getHjid();
System.out.println("Purchase Order Id "+id);
}
}
Purchase Order Comment Hurry, my lawn is going wild!
Url jdbc:oracle:thin:@//localhost:1521/orcl.HotITem.local
Purchase Order Id 1
The fact that it doesn't unmarshal, is clear in the error message: it expects a no-namespace element <{}Repository> as opposed to <{uri:“http://www.oracle.com/obis/repository”}Repository>.
Exception in thread "main" javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.oracle.com/obis/repository", local:"BusinessModel"). Expected elements are <{}Repository>
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:662)