Why and when JAXBElement is required in JAXB?
Solution 1
There are a few use cases where a JAXBElement
is required:
- An element is both
nillable="true"
andminOccurs="0"
. In this case what doesnull
on the mapped field/property mean? When the property isJAXBElement
a null value means the element isn't present and aJAXBElement
wrapping null means an XML element withxsi:nil="true"
. - There are 2 global elements with the same named complex type. Since in JAXB classes correspond to complex types a way is needed to capture which root element was encountered. For more details see this article I wrote.
- There is a choice structure where either
foo
orbar
elements can occur and they are the same type. Here aJAXBElement
is required because simply encountering aString
value isn't enough to indicate which element should be marshalled. - An element with
xsi:nil
is encountered in the document that contains attributes. In this example the object corresponding to that element can still be unmarshalled to hold the attribute values, but JAXBElement can stil indicate that the element was null.
Solution 2
JAXBElement is used to preserve the element name/namespace in use cases where enough information is not present in the object model. It's often used with substitution groups.
Without any JAXB metada the result will be wrapped in a JAXBElement. You can eliminates the root level JAXBElement by using the @XmlRootElement annotation.
If you use xsd files from an external source and no XmlRootElement annotation is available on the generated classes, using JAXBElement during the marshalling process can really come in handy since you can unmarshal the xml to an object using the JAXBElement wrapper. You will see that specifying the class itself doesn't work in that case...
This will work:
JAXBElement<Object> je = (JAXBElement<Object>) unmarshaller.unmarshal(objectXML);
Object = je.getValue();
This will throw a JAXBException:
Object obj = (Object) unmarshaller.unmarshal(objectXML);
Related videos on Youtube
Aman Arora
Updated on October 03, 2022Comments
-
Aman Arora over 1 year
I am just learning JAXB (Java Architecture for XML Binding). Reading through a few sources , one doubt has come in my mind regarding
JAXBElement
.
Oracle docs say:When XML element information can not be inferred by the derived Java representation of the XML content, a JAXBElement object is provided. This object has methods for getting and setting the object name and object value.
Link hereDoes it mean that
JAXBElement
needs to be used when there is not a direct mapping between Schema defined datatype and Java data type?Further, In one of the code examples listed under. which i followed from here :
ObjectFactory factory = new ObjectFactory(); UserT user = factory.createUserT(); user.setUserName("Sanaulla"); ItemT item = factory.createItemT(); item.setItemName("Seagate External HDD"); item.setPurchasedOn("August 24, 2010"); item.setAmount(new BigDecimal("6776.5")); ItemListT itemList = factory.createItemListT(); itemList.getItem().add(item); ExpenseT expense = factory.createExpenseT();// we get expense object here expense.setUser(user); expense.setItems(itemList); JAXBContext context = JAXBContext.newInstance("generated"); JAXBElement<ExpenseT> element = factory.createExpenseReport(expense);//why is this required Marshaller marshaller = context.createMarshaller(); marshaller.setProperty("jaxb.formatted.output",Boolean.TRUE); marshaller.marshal(element,System.out);
Using
ExpenseT expense = factory.createExpenseT();
we are able to getExpenseT
object.
Again in the code if we see ,we createJAXBElement<ExpenseT> element = factory.createExpenseReport(expense);
which according to this source is a wrapper forexpense
object.
On the other hand we don't create wrappers for the objects retrieved usingUserT user = factory.createUserT();
So my questions are :- What is the need of
JAXBElement
wrapper aroundexpense
? - when to use
JAXBElement
?
- What is the need of