Tuesday, December 20, 2011

Ignoring Inheritance with @XmlTransient

In previous articles I have covered how to map inheritance relationships in JAXB and EclipseLink MOXy.  In this example I will describe how to remove an inheritance relationship in JAXB by leveraging @XmlTransient at the type level.


Java Model

Base

In this example we want all of our domain objects to have an id property.  We will accomplish this by having all of our domain objects extend the same base class (Base). Since this base class is not relevant to the domain model we will tell JAXB to ignore it by marking it @XmlTransient.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package blog.inheritance.xmltransient;
 
import javax.xml.bind.annotation.XmlTransient;
 
@XmlTransient
public abstract class Base {
 
    private int id;
 
    public int getId() {
        return id;
    }
 
    public void setId(int id) {
        this.id = id;
    }
 
}

Customer

Since the parent class has been marked @XmlTransient the id property will be treated as part of the child classes.  In the Customer class we will demonstrate this by including the id property in the propOrder specified on @XmlType.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package blog.inheritance.xmltransient;
 
import java.util.List;
 
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
 
@XmlRootElement
@XmlType(propOrder={"id", "name", "address", "phoneNumbers"})
public class Customer extends Base {
 
    private String name;
    private Address address;
    private List<PhoneNumber> phoneNumbers;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public Address getAddress() {
        return address;
    }
 
    public void setAddress(Address address) {
        this.address = address;
    }
 
    @XmlElement(name="phone-number")
    public List<PhoneNumber> getPhoneNumbers() {
        return phoneNumbers;
    }
 
    public void setPhoneNumbers(List<PhoneNumber> phoneNumbers) {
        this.phoneNumbers = phoneNumbers;
    }
 
}

Address

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package blog.inheritance.xmltransient;
 
public class Address extends Base {
 
    private String street;
 
    public String getStreet() {
        return street;
    }
 
    public void setStreet(String street) {
        this.street = street;
    }
 
}

PhoneNumber

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package blog.inheritance.xmltransient;
 
public class PhoneNumber extends Base {
 
    private String number;
 
    public String getNumber() {
        return number;
    }
 
    public void setNumber(String number) {
        this.number = number;
    }
 
}


Demo Code

Below is the demo code that can be used to run this example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package blog.inheritance.xmltransient;
 
import java.io.File;
 
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
 
public class Demo {
 
    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Customer.class);
 
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Customer customer = (Customer) unmarshaller.unmarshal(new File("input.xml"));
 
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(customer, System.out);
    }
 
}

XML (input.xml)

In the XML you will notice that there are no inheritance indicators present.  The properties of the base class are simply treated as properties of the respective subclasses:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
<customer>
   <id>12</id>
   <name>Jane Doe</name>
   <address>
      <id>34</id>
      <street>1 A Street</street>
   </address>
   <phone-number>
      <id>45</id>
      <number>555-1111</number>
   </phone-number>
   <phone-number>
      <id>67</id>
      <number>555-2222</number>
   </phone-number>
</customer>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

No comments:

Post a Comment