如何克隆JAXB对象

时间:2022-10-30 14:25:56

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?

我有一些jaxb对象(从xsd生成的代码实例化jaxb)我需要克隆。 Jaxb类似乎没有为这样做提供简单的界面。我无法手动编辑类并且无法扩展它 - 因此我需要创建一个帮助器/实用程序方法来执行此操作。什么是最好的方法?

6 个解决方案

#1


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

鉴于JAXB的目的,我认为最简单的方法是将您的对象编组为XML并将其解组。

Lots more discussions on Google.

关于谷歌的更多讨论。

JAXB FAQ suggests beanlib.

JAXB FAQ建议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.

在jaxb2-commons下还有一些Cloneable插件的讨论(以及下载链接),虽然我在项目页面上找不到任何引用。

#2


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

您应该尝试cc-xjc,它可以在sourceforge上找到。它的一个功能是生成clone()和copy-constructors。

#3


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

您可以使用Copyable插件。它生成深层复制/克隆方法(甚至可以使用策略进行自定义)。

#4


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

我已经在克隆JAXB对象的各种解决方案上运行基准测试。以下是一些结果:

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

    使用mofokom的xjc-clone插件似乎是最快的解决方案。它只是让你生成的所有文物实现Cloneable并公开覆盖Object.clone()。不幸的是,这还没有进入Maven中心(尚)。

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

    生成可序列化的伪像并将它们序列化/反序列化为虚拟流比使用Java的克隆机制慢10倍:

    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:

    编组/解组JAXB对象的速度比串行化/反序列化慢5倍。这就是ykaganovich的解决方案所暗示的:

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

#5


We have used the jaxb2-basics plugin - it is available in Maven repo, adds only a single dependency and can also be used to generate other useful stuff: equals, hashCode, toString, default values etc. Please see this link for details: http://pragmaticintegrator.wordpress.com/2012/11/20/cloning-a-jaxb-object/

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

#6


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.

这是一个旧线程,但我也必须创建可克隆的JAXB域对象,我认为编组 - 解组并不是最好的解决方案。

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.

理想情况下,您应该使用生成的克隆方法复制内存中的对象。有一个Maven插件(maven-jaxb2-plugin)可以用于此目的。

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

这些是我的Maven pom.xml文件中的相关部分:

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

请注意-Xcopyable参数,该参数在所有对象中生成克隆方法。

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:

您可以在此页面上找到jaxb2基础知识项目的来源和示例:

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

#1


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

鉴于JAXB的目的,我认为最简单的方法是将您的对象编组为XML并将其解组。

Lots more discussions on Google.

关于谷歌的更多讨论。

JAXB FAQ suggests beanlib.

JAXB FAQ建议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.

在jaxb2-commons下还有一些Cloneable插件的讨论(以及下载链接),虽然我在项目页面上找不到任何引用。

#2


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

您应该尝试cc-xjc,它可以在sourceforge上找到。它的一个功能是生成clone()和copy-constructors。

#3


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

您可以使用Copyable插件。它生成深层复制/克隆方法(甚至可以使用策略进行自定义)。

#4


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

我已经在克隆JAXB对象的各种解决方案上运行基准测试。以下是一些结果:

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

    使用mofokom的xjc-clone插件似乎是最快的解决方案。它只是让你生成的所有文物实现Cloneable并公开覆盖Object.clone()。不幸的是,这还没有进入Maven中心(尚)。

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

    生成可序列化的伪像并将它们序列化/反序列化为虚拟流比使用Java的克隆机制慢10倍:

    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:

    编组/解组JAXB对象的速度比串行化/反序列化慢5倍。这就是ykaganovich的解决方案所暗示的:

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

#5


We have used the jaxb2-basics plugin - it is available in Maven repo, adds only a single dependency and can also be used to generate other useful stuff: equals, hashCode, toString, default values etc. Please see this link for details: http://pragmaticintegrator.wordpress.com/2012/11/20/cloning-a-jaxb-object/

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

#6


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.

这是一个旧线程,但我也必须创建可克隆的JAXB域对象,我认为编组 - 解组并不是最好的解决方案。

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.

理想情况下,您应该使用生成的克隆方法复制内存中的对象。有一个Maven插件(maven-jaxb2-plugin)可以用于此目的。

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

这些是我的Maven pom.xml文件中的相关部分:

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

请注意-Xcopyable参数,该参数在所有对象中生成克隆方法。

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:

您可以在此页面上找到jaxb2基础知识项目的来源和示例:

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