2009-05-30 31 views
8

Tengo algunos objetos jaxb (instanciados a partir del código generado a partir de xsd por jaxb) que necesito clonar. La clase Jaxb no parece proporcionar una interfaz para hacer esto fácilmente. No puedo editar manualmente la clase y no puedo extenderla, así que necesito crear un método de ayuda/utilidad para hacer esto. ¿Cuál es el mejor enfoque?Cómo puedo clonar un objeto JAXB

Respuesta

8

Dado el propósito de JAXB, creo que la manera más fácil sería ordenar su objeto a XML y deshacerlo de nuevo.

Muchas más discusiones en Google.

JAXB Preguntas más frecuentes suggestsbeanlib.

También hay algunos discussion (así como un enlace para descargar) de un complemento Cloneable bajo jaxb2-commons, aunque no puedo encontrar ninguna referencia en la página del proyecto.

+0

Sí, marshall-to-unmarshall funcionó a la perfección. Te estoy otorgando la respuesta. Por supuesto, esto se ve afectado por la serialización, pero dado que no se puede serializar, no hay muchas otras opciones además de la reflexión. –

+0

Consulte el siguiente ejemplo de código: http://bdoughan.blogspot.com/2011/03/using-jaxb-to-implement-copy-operation.html –

+0

Marshalling/unmarshalling funciona bastante bien, pero es de lejos la solución más lenta. Puede utilizar 5 veces más rápido el uso de serialización/deserialización, o alrededor de 50 veces más rápido mediante la clonación real. Ver [mi respuesta aquí] (http://stackoverflow.com/a/10870833/521799) –

3

Deberías probar cc-xjc, que está disponible en sourceforge. Una de sus características es generar clone() y copy-constructors.

3

Puede usar el Copyable plugin. Genera métodos de copia/clonación profundos (que pueden incluso personalizarse con estrategias).

+0

Desafortunadamente, este complemento agrega muchas dependencias a los artefactos generados ... –

+0

"Muchas dependencias" ¿cuántas, exactamente? – lexicore

+0

1, probablemente ;-) Lo cual es mucho para POJO simples, que probablemente solo puedan ser clonados usando [Object.clone()] (http://docs.oracle.com/javase/7/docs/api/java/ lang/Object.html # clone% 28% 29). ¿Sabes por qué se agrega la dependencia? Quiero decir, ¿qué hace que los procedimientos de clonación de jvnet sean más robustos? –

2

He realizado pruebas comparativas sobre diversas soluciones para clonar un objeto JAXB. Aquí tienes algunos resultados:

  1. Uso mofokom's xjc-clone plugin parece ser la solución más rápida. Simplemente deja que todos sus artefactos generados implementen Cloneable y anula públicamente Object.clone(). Desafortunadamente, esto no ha llegado a Maven central (todavía).

  2. Generación Serializable artefactos y serialising/deserialising a un flujo ficticio es 10 veces más lento que el uso de mecanismos de clonación de Java:

    public <T extends Serializable> T clone(T jaxbObject) { 
        ByteArrayOutputStream out = new ByteArrayOutputStream(); 
        ObjectOutputStream o = new ObjectOutputStream(out); 
        o.writeObject(jaxbObject); 
        o.flush(); 
    
        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); 
        ObjectInputStream i = new ObjectInputStream(in); 
        return (T) i.readObject(); 
    } 
    
  3. Marshalling/unmarshalling los objetos de JAXB es nuevo 5x más lento que serialising/deserialising ellos. Esto es lo que ykaganovich's solución sugiere:

    public <T extends Serializable> T clone(T jaxbObject) { 
        StringWriter xml = new StringWriter(); 
        JAXB.marshal(jaxbObject, xml); 
        StringReader reader = new StringReader(xml.toString()); 
        return JAXB.unmarshal(reader, jaxbObject.getClass()); 
    } 
    
+0

¿Puedes elaborar sobre cómo usar el plugin xjc-clone? Parece que no puedo encontrar ninguna documentación para este complemento. ¿Tienes que usarlo junto con eclipse? – CKing

+0

@bot: De hecho, he encontrado una mejor solución ahora, que incluye Maven y el complemento oficial 'jaxb2-basics'. Una solución similar a la que he encontrado está documentada [aquí] (http://arnekroeger.blogspot.ch/2011/06/java-jaxb-extend-generated-classes.html). Actualizaré la respuesta cuando tenga tiempo –

+0

Pude hacer que las clases generadas fueran clonables usando el plugin xjc-clone y la hormiga. ¿Hay algún enlace que describa una forma de usar el complemento jaxb2-basics con hormiga? – CKing

1

se trata de un viejo hilo, pero tuve que crear cloneable dominio JAXB objetos demasiado y creo que de clasificación - unmarshalling no es la mejor solución sin lugar a duda.

Idealmente, debe copiar los objetos en la memoria utilizando los métodos de clonación generados. Existe un complemento Maven (maven-jaxb2-plugin) que puede usar para este fin.

Estos son la sección correspondiente en mi pom.xml Maven:

<dependency> 
    <groupId>org.jvnet.jaxb2_commons</groupId> 
    <artifactId>jaxb2-basics</artifactId> 
    <version>0.11.1</version> 
</dependency> 

...

<plugin> 
    <groupId>org.jvnet.jaxb2.maven2</groupId> 
    <artifactId>maven-jaxb2-plugin</artifactId> 
    <executions> 
     <execution> 
      <goals> 
       <goal>generate</goal> 
      </goals> 
     </execution> 
    </executions> 
    <configuration> 
     <extension>true</extension> 
     <schemaDirectory>${basedir}/src/main/xsd</schemaDirectory> 
     <bindingDirectory>${basedir}/src/main/xjb</bindingDirectory> 
     <args> 
      <arg>-Xcopyable</arg> 
     </args> 
     <plugins> 
      <plugin> 
       <groupId>org.jvnet.jaxb2_commons</groupId> 
       <artifactId>jaxb2-basics</artifactId> 
       <version>1.11.1</version> 
      </plugin> 
     </plugins> 
    </configuration> 
</plugin> 

nota del argumento -Xcopyable que genera el método clone en el interior de todos los objetos.

Si utiliza

mvn clean install 

para la construcción del proyecto Esto generará las clases de dominio con una implementación clon.

Este es un extracto de los métodos relacionados con el clon en una de las clases de dominio:

public Object clone() { 
    return copyTo(createNewInstance()); 
} 

public Object copyTo(Object target) { 
    final CopyStrategy2 strategy = JAXBCopyStrategy.INSTANCE; 
    return copyTo(null, target, strategy); 
} 

Usted puede encontrar las fuentes y muestras del proyecto básico jaxb2 en esta página:

https://github.com/highsource/jaxb2-basics/wiki/Sample-Projects

Las versiones con ejemplos útiles se pueden descargar desde aquí:

https://github.com/highsource/jaxb2-basics/releases