2012-08-03 10 views
5

मैंने जेपीए और जेएक्सबी के आधार पर एक आरईएसटी एपीआई लागू की है।जेपीए लांग @ आईडी जेएक्सबी @ एक्सएमएलआईडी एक्सएसडी सत्यापन त्रुटि उत्पन्न करता है

मैं मोटे तौर पर यह (बहुत सरल) की तरह एक वर्ग:

@Entity 
@XmlRootElement 
... 
public class Thing { 
    @Id 
    @GeneratedValue 
    ... 
    @XmlAttribute 
    @XmlID 
    @XmlJavaTypeAdapter(JAXBLongAdapter.class) 
    private Long id; 
    ... 
} 

हाइबरनेट (मेरे वर्तमान जेपीए प्रदाता) आईडी मूल्य के रूप में संख्या उत्पन्न करता है, लेकिन वे स्वाभाविक रूप से केवल एक ही एक प्रकार, बात में के लिए अद्वितीय हैं यह उदाहरण

अब एक्सएसडी का कहना है कि xsd: id (@XmlID) एक एनसीस्ट्रिंग है जो एक सादा संख्या नहीं हो सकता है इसलिए मैंने JAXBLongAdapter में संख्याओं के लिए '_' तैयार किया। - '_1'

की तरह अब स्कीमा सत्यापनकर्ता शिकायत:

[org.xml.sax.SAXParseException: cvc-id.2: There are multiple occurrences of ID value '_1'.] 

अगर मैं सही ढंग एक XSD इस बात को समझ: आईडी तत्व एक (स्ट्रिंग) मूल्य कि XML दस्तावेज में वैश्विक रूप से अद्वितीय है होना आवश्यक है। लेकिन यह डेटाबेस में आईडी का उपयोग करने के सामान्य तरीके से बहुत विपरीत है।

अब मैं क्या करूँ? मैं तीन बातें के बारे में सोचा:

  • एक प्रकार विशिष्ट उपसर्ग के साथ प्रत्येक प्रकार के लिए एक JAXBLongAdapter बनाएँ?
  • अन्य जेपीए आईडी जनरेटर का उपयोग करना, शायद यूयूआईडी? - पर कौनसा?
  • @XmlID और @XmlIDREF का उपयोग करना बंद करें, जो अनावश्यकता और सामान्य गड़बड़ी पैदा करता है।

ऐसा लगता है कि अब मुझे विभिन्न आईडी का उपयोग करने के लिए डेटाबेस स्कीमा को बदलना है। - लेकिन यह अच्छा होगा अगर आईडी कम रहे, क्योंकि वे यूआरएल में दिखाई देते हैं।

मेरा प्रश्न: क्या कोई आईडी जनरेटर है जो तुलनात्मक रूप से तेज़ है और वैश्विक स्तर पर अद्वितीय है? या इस से निपटने का कोई और तरीका है?

संपादित करें:

इस हैक थोड़े, काम करता है जेपीए आईडी बरकरार छोड़कर।

@XmlID 
@XmlAttribute(name="id") 
private String getXmlID(){ 
    return String.format("%s-%s", this.getClass().getSimpleName(), this.getId().toString()); 
} 

private void setXmlID(String xmlid){ 
    String prefix = String.format("%s-", this.getClass().getSimpleName()); 
    if(xmlid.startsWith(prefix)){ 
     this.id = Long.parseLong(xmlid.substring(prefix.length())); 
    }else{ 
     throw new IllegalArgumentException(xmlid+" does not look like "+prefix+"###"); 
    } 
} 

फ़ील्ड से जेएक्सबी एनोटेशन को एक्सएमएलआईडी के लिए समर्पित निजी गेटर्स/सेटर्स में ले जाकर।

+0

देखें http://stackoverflow.com/questions/9629948/jaxb-what-should-be-returned-from-beforemarshalmarshaller-method –

उत्तर

2

वही है जो मैंने कुछ समय के लिए किया था।

आप अपने आप से पूछ सकते हैं कि वास्तव में @XmlID इस डोमेन ऑब्जेक्ट के लिए marshalled क्या है?

मैंने एक बार सोचा @XmlID और @XmlIDREF जेएक्सबी में परिपत्र समस्या को हल कर सकता है।

यहां जेएक्सबी एनोटेशन के साथ मैं अपनी जेपीए इकाइयों के साथ क्या कर रहा हूं।

simple JPA @Id ऊपर न दें। यह जेपीए का दिल है।

@XmlRootElement 
public class Parent { 

    @Id 
    @XmlAttribute 
    private Long id; 

    @OneToMany 
    @XmlElement(name = "child") 
    @XmlElementWrapper 
    private Collection<Child> children; 
} 


@XmlRootElement 
public class Child { 

    @XmlAttribute 
    private Long getParentId() { 
     return parent.getId(); 
    } 

    @Id 
    @XmlAttribute 
    private Long id; 

    @ManyToOne 
    @XmlTransient // for preventing infinite circular problem 
    private Parent parent; 
} 
+0

हाय, आपके उत्तर के लिए धन्यवाद! - इसलिए आपने आईडी द्वारा "मैन्युअल" संदर्भों के पक्ष में आईडी और आईडीआरईएफ सुविधाओं का उपयोग करना बंद कर दिया है। - आप उमरल के दौरान वस्तुओं को दोबारा कैसे जोड़ते हैं? क्या आप किसी प्रकार का कारखाना या अदरक का उपयोग करते हैं? – sleeplessnerd

+0

मुझे वास्तव में उन्हें फिर से कनेक्ट करने की आवश्यकता नहीं है। अभिभावक और बच्चा बहुत अलग और अद्वितीय डोमेन ऑब्जेक्ट्स है। प्रत्येक जेएक्स-आरएस संसाधन पूरी तरह से माता-पिता या बच्चे के लिए काम करते हैं। क्योंकि माता-पिता.आईडी और चाइल्ड.आईडी डीबी में अद्वितीय है, इसलिए मेरी EntityManager उन्हें केवल उन आईडी के साथ पाता है। जब मुझे बच्चा अपनी आईडी के साथ पाता है तो पहले से ही पैरेंट फील्ड सेट होता है। –

2

नोट: मैं EclipseLink JAXB (MOXy) नेतृत्व और JAXB (JSR-222) विशेषज्ञ समूह का सदस्य हूँ।

क्या जवाब दिया जाना चाहिए

जवाब दोनों @XmlID और @XmlIDREF गुणों पर @XmlSchemaType एनोटेशन उपयोग करने के लिए होना चाहिए। दुर्भाग्य से जेएक्सबी आरआई उस संयोजन का लाभ नहीं उठाता है, और एक्लिप्ससेंक मोक्सी केवल @XmlID के लिए इसका लाभ उठाता है। मैं निम्नलिखित MOXY बग, अगर आप इस दृष्टिकोण में रुचि रखते हैं जो हम को ठीक कर सकता है में प्रवेश किया है:

कर्मचारी

package forum11791735; 

import java.util.List; 
import javax.xml.bind.annotation.*; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Employee { 

    @XmlID 
    @XmlJavaTypeAdapter(JAXBLongAdapter.class) 
    @XmlSchemaType(name="long") 
    private Long id; 

    @XmlIDREF 
    @XmlSchemaType(name="long") 
    private Employee manager; 

    @XmlElement(name="report") 
    private List<Employee> reports; 

} 

कार्यों के बीच

जो त्रुटि आप देख रहे हैं वह एक है स्कीमा सत्यापन के कारण होने के लिए पपीर। क्या इन त्रुटियों को अनदेखा करने के लिए Unmarshaller पर स्कीमा सत्यापन को अक्षम करना या ValidationEventHandler सेट करना संभव है?

ALTERNATIVES

आप @XmlID/@XmlIDREF उपयोग कर रहे हैं द्विदिश रिश्ते मैप करने के लिए तो आप MOXY के @XmlInverseReference विस्तार में रुचि हो सकती:

+0

हाय, कठोर अंतर्दृष्टि के लिए धन्यवाद! - बग रिपोर्ट में स्कीमा में ऐसा लगता है कि मैं एक्सएसडी ब्रह्मांड में आईडी/आईडीआरईएफ जोड़ी की अर्थपूर्ण जानकारी को "ढीला" करता हूं? - या क्या उन प्रकारों से जुड़े कोई विशेष अर्थपूर्ण नहीं है? मेरे विचार में अन्य भाषाओं के लिए आसान ग्राहक उत्पादन शामिल था, लेकिन मुझे संदेह है कि यह वास्तविकता बन गया है। हालांकि मैं सत्यापन रखना चाहता हूं। – sleeplessnerd

+0

यदि मैं आईडी/आईडीआरईएफ को छोड़ने के लिए तैयार हूं और xml में किसी प्रकार की संदर्भ प्रॉक्सी का उपयोग करके इसे मैन्युअल रूप से पुन: कार्यान्वित करना चाहता हूं - क्या यह JAXB मानक उपकरण के साथ ऐसा करने का एक साफ तरीका है? यह शायद मेरे संदर्भ-से-बाहरी-टू-एक्सएमएल-जेपीए-इकाई समस्या को भी हल करेगा, शायद .. – sleeplessnerd

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