2010-09-21 15 views
2

ont un projet mis en place comme suit:annotations JAXB pour les classes d'attributs groovy

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 
} 

Lorsque je tente de faire le marshaling XML de cette configuration, je reçois des valeurs valides ennemi des employés, mais toutes les compétences venir Retour vide, comme ceci:

<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> 

En d'autres termes - nom ne revient jamais des objets de compétence. Je pense que l'employé doit savoir combien d'employésDesiredSkills sont dans la liste (puisque 5 d'entre eux apparaissent), mais pour une raison quelconque ne peut pas obtenir les valeurs dans la classe de compétence.

Que puis-je faire pour résoudre ce problème? Dans mon contrôleur, si je fais ce qui suit:

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

-je obtenir la liste complète des compétences désirées imprimées (5 d'entre eux), donc je sais que les valeurs sont dans la base de données déjà.

Pour moi, il semble que la classe EmployeeDesiredSkill ne sait pas pour quel employé retourner les compétences, mais je ne suis pas sûr que ce soit la bonne pensée ou non. Je ne veux pas vraiment ajouter un belongsTo = Employee à ma classe Skills, car je veux que ces compétences soient également utilisées par d'autres employés.

Répondre

2

Je ne sais pas si cela aide, mais si je lance votre exemple directement en Java tout fonctionne:

Employé:

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; 
} 

Compétences

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

@XmlAccessorType (XmlAccessType.FIELD) des compétences de classe {

boolean _deleted; 

@XmlAttribute 
String name; 

}

Avec le code suivant:

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); 

    } 
} 

peut produire/consommer le code XML suivant:

<?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>