Java 如何使用hibernate和web服务将实体持久化为双亲实体?
我有以下实体结构(A、B、C、D为实体): 我想用hibernate持久化实体A,但我通过web服务发送它(消除了循环引用)。因此,在服务器上,我接收到“知道”孩子的家长和不知道家长的家长,我需要再次链接所有内容。问题是我需要将D与两个父级匹配—客户端上的是一个D实例,服务器上的是两个必须合并的实例,并且D以前没有被持久化,因此它不包含可以匹配的唯一id。我正在考虑两种解决方案:Java 如何使用hibernate和web服务将实体持久化为双亲实体?,java,web-services,hibernate,jaxb,cxf,Java,Web Services,Hibernate,Jaxb,Cxf,我有以下实体结构(A、B、C、D为实体): 我想用hibernate持久化实体A,但我通过web服务发送它(消除了循环引用)。因此,在服务器上,我接收到“知道”孩子的家长和不知道家长的家长,我需要再次链接所有内容。问题是我需要将D与两个父级匹配—客户端上的是一个D实例,服务器上的是两个必须合并的实例,并且D以前没有被持久化,因此它不包含可以匹配的唯一id。我正在考虑两种解决方案: 1. Call web service twice – in first call persist Ds and
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。这两种方法都是合理的: 给网络服务打两次电话 一些用户正在将消息分成更小的块,以便在单个消息中仅通过有线发送私有数据。对非私有数据的引用表示为链接(链接指定如何从另一个JAX-RS服务获取对象)。然后,您可以使用XmlAdapters来解析链接(请参见下文):
导入java.net.HttpURLConnection;
导入java.net.URL;
导入javax.xml.bind.JAXBContext;
导入javax.xml.bind.JAXBException;
导入javax.xml.bind.annotation.adapters.XmlAdapter;
导入org.example.product.product;
公共类ProductAdapter扩展了XmlAdapter{
私有JAXBContext JAXBContext;
公共产品适配器(){
试一试{
jaxbContext=jaxbContext.newInstance(Product.class);
}捕获(JAXBEException e){
抛出新的运行时异常(e);
}
}
@凌驾
公共字符串封送处理(产品v)引发异常{
如果(null==v){
返回null;
}
返回“http://localhost:9999/products/“+v.getId();
}
@凌驾
公共产品解组(字符串v)引发异常{
如果(null==v){
返回null;
}
URL=新URL(v);
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
connection.setRequestMethod(“GET”);
setRequestProperty(“接受”、“应用程序/xml”);
Product Product=(Product)jaxbContext.createUnmarshaller().unmarshal(connection.getInputStream());
连接断开();
退货产品;
}
}
@XmlID/@XMLIDREF
如果要在一次调用中发送所有数据,并且B和C共享对D实例的引用,则需要@XmlID/@XmlIDREF。您将需要一个对象来嵌套D的实例。在这种情况下,根据A的规定将是合适的。下面是我与一位用户讨论的关于自动化的一条线索:
导入java.net.HttpURLConnection;
导入java.net.URL;
导入javax.xml.bind.JAXBContext;
导入javax.xml.bind.JAXBException;
导入javax.xml.bind.annotation.adapters.XmlAdapter;
导入org.example.product.product;
公共类ProductAdapter扩展了XmlAdapter{
私有JAXBContext JAXBContext;
公共产品适配器(){
试一试{
jaxbContext=jaxbContext.newInstance(Product.class);
}捕获(JAXBEException e){
抛出新的运行时异常(e);
}
}
@凌驾
公共字符串封送处理(产品v)引发异常{
如果(null==v){
返回null;
}
返回“http://localhost:9999/products/“+v.getId();
}
@凌驾
公共产品解组(字符串v)引发异常{
如果(null==v){
返回null;
}
URL=新URL(v);
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
connection.setRequestMethod(“GET”);
setRequestProperty(“接受”、“应用程序/xml”);
Product Product=(Product)jaxbContext.createUnmarshaller().unmarshal(connection.getInputStream());
连接断开();
退货产品;
}
}
@XmlID/@XMLIDREF
如果要在一次调用中发送所有数据,并且B和C共享对D实例的引用,则需要@XmlID/@XmlIDREF。您将需要一个对象来嵌套D的实例。在这种情况下,根据A的规定将是合适的。下面是我与一位用户讨论的关于自动化的一条线索:
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.
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;
}
}