Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAXB edit List getter?

I have my data model in the form of XSD files from which I then generate the corresponding Java files from xjc using command line.

When I generate JAXB classes from an XSD, List type elements gets a getter method generated for them (with no corresponding setter method), as follows:

public List<Type> getElement3() {
    if (element3 == null) {
        element3 = new ArrayList<Type>();
    }
    return this.element3;
}

I have lot of fields in almost every file generated from XSD of List type.

USE case:

Now, I don't want the getter to be generated with the null check. My application code has logic in which the getters of every fields are called often, which leads to their initialization to empty List.

Then while marshaling I have to stop the empty list to pass in the payload to avoid lot of empty lists being sent over the wire.

PS: I have a use case where Empty List is set explicitly by the user, the server has to delete certain items at the back-end. So the differentiation whether the value is explicitly set by the user or is set just because the getter for the List was called during accessing the field.

So, How to make JAXB generate a getter without a null check ??

As, editing the generated java files after compilation will be cumbersome as it's there in lot of files and we have XSD versions getting updated and would have to perform the editing every time a new version comes up.

like image 299
Siddharth Trikha Avatar asked Jul 12 '18 11:07

Siddharth Trikha


1 Answers

At first, I would think of using a custom JAXB Binding, but I can´t think of any that would meet this requirement.

In this case, perhaps you could use a wrapper class:

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "employees")
@XmlAccessorType (XmlAccessType.FIELD)
public class Employees
{
    @XmlElement(name = "employee")
    private List<Employee> employees = null;

    public List<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }
}

And then define your business object:

@XmlRootElement(name = "employee")
@XmlAccessorType (XmlAccessType.FIELD)
public class Employee
{
    private Integer id;
    private String firstName;
    private String lastName;
    private double income;

    //Getters and Setters
}

You will have to control the initialization of the list yourself when generating the objects to be marshalled:

Employees employees = new Employees();
employees.setEmployees(new ArrayList<Employee>());

Source of this example: Here

like image 111
Victor Avatar answered Sep 23 '22 03:09

Victor