0

I have the following simple jaxB class that takes generic type E

@XmlAccessorType(XmlAccessType.FIELD)
@XmlTransient
@XmlRootElement(name = "searchResponseBase")
public abstract class SearchResponseBase<E>{

    @XmlElement(type=NameSearchResults.class)
    protected E searchResults;

    public E getSearchResults()
    {
        return searchResults;
    }

    public void setSearchResults(E mSearchResults)
    {
        this.searchResults = mSearchResults;
    }

}

I need to remove the reference to NameSearchResults @XmlElement(type=NameSearchResults.class) to make the base actually generic, but if I do I get the error.

error

[com.sun.istack.internal.SAXException2: class au.test.nameSearch.NameSearchResults nor any of its super class is known to this context.
javax.xml.bind.JAXBException: class au.test.nameSearch.NameSearchResults nor any of its super class is known to this context.]


This is an example of a class that extends it

extended class

@SuppressWarnings("javadoc")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = {
    "searchRequest",
    "searchResults"
})
@XmlRootElement(name = "searchResponse")
public class SearchResponse extends SearchResponseBase<NameSearchResults> {

    @XmlElement(required = true)
    protected SearchRequest searchRequest;

    public SearchRequest getSearchRequest() {
        return searchRequest;
    }

    public void setSearchRequest(SearchRequest value) {
        this.searchRequest = value;
    }
}

How do i make the base class actually generic?

preferably i would like my extended class to work in the format SearchResponse<E> extends SearchResponseBase<E> and use it as a generic type too.

if i do as paul suggested i can get teh class to:

@XmlRootElement(name = "searchResponse")
public class SearchResponse<E extends NameSearchResults> extends SearchResponseBase<E> {

    @XmlElement(required = true)
    protected SearchRequest searchRequest;

    protected E searchResults;

    public SearchRequest getSearchRequest() {
        return searchRequest;
    }

    public void setSearchRequest(SearchRequest value) {
        this.searchRequest = value;
    }

    @Override
    public E getSearchResults() {
        return searchResults;
    }

    @Override
    public void setSearchResults(E mSearchResults) {
        this.searchResults = mSearchResults;
    }  
}

is there a way i can push the NameSearchResults out of this <E extends NameSearchResults>?

Sean F
  • 2,352
  • 3
  • 28
  • 40

2 Answers2

3

Thanks to @PaulBellora for the help, the base and extend class will both become abstract then haveing a Name implimentation, like this:

Base

@XmlRootElement(name = "searchResponseBase")
public abstract class SearchResponseBase<E>{

    public abstract E getSearchResults();

    public abstract void setSearchResults(E mSearchResults);

}

Extended Base

@XmlRootElement(name = "searchResponse")
public abstract class SearchResponse<E> extends SearchResponseBase<E>{

    public abstract SearchRequest getSearchRequest();

    public abstract void setSearchRequest(SearchRequest value);   
}

Name Implimentation

@XmlRootElement(name = "nameSearchResponse")
public class NameSearchResponse extends SearchResponse<NameSearchResults>{

    @XmlElement(required = true)
    protected SearchRequest searchRequest;

    protected NameSearchResults searchResults;

    @Override
    public NameSearchResults getSearchResults() {
        return searchResults;
    }

    @Override
    public void setSearchResults(NameSearchResults mSearchResults) {
        this.searchResults = mSearchResults;
    }

    @Override
    public SearchRequest getSearchRequest() {
        return searchRequest;
    }

    @Override
    public void setSearchRequest(SearchRequest value) {
        this.searchRequest = value;
    }
}
Sean F
  • 2,352
  • 3
  • 28
  • 40
  • also at this point, i combined extended and base into one class and made it an interface not abstract class anymore. – Sean F Nov 07 '12 at 02:53
  • saved me a lot of work in searching solution. Thanks! works perfectly – LMG Dec 28 '13 at 16:01
1

I'm unfamiliar with JAXB, but you could try making getSearchResults and setSearchResults abstract methods, and implement them only when E was resolved. For example:

//annotations ommitted
public abstract class SearchResponseBase<E>{

    public abstract E getSearchResults();

    public abstract void setSearchResults(E mSearchResults);
}

//annotations ommitted
public class SearchResponse extends SearchResponseBase<NameSearchResults> {

    @XmlElement(type=NameSearchResults.class)
    protected NameSearchResults searchResults;

    @Override
    public final NameSearchResults getSearchResults() {
        return searchResults;
    }

    @Override
    public final void setSearchResults(NameSearchResults mSearchResults) {
        this.searchResults = mSearchResults;
    }

    ...
}
Paul Bellora
  • 54,340
  • 18
  • 130
  • 181
  • thanks paul, this does work for making the base abstract, however it just pushes the reference to NameSearchResults into the class that extends base. What i wanted was to remove it from the classes completely. – Sean F Nov 06 '12 at 22:17