Как сохранить сущность с двумя родителями, используя спящий и веб-сервис? - PullRequest
1 голос
/ 27 июля 2010

У меня есть следующая структура сущности (A, B, C, D - сущности):

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

Я хочу сохранить объект A в спящем режиме, но отправляю его через веб-службу (циклические ссылки исключены). Итак, на сервере я получаю родителей, которые «знают» о детях, а дети не знают о родителях, и мне нужно снова все связать. Проблема в том, что мне нужно сопоставить D с двумя родителями - то, что на клиенте было одним экземпляром D, на сервере стало двумя экземплярами, которые необходимо объединить, и D ранее не сохранялось, поэтому он не содержит уникальный идентификатор это может быть сопоставлено. Я думаю о двух решениях:

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 Ответ

1 голос
/ 27 июля 2010

Оба подхода разумны:

Дважды вызвать веб-службу

Некоторые пользователи разбивают сообщения на более мелкие куски, так что по сети передаются только личные данные.в одном сообщении.Ссылки на данные, не принадлежащие частным лицам, представляются в виде ссылок (ссылки указывают, как получить объект из другой службы 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 под.В этом случае под А будет уместно.Ниже приведена ветка с пользователем, посвященная автоматизации этого процесса:

Циклические ссылки

МОКСИРеализация JAXB имеет расширения для обработки циклических отношений.Это делается с помощью аннотации @XmlInverseReference.Для получения дополнительной информации см .:

...