简体   繁体   中英

How Do I Clone A JAXB Object

I have some jaxb objects (instantiated from code generated from xsd by jaxb) that I need to clone. The Jaxb class does not appear to provide an interface for doing this easily. I can not hand edit the class and can not extend it - so I need to create a helper/utility method to do this. What is the best approach?

Given the purpose of JAXB, I think the easiest way would be to marshall your object to XML and unmarshall it back.

Lots more discussions on Google .

JAXB FAQ suggests beanlib .

There's also some discussion (as well as a link to download) of a Cloneable plugin under jaxb2-commons, although I can't find any reference on the project page.

I've run benchmarks on various solutions for cloning a JAXB object. Here are some results:

  1. Using mofokom's xjc-clone plugin seems to be the fastest solution. It just lets all your generated artefacts implement Cloneable and publicly overrides Object.clone() . Unfortunately, this hasn't made it into Maven central (yet).

  2. Generating Serializable artefacts and serialising / deserialising them to a dummy stream is 10x slower than using Java's cloning mechanisms:

     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 the JAXB objects is again 5x slower than serialising / deserialising them. This is what ykaganovich's solution suggests:

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

You should try cc-xjc , which is available on sourceforge. One of its features is to generate clone() and copy-constructors.

You can use the Copyable plugin . It generates deep copy/clone methods (which can be even customized with strategies).

我们使用了jaxb2-basics插件 - 它在Maven repo中可用,只添加一个依赖项,也可用于生成其他有用的东西:equals,hashCode,toString,默认值等。请参阅此链接了解详细信息: http ://pragmaticintegrator.wordpress.com/2012/11/20/cloning-a-jaxb-object/

This is an old thread, but I had to create cloneable JAXB domain objects too and I think that marshalling - unmarshalling is not the best solution for sure.

Ideally you should copy the objects in memory using generated clone methods. There is a Maven plugin ( maven-jaxb2-plugin ) which you can use for this purpose.

These are the relevant section in my Maven pom.xml file:

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

Note the -Xcopyable argument which generates the clone method inside of all objects.

If you use

mvn clean install

for building the project this will generate the domain classes with a clone implementation.

This is an extract of the clone related methods in one of the domain classes:

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

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

You can find the sources and samples of the jaxb2 basics project on this page:

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

The releases with useful examples can be downloaded from here:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM