JAXB and Composite Pattern

二次信任 提交于 2020-02-06 04:15:46

问题


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:

  • simple : only a text node containing the query
  • compound
    • OR : the preconditions of 1 precondition query OR the other matches
    • AND : the preconditions of 1 precondition query AND the other matches

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?


回答1:


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 for sure. :)

Good luck and best wishes.



来源:https://stackoverflow.com/questions/26682591/jaxb-and-composite-pattern

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!