2010-04-01 8 views
7

मैं जावा डेस्कटॉप एप्लिकेशन विकसित कर रहा हूं और दृढ़ता के लिए जेपीए का उपयोग कर रहा हूं। मैं एक समस्या नीचे का उल्लेख किया है:जेपीए - इकाई डिजाइन समस्या

मैं दो संस्थाओं है:

  • देश
  • शहर

देश निम्न विशेषता है:

  • COUNTRYNAME (पी)

सिटी के पश्चात विशेषता है:

  • CityName

अब वहाँ के रूप में दो अलग-अलग देशों में ही नाम के दो शहरों हो सकता है, datbase में शहर तालिका के लिए PrimaryKey एक समग्र प्राथमिक बना कुंजी है CityName और CountryName का।

अब मेरे सवाल जावा

@Entity 
    public class Country implements Serializable { 
     private String countryName; 

     @Id 
     public String getCountryName() { 
      return this.countryName; 
     } 
    } 

    @Entity 
    public class City implements Serializable { 
      private CityPK cityPK; 
      private Country country; 

      @EmbeddedId 
      public CityPK getCityPK() { 
       return this.cityPK; 
      } 
    } 


    @Embeddable 
    public class CityPK implements Serializable { 
     public String cityName; 
     public String countryName; 
    } 

में एक Entity रूप City की प्राथमिक कुंजी लागू करने के लिए कैसे अब हम जानते हैं कि City को Country से संबंध OneToMany है और यह दिखाने के लिए है उपरोक्त कोड में रिश्ते, मैंने country वैरिएबल City कक्षा में जोड़ा है। country वस्तु में एक और cityPK वस्तु में अन्य:

लेकिन तब हम डुप्लिकेट डेटा (countryName) City वर्ग 'वस्तु में दो स्थानों में संग्रहीत है।

लेकिन दूसरी तरफ, दोनों जरूरी हैं:

cityPK में
  • countryName वस्तु आवश्यक है, क्योंकि हम इस तरह से समग्र प्राथमिक कुंजी को लागू।

  • country ऑब्जेक्ट में आवश्यक है क्योंकि यह ऑब्जेक्ट्स के बीच रिलेशनशिप दिखाने का मानक तरीका है।

इस समस्या को हल करने के लिए कैसे करें?

उत्तर

7

CityPK में countryName केवल पढ़ने के लिए @Column(insertable = false, updatable = false) का उपयोग कर के रूप में चिह्नित हो जानी चाहिए और countryName रों उसी स्तंभ को मैप किया जाना चाहिए (name संपत्ति का उपयोग कर):

@Entity 
    public class City implements Serializable { 
      @EmbeddedId 
      private CityPK cityPK; 

      @ManyToOne 
      @JoinColumn(name = "countryName") 
      private Country country; 
    } 


    @Embeddable 
    public class CityPK implements Serializable { 
     public String cityName; 

     @Column(name = "countryName", insertable = false, updatable = false) 
     public String countryName; 
    } 
+0

क्या यह इस प्रकार की समस्या से निपटने का एक मानक तरीका है? क्या यह समस्या जेपीए में आम है? –

+0

@ यतेन्द्र: हाँ, यह एक मानक तरीका है (यदि आप सरोगेट कुंजी का उपयोग नहीं करते हैं, जैसा कि पीटर सुझाव देता है)। – axtavt

3

IMO इस तरह के मुद्दों से निपटने के लिए होगा उचित तरीके एक प्राकृतिक प्राथमिक कुंजी के बजाय जेनरेटेड आंतरिक (आमतौर पर Long) आईडी का उपयोग करने के लिए - यह पूरी समस्या को समाप्त करता है। बेशक, इसके लिए आपके डीबी स्कीमा में संशोधन की आवश्यकता है, लेकिन आपकी पोस्ट से मुझे लगता है कि यह संभव है।

@Entity 
public class City implements Serializable { 
    private Long id; 

    private String name; 
    private Country country; 

    @Id 
    @GeneratedValue 
    @Column(name = "CITY_ID") 
    public Long getId() { 
     return this.id; 
    } 
    private void setId(Long id) { 
     this.id = id; 
    } 

    // more getters, setters and annotations 
} 
+0

तब मुझे लगता है कि मैं समानता के बराबर विधि में 'id' का उपयोग नहीं कर सकता। सही बात? –

+0

@ यतेन्द्र क्यों नहीं? एक ही नाम वाले दो शहरों लेकिन अलग-अलग देश में अलग-अलग आईडी होनी चाहिए। आपको केवल यह सुनिश्चित करना होगा कि आप तालिका में दो बार एक ही देश के उसी शहर को सम्मिलित न करें। इसे डीबी ट्रिगर द्वारा या हाइबरनेट इंटरसेप्टर द्वारा लागू किया जा सकता है। –

+0

आप 'id' का उपयोग' बराबर() 'में नहीं कर सकते क्योंकि डेटाबेस द्वारा 'id' उत्पन्न होता है। और ऑब्जेक्ट जारी नहीं होने तक उपलब्ध नहीं होगा। गेविन किंग के 'जावा पर्सिस्टेंस विद हाइबरनेट' का संदर्भ लें, बिजनेस की और सरोगेट कुंजी पर चर्चा देखें। – Ram