2011-07-27 12 views
6

पिछले कुछ दिनों में मैंने MOXY JAXB का उपयोग करके, एक हाइबरनेट मॉडल के एक्सएमएल मार्शलिंग/अनमर्शलिंग के लिए समर्थन करने का प्रयास किया है। ऐसा करने की कोशिश कर रहा है, मैंने हाइबरनेट प्रॉक्सी ऑब्जेक्ट्स के साथ एक समस्या में भाग लिया है। की तरह कुछ पर विचार करें:(moxy) jaxb marshaling और हाइबरनेट प्रॉक्सी ऑब्जेक्ट्स

@XmlAccessorType(XmlAccessType.NONE) 
public class User { 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "address") 
    @XmlElement 
    public Address getAddress() { 
     return address; 
    } 
} 

@XmlAccessorType(XmlAccessType.NONE) 
@XmlSeeAlso(CoolAddress.class) 
public abstract class Address { 
    // Something 
} 

@XmlAccessorType(XmlAccessType.NONE) 
public class CoolAddress extends Address { 
    @XmlElement 
    public String getSomething() { 
     return something; 
    } 
} 

मेरे समस्या यह है कि हाइबरनेट पते के एक प्रॉक्सी वस्तु getAddress फोन करके प्राप्त को दर्शाता है:

public class User { 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "address") 
    public Address getAddress() { 
     return address; 
    } 
} 

public abstract class Address { 
    // Something 
} 

public class CoolAddress extends Address { 
    public String getSomething() { 
     return something; 
    } 
} 

मैं इस कोड निम्नलिखित तरीके से MOXY JAXB का उपयोग कर मैप करने के लिए कोशिश की है() उपयोगकर्ता पर। फिर, जब जेएक्सबी वस्तु को मार्शल करने की कोशिश करता है, तो यह पता नहीं लगा सकता कि यह वास्तव में एक कूल एड्रेस है जो मार्शल की कोशिश कर रहा है, जिसके परिणामस्वरूप कूलएड्रेस में उन गुणों का मार्शल नहीं किया जा रहा है।

मैं googled है/निम्नलिखित संभव समाधान पर विचार किया:

  • कुछ रास्ते में मुझे वस्तु दूसरे के साथ मार्शल की जा रही बदलने के लिए अनुमति देता है JAXB से एक कॉलबैक मिलता है। यह मुझे प्रॉक्सी से वास्तविक वस्तु प्राप्त करने की अनुमति देगा।
  • मॉडल में सभी ऑब्जेक्ट्स को स्पर्श करें जो हाइबरनेट को वास्तविक वस्तुओं को लाएगा। मैं सभी गैर-क्षणिक गुणों के माध्यम से मैन्युअल रूप से चलने के अलावा ऐसा करने का कोई भी स्मार्ट तरीका नहीं ढूंढ पाया है, जो शांत थकाऊ है।
  • सत्र में उत्सुक लाने के लिए हाइबरनेट सेट करें, मैं मॉडल को मार्शल कर रहा हूं।

मैं वैकल्पिक सुझावों की तलाश में हूं, या यदि उपर्युक्त सुझावों में से एक को कार्यान्वित करना संभव है (और आसान)। किसी भी मदद की सराहना की है :)।

+0

क्या 'CoolAddress'' पता 'बढ़ाता है? –

+0

हां, क्षमा करें। मैं इसे लिखना भूल गया हूँ। –

उत्तर

6

इस हाइबरनेट समस्या को हल करने के लिए आप XmlAdapter का उपयोग करने में सक्षम हो सकते हैं।XmlAdapter कुछ ऐसा दिखाई देगा मार्शल विधि में तर्क प्रॉक्सी से वास्तविक वस्तु में बदलने के लिए है, जहां की तरह:

package forum6838323; 

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

public class AddressAdapter extends XmlAdapter<Address, Address> { 

    @Override 
    public Address unmarshal(Address v) throws Exception { 
     return v; 
    } 

    @Override 
    public Address marshal(Address v) throws Exception { 
     // TODO Auto-generated method stub 
     return null; 
    } 

} 

आप XmlAdapter इस प्रकार कॉन्फ़िगर करें:

public class User { 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "address") 
    @XmlJavaTypeAdapter(AddressAdapter.class) 
    public Address getAddress() { 
     return address; 
    } 
} 

आप पारित करने के लिए की जरूरत है JAXB marshaller के लिए एक प्रारंभ XmlAdapter, तो आप ऐसा कर सकते हैं और साथ ही, एक उदाहरण के लिए निम्न देखें:


वैकल्पिक EclipseLink जेपीए का उपयोग

नोट: EclipseLink जेपीए में आलसी लोड हो रहा है इस मुद्दे का कारण नहीं है:

उपयोगकर्ता

package forum6838323; 

import javax.persistence.*; 
import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlRootElement; 

@Entity 
@Table(name="users") 
@XmlRootElement 
public class User { 

    private int id; 
    Address address; 

    @Id 
    @XmlAttribute 
    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "address") 
    public Address getAddress() { 
     return address; 
    } 

    public void setAddress(Address address) { 
     this.address = address; 
    } 

} 

पता

package forum6838323; 

import javax.persistence.*; 
import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlSeeAlso; 

@Entity 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name="TYPE", discriminatorType=DiscriminatorType.STRING) 
@DiscriminatorValue("ADDRESS") 
@XmlSeeAlso(CoolAddress.class) 
public class Address { 

    private int id; 
    private String street; 

    @Id 
    @XmlAttribute 
    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public String getStreet() { 
     return street; 
    } 

    public void setStreet(String street) { 
     this.street = street; 
    } 

} 

CoolAddress

package forum6838323; 

import javax.persistence.*; 

@Entity 
@DiscriminatorValue("COOL") 
public class CoolAddress extends Address { 

    private String something; 

    public String getSomething() { 
     return something; 
    } 

    public void setSomething(String something) { 
     this.something = something; 
    } 

} 

डेमो

package forum6838323; 

import javax.persistence.EntityManager; 
import javax.persistence.EntityManagerFactory; 
import javax.persistence.Persistence; 
import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     EntityManagerFactory emf = Persistence.createEntityManagerFactory("Forum6838323"); 
     EntityManager em = emf.createEntityManager(); 

     User user = em.find(User.class, 2); 
     System.out.println("user.address BEFORE marshal: " + user.address); 

     JAXBContext jc = JAXBContext.newInstance(User.class); 
     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(user, System.out); 

     System.out.println("user.address AFTER marshal: " + user.address); 
    } 

} 

आउटपुट

आप उत्पादन से देख सकते हैं कि पता वैल ue को आंशिक रूप से लोड किया जा रहा है क्योंकि क्षेत्र मार्शल से पहले शून्य है और बाद में आबादी है:

user.address BEFORE marshal: null 
[EL Finest]: 2011-07-27 11:47:13.118--ServerSession(23503403)--Thread(Thread[main,5,main])--Execute query ReadObjectQuery(name="Forum6838323" referenceClass=Address) 
[EL Finest]: 2011-07-27 11:47:13.118--ServerSession(23503403)--Connection(10272075)--Thread(Thread[main,5,main])--Connection acquired from connection pool [default]. 
[EL Fine]: 2011-07-27 11:47:13.118--ServerSession(23503403)--Connection(10272075)--Thread(Thread[main,5,main])--SELECT ID, TYPE, STREET, SOMETHING FROM ADDRESS WHERE (ID = ?) 
    bind => [2] 
[EL Finest]: 2011-07-27 11:47:13.118--ServerSession(23503403)--Connection(10272075)--Thread(Thread[main,5,main])--Connection released to connection pool [default]. 
[EL Finest]: 2011-07-27 11:47:13.118--UnitOfWork(6131844)--Thread(Thread[main,5,main])--Register the existing object [email protected] 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<user id="2"> 
    <address xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="coolAddress" id="2"> 
     <street>2 B Road</street> 
     <something>Cool Road</something> 
    </address> 
</user> 
user.address AFTER marshal: [email protected] 
+1

आपको बहुत अच्छे जवाब के लिए धन्यवाद। –

संबंधित मुद्दे