2011-01-13 10 views
6

एक एप्लिकेशन जो मैं काम कर रहा हूं, विशेष रूप से डेटाबेस से मेमोरी तक लगातार वस्तुओं का एक समूह लाने के लिए हाइबरनेट का उपयोग करता है। एप्लिकेशन को अब और फिर डेटाबेस से इस इन-मेमोरी स्नैपशॉट को रीफ्रेश करना है, और यह डेटाबेस के साथ एकमात्र संचार होना चाहिए।मैं एक हाइबरनेट-मैप किए गए सेट को एक अपरिवर्तनीय सेट के रूप में कैसे लोड कर सकता हूं?

इन-मेमोरी ऑब्जेक्ट्स का उपयोग गणनाओं के समूह के लिए किया जाता है। गणना इन वस्तुओं को संशोधित नहीं करनी चाहिए। कुछ वर्ग को गलती से कहीं भी छोड़कर, और मुझे एक दिन बग को शिकार करना पड़ा। अब मैं सोच रहा हूं कि पूरे ऑब्जेक्ट पेड़ को अपरिवर्तनीय बनाने का सबसे अच्छा तरीका क्या है।

मान लीजिए वर्ग पदानुक्रम इस तरह दिखता है:

  • बेसब्री से सभी संस्थाओं और संग्रह
  • सभी संस्थाओं और संग्रह अंकन प्राप्त करने में कठिनाई:

    public class Building { // persistent entity 
        private String name; // hibernate-mapped property 
        private Set<Person> inhabitants; // hibernate-mapped collection 
    
        // getters 
    } 
    
    public class Person { // persistent entity 
        private String name; // hibernate-mapped property 
    
        // getters 
    } 
    

    मैं द्वारा डेटाबेस तक पहुँचने से ग्राहकों को रोका गया है mutable=false में हाइबरनेट मैपिंग्स

  • हाइबरनेट सत्र, या राज्य-परिवर्तन के किसी भी उदाहरण प्रदान नहीं कर रहा है जी दाओ विधियों।

अब त्रुटि जो मैं रोकना चाहता हूं, कोई गलती से building.getInhabitants().clear(); पर जा रहा है। मैं इन विकल्पों के बारे में सोच सकते हैं:

  1. मनुष्य लपेटकर: एक Collections.unmodifiableSet() कॉल में getInhabitants पहले रैप inhabitants लें, फिर इसे वापस।

    • पेशेवरों: कम से कम काम करते हैं, कम से कम अतिरिक्त कोड
    • विपक्ष: Feels hacky
  2. आवरण वर्गों: Building, MutableBuilding को PersonMutablePerson करने का नाम बदलें, और अपरिवर्तनीय कक्षाएं Building और Person प्रदान करते हैं। चूंकि मेरे एप्लिकेशन में एक स्पष्ट स्नैपशॉट बिंदु है, इसलिए मैं रिकॉर्ड्स को म्यूटेबल ऑब्जेक्ट्स (जैसा कि अब मैं करता हूं) के रूप में ला सकता हूं, गहराई से अपरिवर्तनीय प्रतियां बना सकता हूं और उस ऑब्जेक्ट पेड़ को ग्राहकों को पेश कर सकता हूं।

    • पेशेवर: सीधे जावा, कोई हाइबरनेट जादू नहीं। मुझे अपने पसंदीदा कीवर्ड का उपयोग करना पड़ता है: final
    • विपक्ष: लिखने और बनाए रखने के लिए अधिक कोड। इसके अलावा, क्या हाइबरनेट मेडेबल उदाहरणों को स्मृति में रखेगा?
  3. हाइबरनेट मानचित्रण जादू: का प्रयोग करें कि एक जादू कीवर्ड हाइबरनेट को निर्देश देने Collections.unmodifiableSet() या समकक्ष में संग्रह मेरी इकाई वस्तुओं पर सेट रैप करने के लिए।(नोट: मैं एक xml मैपिंग फ़ाइल का उपयोग)

    • पेशेवरों: मनोहर, बिना किसी अतिरिक्त कोड
    • विपक्ष: ऐसी कीवर्ड मौजूद न हो
  4. हाइबरनेट विस्तार: का प्रयोग करें कि एक हाइबरनेट विस्तार अपना ऑब्जेक्ट इंस्टेंटिएटर लिखने के लिए इंगित करें, और वहां इसे वापस करने से पहले Collections.unmodifiableSet() में सेट को लपेटें।

    • पेशेवरों: मेरी ही टिककर खेल
    • विपक्ष हैकिंग से अधिक सुरुचिपूर्ण: इस तरह के विस्तार बिंदु

मौजूद नहीं है अभी मैं # 2 की ओर झुकाव रहा हूँ, ज्यादातर क्योंकि मैं नहीं पता है कि 3 और 4 संभव हैं।

सबसे अच्छा तरीका क्या है?

उत्तर

6

विकल्प 1, निश्चित रूप से। यह "हैकी" नहीं है, और यही कारण है कि आपने संपत्तियों को पहली जगह में एक्सेस किया है :-) बस ध्यान दें कि आपको "विधि" के बजाय हाइबरनेट के साथ "फ़ील्ड एक्सेस" का उपयोग करना चाहिए, ताकि आप नहीं हाइबरनेट को एक अपरिवर्तनीय संग्रह प्रदान करने का जोखिम।

दुर्भाग्यवश, हाइबरनेट अपरिवर्तनीय संग्रह रखने का कोई तरीका प्रदान नहीं करता है, लेकिन मुझे लगता है कि ऑब्जेक्ट लोड होने के बाद आप सभी संग्रहों को संशोधित करने के लिए @ पोस्ट लोड ईवेंट श्रोता कर सकते हैं।

+0

+1 मुझे याद दिलाने के लिए कि हम गेटर्स और सेटर्स क्यों लिखते हैं :-) – KarlP

+0

यह सबसे अच्छा समाधान प्रतीत होता है। मुझे बस इस तथ्य के साथ आना होगा कि उत्परिवर्ती कक्षाएं कभी-कभी ठीक होती हैं! :) – oksayt

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

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