I am using Hyperjaxb to generate my JPA mappings. Then I use hibernate3-maven-plugin to generate the SQL Script of the database. My problem lies in the fact that I have a type that has a property defined like this:
<xsd:element name="priority" type="xsd:boolean"/>
The sql script defines the column like this
PRIORITY bit,
And the JPA entity defines it like this
/**
* Obtient la valeur de la propriété priority.
*
*/
#Basic
#Column(name = "PRIORITY")
public boolean isPriority() {
return priority;
}
/**
* Définit la valeur de la propriété priority.
*
*/
public void setPriority(boolean value) {
this.priority = value;
}
I am using MySql as a backend. The problem raises when my JPA/Hibernate entityManager tries to validate my JPA model against the database. Then I get this error
org.hibernate.HibernateException: Wrong column type in custom.sample_type for column PRIORITY. Found: bit, expected: boolean
How can I fix this error? Somewhere I read I could do something like this in java code
#Basic
#Column(name = "B", columnDefinition = "BIT", length = 1)
public boolean isB() {
return b;
}
But my JPA java code is autogenerated by Hyperjaxb, so how can I achieve something like that with Hyperjaxb?
Disclaimer: I am the author of Hyperjaxb.
I'd try customizing your property with:
<hj:basic>
<orm:column column-definition="..."/>
</hj:basic>
See the customizations schema and the ORM schema it uses.
You can also configure per-type customizations if you don't want to customize every single boolean (which you probably don't want):
<hj:default-single-property type="xsd:boolean">
<hj:basic>
<orm:column column-definition="..."/>
</hj:basic>
</hj:default-single-property>
<hj:default-collection-property type="xsd:boolean">
<hj:element-collection>
<orm:column column-definition="..."/>
</hj:element-collection>
</hj:default-collection-property>
See this example of a binding file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<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"
xmlns:annox="http://annox.dev.java.net"
jaxb:extensionBindingPrefixes="hj orm annox">
<jaxb:bindings schemaLocation="schema.xsd" node="/xs:schema">
<jaxb:schemaBindings>
<jaxb:package name="org.jvnet.hyperjaxb3.ejb.tests.pocustomized"/>
</jaxb:schemaBindings>
<hj:persistence>
<hj:default-generated-id name="MySuperId" transient="true">
<orm:column name="MY_SUPER_ID"/>
</hj:default-generated-id>
<hj:default-one-to-many>
<orm:join-table/>
</hj:default-one-to-many>
</hj:persistence>
<jaxb:bindings node="xs:complexType[#name='one']/xs:sequence/xs:element[#name='many-to-many-join-table']">
<annox:annotate>
<annox:annotate annox:class="org.hibernate.annotations.Cascade" value="DELETE_ORPHAN"/>
</annox:annotate>
</jaxb:bindings>
<jaxb:bindings node="xs:element[#name='ten']/xs:complexType">
<hj:basic name="content">
<orm:column length="1024"/>
</hj:basic>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
You'll have to place your hj:default-...-property elements inside hj:persistence. They will then override default mappings.
Related
I'm currently working on a xsd which uses the following contruct:
<xs:attribute name="listVersionID" type="xs:normalizedString" use="required" fixed="1.0">
While not problematic per se, it is rather annoying to work with, since the fixed-value of this definition increases between releases of the xsd spec, and we need to modify the values in a seperate constants-class to keep them valid, although little if anything of interest in the xsd has changed. The xsd is maintained elsewhere, so just changing it is no option.
Thus I was asking myself wether there is a jaxb-plugin or similar to turn fixed-value attributes into constants ala
#XmlAttribute(name = "listVersionID")
#XmlJavaTypeAdapter(NormalizedStringAdapter.class)
#XmlSchemaType(name = "normalizedString")
protected final String listVersionID = "1.0";
instead of just
#XmlAttribute(name = "listVersionID")
#XmlJavaTypeAdapter(NormalizedStringAdapter.class)
#XmlSchemaType(name = "normalizedString")
protected String listVersionID;
which must be populated manually.
Does anyone know of such?
If you don't want to modify your schema, another option is to use an external binding file:
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jaxb:bindings schemaLocation="yourschema.xsd" node="/xs:schema">
<jaxb:globalBindings fixedAttributeAsConstantProperty="true" />
</jaxb:bindings>
</jaxb:bindings>
It is equivalent to what proposes #jmattheis in his answer.
Yes it is possible through custom jaxb bindings, which can be added as file at the codegen.
In the jaxb bindings, there is the fixedAttributeAsConstantProperty-attribute. Setting this to true, instructs the code generator to generate attributes with the fixed attribute as java-constants.
There are 2 options for this:
1. Through global bindings:
which then make all attributes with fixed values to constants
<schema targetNamespace="http://stackoverflow.com/example"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.0">
<annotation>
<appinfo>
<jaxb:globalBindings fixedAttributeAsConstantProperty="true" />
</appinfo>
</annotation>
...
</schema>
2. Through local mappings:
Which only defines the fixedAttributeAsConstantProperty property on a specific attribute.
<schema targetNamespace="http://stackoverflow.com/example"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.0">
<complexType name="example">
<attribute name="someconstant" type="xsd:int" fixed="42">
<annotation>
<appinfo>
<jaxb:property fixedAttributeAsConstantProperty="true" />
</appinfo>
</annotation>
</attribute>
</complexType>
...
</schema>
Both examples should result in:
#XmlRootElement(name = "example")
public class Example {
#XmlAttribute
public final static int SOMECONSTANT = 42;
}
Is there a way to customize the JAXB binding for xs:list? The folowing example:
<simpleType name="doubleList">
<list itemType="double" />
</simpleType>
Will be bound by xjc to: List<Double>. However, I'd like to bind it to: List<BigDecimal>.
My initial setup was to define a binding like this:
<jaxb:bindings multiple="true" node="//xs:simpleType[#name='doubleList']/xs:list/#itemType">
<jaxb:property>
<jaxb:baseType name="java.math.BigDecimal" />
</jaxb:property>
</jaxb:bindings>
However, this gives the following problem:
XPath evaluation of "//xs:simpleType[#name='doubleList']/xs:list/#itemType" needs to result in an element.
Is there a way to do this without resorting to writing your own custom adapters?
The doubleList above was used elsewhere. Applying the binding on those spots, resulting in a correct Javaclass. Supprisingly, only choosing the proper base type was sufficient.
So place where the doubleList was used elsewhere:
<complexType name="DirectPositionType">
<simpleContent>
<extension base="gml:doubleList">
<attributeGroup ref="gml:SRSReferenceGroup" />
</extension>
</simpleContent>
</complexType>
Binding
<jaxb:bindings schemaLocation="http://schemas.opengis.net/gml/3.2.1/geometryBasic0d1d.xsd" node="/xs:schema">
<jaxb:bindings multiple="true" node="//xs:complexType[#name='DirectPositionType']">
<jaxb:property>
<jaxb:baseType name="java.math.BigDecimal" />
</jaxb:property>
</jaxb:bindings>
</jaxb:bindings>
resulting Java class:
public class DirectPositionType
{
#XmlValue
protected List<BigDecimal> value;
#XmlAttribute(name = "srsName")
HyperJAXB generates #ManyToOne Annotations for XSD 1:1-relationships like:
<xs:element name="typeName" type="otherType" />
or
<xs:element name="typeName" type="otherType" minOccurs="0" maxOccurs="1" />
This is not the expected behaviour since it should generate #OneToOne Annotations. Well, the customization guide describes that you can customize this behaviour by adding instructions to every single element definition (see http://confluence.highsource.org/display/HJ3/Making+schema-derived+classes+ready+for+JPA, paragraph "Mapping as one-to-one").
This is fine, but I need a global configuration for this. Can anybody please tell me, what to put in bindings.xjb to achieve this goal?
You can switch X:1 by default to one-to-one globaly:
<jaxb:bindings schemaLocation="schema.xsd" node="/xs:schema">
<hj:persistence>
<hj:default-to-one>
<hj:one-to-one/>
</hj:default-to-one>
</hj:persistence>
</jaxb:bindings>
However be warned, I think I've opted to #ManyToOne by default for a reason. It was safer and easier to handle.
Hi stackoverflow world,
I want to specify in a XSD that a specific element can be used as a XmlRootElement by JAXB.
I know how to add the annotation to the generated class: what I want to do is to specify that a element can be generated as a root element before the code generation.
I use external JAXB customizations (.xjb files).
The purpose is here to not modifying the schemas (as they are defining standards).
Anybody knows how do that?
Thanks!
NJ
Problem solved.
The JAXB plugin Annotate http://confluence.highsource.org/display/J2B/Annotate+Plugin do the job.
Add the following fragment in your jaxb binding file (external binding, i.e. a .xjb file):
<jaxb:bindings schemaLocation="csw/2.0.2/CSW-discovery.xsd" node="/xs:schema">
<jaxb:bindings node="xs:complexType[#name='GetRecordsType']">
<annox:annotate>
<annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement"
name="GetRecordsType" />
</annox:annotate>
</jaxb:bindings>
</jaxb:bindings>
Do not forget to declare the namespaces:
<jaxb:bindings
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:annox="http://annox.dev.java.net"
xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
jaxb:extensionBindingPrefixes="xjc annox" version="2.1">
...
</jaxb:bindings>
And use a ANT or MAVEN task http://confluence.highsource.org/display/J2B/User+Guide to proceed the generation of the sources.
I still search how to specify manually (without an xjc task with ant or maven) the JAXB extensions but it works now. (I have my own ANT script what's why I search to manually call XJC).
The JAXB extension mechanism is very convenient, have a look to JAXB2 Basics:
http://confluence.highsource.org/display/J2B/Home
I need to generate many classes from my XML Schema (XSD) in a package (.jar).
How can I configure these classes to be serializable?
(I'm using Eclipse and JAX-B)
If you are using XJC, I recomend you to read this reference: JavaTM Architecture for XML Binding: JAXB RI Vendor Extensions Customizations :
You have to add in your schema aditional namespaces definition to add xjc aditional markup:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:extensionBindingPrefixes="xjc"
jaxb:version="1.0">
Then, including an <xjc:serializable> node within <jaxb:globalBindings>:
<xs:annotation>
<xs:appinfo>
<jaxb:globalBindings generateIsSetMethod="true">
<xjc:serializable uid="12343"/>
</jaxb:globalBindings>
</xs:appinfo>
</xs:annotation>
This will cause that all the concrete classes implement the Serializable interface. Also, you can define the UUID value of the resulting classes (that's an optional attribute).
I've found
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:extensionBindingPrefixes="xjc"
jaxb:version="1.0"
>
<!-- FORCE ALL CLASSES IMPLEMENTS SERIALIZABLE -->
<annotation>
<appinfo>
<jaxb:globalBindings generateIsSetMethod="true">
<xjc:serializable uid="1"/>
</jaxb:globalBindings>
</appinfo>
</annotation>
....
</schema>