0

I tried the approach in this post

However I am getting a

>

 1 counts of IllegalAnnotationExceptions
XmlIDREF property is referencing a type "java.lang.String" that doesn't have an XmlID property.
    this problem is related to the following location:
        at private externalReferences.Department   
externalReferences.Employee.department
        at externalReferences.Employee
        at private java.util.List externalReferences.Company.employees
        at externalReferences.Company

The two xml Files are the following:

employee.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<company>
    <employeeList>
        <employee name="Jane Doe" id="1">
            <department>1</department>
        </employee>
        <employee name="John Smith" id="2">
            <department>2</department>
        </employee>
        <employee name="Anne Jones" id="3">
            <department>3</department>
        </employee>
    </employeeList>
</company>

department.xml

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<departmentList>
    <departmentList>
        <department name="Dev" id="1"/>
        <department name="Sales" id="2"/>
        <department name="Research" id="3"/>
    </departmentList>
</departmentList>

The employee.xml references the department and I want to point to the right department objects when unmarshalling employee.xml.

Classes are as follows:

Company.java

 @XmlRootElement
 @XmlAccessorType(XmlAccessType.FIELD)
 public class Company {

    @XmlElementWrapper(name = "employeeList")
    @XmlElement(name="employee")
    private List<Employee> employees;

    @XmlElementWrapper(name = "departmentList")
    @XmlElement(name="department")
    private List<Department> departments;

    public Company() {
        employees = new ArrayList<Employee>();
        departments = new ArrayList<Department>();
    }
    ...
}

Employee.java

 @XmlRootElement
 @XmlAccessorType(XmlAccessType.FIELD)
 public class Employee {

        @XmlAttribute
        @XmlID
        private String id;

        public String getId() {
            return id;
        }

         @XmlIDREF
         private Employee manager;


        @XmlJavaTypeAdapter(EmpAdapter.class)
        @XmlIDREF
        private Department department;
     }

Department.java

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Department {

@XmlAttribute
@XmlID
private String id;
...
}

DepartmentList.java

    @XmlRootElement
    @XmlAccessorType(XmlAccessType.FIELD)
    public class DepartmentList {

    @XmlElementWrapper(name = "departmentList")
    @XmlElement(name="department")
    private List<Department> departments;

Then I run the following in Main

 JAXBContext jc = JAXBContext.newInstance(DepartmentList.class);                                                                                  Unmarshaller unmarshaller = jc.createUnmarshaller();
      DepartmentList depList = (DepartmentList) unmarshaller.unmarshal(new FileReader(DepRef));
      EmpAdapter adapter = new EmpAdapter();
      for(Department dep : depList.getDepartments()) {
          adapter.getDepList().put(dep.getId(), dep);
      }
      JAXBContext jc2 = JAXBContext.newInstance(Company.class);
      Unmarshaller unmarshaller2 = jc2.createUnmarshaller();
      unmarshaller2.setAdapter(adapter);
      Company company2 = (Company) unmarshaller2.unmarshal(new FileReader(empRef));

I feel that having one XMLIDREF refer to employee id and the other XMLIDREF refer to department id is part of the problem. But that is required since the manager field references other employee objects.

Can someone please help me with this. Thank you

Community
  • 1
  • 1
GenerousJoker
  • 87
  • 1
  • 12

1 Answers1

0

The problem arises from class Company that corresponds to an XML document containing employees and departments. However, you've got two separate documents. Apparently you want one final class containing both lists.

(1) You could define a class EmployeeList for employees only, similar to the one for departments (DepartmentList). This will still let you write an application class Company into which you set the references for both lists.

(2) Change the annotation for Company.departments

@XmlTransient
private List<Department> departments;

marshal like you do now, and set the List with the reference you have from unmarshalling the corresponding XML into the returned object.

laune
  • 31,114
  • 3
  • 29
  • 42