Estoy usando etiquetas @XmlID y @XmlIDREF para hacer referencia a un objeto de otro. Funcionó bien en Java 6 incluso con clases heredadas. El código de ejemplo que he creado se ve así. clase base etiquetas usadas:XmlID/XmlIDREF y herencia en la última versión de JAXB (Java 7)
@XmlRootElement
@XmlAccessorType(FIELD)
public class Module {
Module() {}
@XmlIDREF
private Module other;
@XmlID
private String id;
public Module(String id, Module other) {
this.id = id;
this.other = other;
}
}
clase heredada:
contenedores para estas clases:
@XmlRootElement
public class Script {
Script() {}
public Script(Collection<Module> modules) {
this.modules = modules;
}
@XmlElementWrapper
@XmlElementRef
Collection<Module> modules = new ArrayList<Module>();
}
Cuando se ejecuta este código de ejemplo:
public class JaxbTest {
private Script createScript() {
Module m1 = new Module("Module1", null);
Module m2 = new TheModule("Module2", m1, "featured module");
Module m3 = new Module("Module3", m2);
return new Script(Arrays.asList(m1, m2, m3));
}
private String marshal(Script script) throws Exception {
JAXBContext context = JAXBContext.newInstance(Module.class, Script.class, TheModule.class);
Writer writer = new StringWriter();
context.createMarshaller().marshal(script, writer);
return writer.toString();
}
private void runTest() throws Exception {
Script script = createScript();
System.out.println(marshal(script));
}
public static void main(String[] args) throws Exception {
new JaxbTest().runTest();
}
}
recibo XML, en Java 6:
<script>
<modules>
<module>
<id>Module1</id>
</module>
<theModule>
<other>Module1</other>
<id>Module2</id>
<feature>featured module</feature>
</theModule>
<module>
<other>Module2</other>
<id>Module3</id>
</module>
</modules>
</script>
Nota que la referencia a los m2 (ejemplo TheModule) es de serie como se esperaba. Pero cuando el mismo código se ejecuta en Java 7 (JAXB 2.2.4-1) Recibo:
<script>
<modules>
<module>
<id>Module1</id>
</module>
<theModule>
<other>Module1</other>
<id>Module2</id>
<feature>featured module</feature>
</theModule>
<module>
<other xsi:type="theModule" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<other>Module1</other>
<id>Module2</id>
<feature>featured module</feature>
</other>
<id>Module3</id>
</module>
</modules>
</script>
Así se puede ver que en el último JAXB @XmlIDREF para el módulo heredado no está funcionando!
Gracias por su respuesta. Tengo algunas dudas. Javadoc para JAXBContext.newInstance (Class ...) establece que quien llama debe listar las clases de nivel superior. "Nuevo contexto reconocerá todas las clases especificadas, pero también reconocerá cualquier clase que están directamente/indirectamente hace referencia ** ** estáticamente (sic!) De las clases especificadas. Las subclases de clases referenciadas ni clases @XmlTransient hace referencia no están registrados JAXBContext. ". Si aplicamos esta afirmación con el ejemplo de Konstantin, TheModule clase descendiente no será descubierto automático. \ –
@AndyMalakov Parece que tienes razón. No recuerdo exactamente si he leído la documentación de 'newInstance' en aquel momento cuando respondí la pregunta, pero recuerdo que probé un código y que lo que he escrito parecía verificar. Como el OP no respondió a mi respuesta de ninguna manera, me olvidé por completo de esto. De hecho, puedo ver que he malinterpretado la pregunta/problema real, por lo que mi respuesta es totalmente inactiva. Actualizaré mi respuesta para reflejar esto. ¡Gracias por el aporte! –