@XmlSeeAlso(Employee.class)
public abstract class Person {
protected String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Employee extends Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
and in my public static main(), i setName("John") and marshal it to an xml.
This generates an XML :-
<Employee>
<name>John</John>
</Employee>
However, when i unmarshal this to the Employee object, neither the super nor local class had their name variable initialized to 'John'. I suspect its the sharing of the same name variable for both the inherited and parent class. I understand that this is bad practice, however how can one unmarshal to the Employee class? or Both?
Thank u.
Answer to this question starts from basic java principal. Since derived class override setName and getName . (new Employee()).setName("John") populates Employee's name not Person's. So if you want to populate properties of both the classes you should change person class to
@XmlSeeAlso(Employee.class)
public abstract class Person {
protected String firstName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
and do marshal of this.
Employee e = new Employee();
e.setName("John");
e.setLastName("JohnLast");
then your xml will look like
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<employee>
<lastName>JohnLast</lastName>
<name>John</name>
</employee>
and xsd
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="employee" type="employee"/>
<xs:complexType name="employee">
<xs:complexContent>
<xs:extension base="person">
<xs:sequence>
<xs:element name="name" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="person" abstract="true">
<xs:sequence>
<xs:element name="lastName" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
and during unmarshalling following works and name and lastName gets populated,
JAXBContext context = JAXBContext.newInstance(Employee.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
Employee e = (Employee) unmarshaller.unmarshal(xml);
Person p = (Person) unmarshaller.unmarshal(xml);