如何使用hibernate和Web服务与两个父母持久化实体?

时间:2010-07-26 22:40:39

标签: java web-services hibernate jaxb cxf

我有以下实体结构(A,B,C,D是实体):

A-> one-to-many B, 
A-> one-to-many C,
B-> one-to-many D, 
C-> one-to-many D.

我想用hibernate来持久保存实体A但我通过Web服务发送它(循环引用被删除)。所以,在服务器上,我收到的父母“知道”孩子和孩子们不了解父母,我需要再次联系一切。问题是我需要将D与两个父项匹配 - 客户端上的单个D实例,服务器上的两个实例必须合并而D之前没有持久化,因此它不包含唯一ID可以匹配。我正在考虑两种解决方案:

1.  Call web service twice – in first call persist Ds and then call it to persist A
2.  XmlIDRef, and XmlID annotations so I don’t have to merge Ds (jaxb will do the job for me) but in that case client will have to generate unique ids for that fields and I wanted to avoid that.

我该怎么办?我是在正确的轨道上吗?

顺便说一下,我正在使用hibernate,cxf和jaxb。

1 个答案:

答案 0 :(得分:1)

这两种方法都是合理的:

两次致电Web服务

有些用户将消息分成较小的块,以便只在一条消息中通过线路发送私有数据。对非私有数据的引用表示为链接(链接指定如何从另一个JAX-RS服务获取对象)。然后你可以拥有解析链接的XmlAdapters(见下文):

import java.net.HttpURLConnection;
import java.net.URL;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.adapters.XmlAdapter;

import org.example.product.Product;

public class ProductAdapter  extends XmlAdapter<String, Product>{

    private JAXBContext jaxbContext;

    public ProductAdapter() {
        try {
            jaxbContext = JAXBContext.newInstance(Product.class);
        } catch(JAXBException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String marshal(Product v) throws Exception {
        if(null == v) {
            return null;
        }
        return "http://localhost:9999/products/" + v.getId();
    }

    @Override
    public Product unmarshal(String v) throws Exception {
        if(null == v) {
            return null;
        }

        URL url = new URL(v);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setRequestProperty("Accept", "application/xml");

        Product product = (Product) jaxbContext.createUnmarshaller().unmarshal(connection.getInputStream());
        connection.disconnect();
        return product;
    }

}

<强> @ XmlID / @ XMLIDREF

如果要在一次调用中发送所有数据,并且B和C共享对D实例的引用,则需要@ XmlID / @ XmlIDREF。您将需要一个对象来嵌套D的实例。在这种情况下,A是合适的。下面是我与用户有关自动执行此操作的线程:

循环引用

MOXy JAXB实现具有处理循环关系的扩展。这是通过@XmlInverseReference批注完成的。有关更多信息,请参阅: