JAXB аннотации для классов классных атрибутов - PullRequest
2 голосов
/ 22 сентября 2010

проект настроен следующим образом:

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

@XmlRootElement(name="employee")
@XmlSeeAlso([EmployeeDesiredSkill.class, EmployeeDesiredTool.class,  EmployeeAreaOfExpertise.class, Project.class, Education.class])
@XmlAccessorType(XmlAccessType.NONE)
class Employee implements Comparable
{       
static hasMany = [employeeDesiredSkills:EmployeeDesiredSkill]     
 @XmlElement
     String name
    @XmlElement
    List<EmployeeDesiredSkill> employeeDesiredSkills = new ArrayList<EmployeeDesiredSkill>();
}


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

@XmlAccessorType(XmlAccessType.NONE)
class EmployeeDesiredSkill implements Comparable
{

boolean _deleted
@XmlElement
Skill skill
static belongsTo = [employee:Employee, skill:Skill]
}

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

@XmlAccessorType(XmlAccessType.FIELD)
class Skill implements Comparable
{
    static hasMany = [roleSkills:RoleSkill, employeeDesiredSkills:EmployeeDesiredSkill]

    boolean _deleted
static transients = ['_deleted']
    @XmlAttribute
    String name
}

Когда я пытаюсь выполнить XML-маршалинг этой настройки, я получаю действительные значения для Employee, но все навыки возвращаются пустыми, например:

<employee name = "Joe">
<employeeDesiredSkills>
    <skill name="">
        <_deleted>false</_deleted>
    </skill>
</employeeDesiredSkills>
<employeeDesiredSkills>
    <skill name="">
        <_deleted>false</_deleted>
    </skill>
</employeeDesiredSkills>
<employeeDesiredSkills>
    <skill name="">
        <_deleted>false</_deleted>
    </skill>
</employeeDesiredSkills>
<employeeDesiredSkills>
    <skill name="">
        <_deleted>false</_deleted>
    </skill>
</employeeDesiredSkills>
<employeeDesiredSkills>
    <skill name="">
        <_deleted>false</_deleted>
    </skill>
</employeeDesiredSkills>

Другими словами - имя никогда не возвращается из объектов умений. Я думаю, что Employee должен знать, сколько employeeDesiredSkills находится в списке (поскольку 5 из них отображаются), но по какой-то причине не может получить значения в классе Skill.

Что я могу сделать, чтобы это исправить? В моем контроллере, если я сделаю следующее:

            def employee = Employee.get(session.empid);
            for(esd in employee.getEmployeeDesiredSkills()){println "EmployeeDesiredSkill:" + esd}

Я получил полный список требуемых навыков (5 из них), поэтому я знаю, что значения уже есть в базе данных.

Мне кажется, что класс EmployeeDesiredSkill не знает, за какого сотрудника вернуть навыки, но я не уверен, правильное ли это мышление или нет. На самом деле я не хочу добавлять в свой класс навыков «ownTo = Employee», потому что я хочу, чтобы эти навыки могли также использоваться другими сотрудниками.

1 Ответ

2 голосов
/ 27 сентября 2010

Не уверен, помогает ли это, но если я запускаю ваш пример непосредственно в Java, все работает:

Сотрудник:

import java.util.ArrayList;
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 = "employee")
@XmlAccessorType(XmlAccessType.NONE)
class Employee {
    @XmlElement
    String name;

    @XmlElement
    List<EmployeeDesiredSkill> employeeDesiredSkills = new ArrayList<EmployeeDesiredSkill>();
}

EmployeeDesiredSkill

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

@XmlAccessorType(XmlAccessType.NONE)
class EmployeeDesiredSkill {

    boolean _deleted;

    @XmlElement
    Skill skill;
}

Умение

import javax.xml.bind.annotation.XmlAccessType;import javax.xml.bind.annotation.XmlAccessorType;import javax.xml.bind.annotation.XmlAttribute;

@ XmlAccessorType (XmlAccessType.FIELD) class Skill {

boolean _deleted;

@XmlAttribute
String name;

} ​​

со следующим кодом:

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(Employee.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Employee employee = (Employee) unmarshaller.unmarshal(new File("input.xml"));

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(employee, System.out);

    }
}

Может производить / потреблять следующий XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<employee>
    <employeeDesiredSkills>
        <skill name="A">
            <_deleted>false</_deleted>
        </skill>
    </employeeDesiredSkills>
    <employeeDesiredSkills>
        <skill name="B">
            <_deleted>false</_deleted>
        </skill>
    </employeeDesiredSkills>
    <employeeDesiredSkills>
        <skill name="C">
            <_deleted>false</_deleted>
        </skill>
    </employeeDesiredSkills>
    <employeeDesiredSkills>
        <skill name="D">
            <_deleted>false</_deleted>
        </skill>
    </employeeDesiredSkills>
    <employeeDesiredSkills>
        <skill name="E">
            <_deleted>false</_deleted>
        </skill>
    </employeeDesiredSkills>
</employee>
...