2010-07-26 3 views
1

J'ai la structure de l'entité suivante (A, B, C, D sont des entités):Comment persister entité avec deux parents utilisant hibernate et service web?

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

Je veux persister l'entité A avec mise en veille prolongée, mais je l'envoie sur le service Web (références cycliques sont éliminés). Donc, sur le serveur, je reçois des parents qui "connaissent" les enfants et les enfants ne connaissent pas les parents et je dois tout relier. Le problème est que je dois faire correspondre D avec deux parents - ce qui était sur le client une seule instance D, sur le serveur est devenu deux instances qui doivent être fusionnées et D n'a pas été précédemment persisté de sorte qu'il ne contient pas d'identifiant unique cela peut être égalé. Je pense à deux solutions:

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. 

Comment dois-je faire? Suis-je sur la bonne voie? Btw, j'utilise hibernate, cxf et jaxb.

Répondre

1

Les deux approches sont raisonnables:

Web Call Serice deux fois

Certains utilisateurs rompent les messages en petits morceaux afin que seules les données de propriété privée est envoyée sur le fil dans un seul message. Les références à des données non privées sont représentées par des liens (les liens spécifient comment obtenir l'objet à partir d'un autre service JAX-RS). Ensuite, vous pouvez avoir XmlAdapters que résoudre les liens (voir ci-dessous):

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

Si vous allez envoyer toutes les données dans un appel et B et les références des actions C Pour les instances de D, vous aurez besoin de @ XmlID/@ XmlIDREF. Vous aurez besoin d'un objet pour imbriquer les instances de D sous. Dans ce cas, sous A serait approprié. Ci-dessous un fil j'ai eu avec un utilisateur sur l'automatisation de ceci:

Références cycliques

La mise en œuvre Moxy JAXB a des extensions pour le traitement des relations cycliques. Ceci est fait par l'annotation @XmlInverseReference. Pour plus d'informations, voir:

+0

Merci pour la réponse détaillée. – draganstankovic

Questions connexes