Why and when JAXBElement is required in JAXB?
java, jaxb, oracle, xml, xsd
Solution
There are a few use cases where a `JAXBElement` is required:
- An element is both `nillable="true"` and `minOccurs="0"`. In this case what does `null` on the mapped field/property mean? When the property is `JAXBElement` a null value means the element isn't present and a `JAXBElement` wrapping null means an XML element with `xsi: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` or `bar` elements can occur and they are the same type. Here a `JAXBElement` is required because simply encountering a `String` 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.
Problem
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 here Does 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 get `ExpenseT` object. Again in the code if we see ,we create `JAXBElement<ExpenseT> element = factory.createExpenseReport(expense);` which according to this source is a wrapper for `expense` object. On the other hand we don't create wrappers for the objects retrieved using `UserT user = factory.createUserT();` So my questions are : - What is the need of `JAXBElement` wrapper around `expense` ? - when to use `JAXBElement` ?