I'm working with JAXB right now and I'm struggling to annotate my composite notion of precondition query so that JAXB would be happy.
A precondition query can be:
Of course, compound queries can be made of compound queries, just like in the following example:
<precondition>
<or>
<and>
<query>foo</query>
<query>bar</query>
</and>
<query>baz</query>
</or>
</precondition>
In my Java model, I've got a single interface annotated PreconditionQuery (actually an abstract class since JAXB seems unhappy with interfaces) with 3 implementations SimplePreconditionQuery, CompoundOrPreconditionQuery and CompoundAndPreconditionQuery.
@XmlSeeAlso(PreconditionQuery.class)
@XmlRootElement(name = "query")
public class SimplePreconditionQuery extends PreconditionQuery {
private String query;
@XmlValue
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.query = query;
}
}
For the compound ones (CompoundOrPreconditionQuery is basically the same):
@XmlSeeAlso(PreconditionQuery.class)
@XmlRootElement(name = "and")
public class CompoundAndPreconditionQuery extends PreconditionQuery {
private Collection<PreconditionQuery> preconditionQueries = newArrayList();
@XmlElementRef(name = "query")
public Collection<PreconditionQuery> getPreconditionQueries() {
return preconditionQueries;
}
public void setPreconditionQueries(Collection<PreconditionQuery> preconditionQueries) {
this.preconditionQueries = preconditionQueries;
}
}
Finally, at the enclosing bean level, I mapped like this:
public class Precondition {
private PreconditionQuery query;
@XmlElementRef(required = true)
public PreconditionQuery getQuery() {
return query;
}
public void setQuery(PreconditionQuery query) {
this.query = query;
}
}
In the end, JAXB complains about not being able to resolve this:
Caused by: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Invalid @XmlElementRef : Type "class xxx.PreconditionQuery" or any of its subclasses are not known to this context.
this problem is related to the following location:
at public xxx.PreconditionQuery xxx.Precondition.getQuery()
at xxx.Precondition
If @XmlElementRef
doesn't do the job, what will?
Please try adding
@XmlSeeAlso({PreconditionQuery.class})
to your CompoundAndPreconditionQuery
class.
Then, try annotating ALL of your PreconditionQuery
classes/subclasses with @XmlRootElement
.
Also, be a bit more careful with @XmlAccessorType
- sometimes you have it, sometimes not. Better annotate the package with it.
Finally, you may need an ObjectFactory
with @XmlRegistry
and @XmlElementDecl
, but I do not think it is absolutely required.
I think the problem is the missing @XmlRootElement
/@XmlSeeAlso
annotations.
@XmlElementRef
is known to be tricky, but it does work. :)