<Union-subclass> (TABLE_PER_CLASS) के साथ पहचान कॉलम कुंजी पीढ़ी का उपयोग नहीं किया जा सकता


96

com.something.SuperClass:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class SuperClass implements Serializable {
    private static final long serialVersionUID = -695503064509648117L;

    long confirmationCode;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO) // Causes exception!!!
    public long getConfirmationCode() {
        return confirmationCode;
    }

    public void setConfirmationCode(long confirmationCode) {
        this.confirmationCode = confirmationCode;
    }
}

com.something.SubClass:

@Entity
public abstract class Subclass extends SuperClass {
    private static final long serialVersionUID = 8623159397061057722L;

    String name;

    @Column(nullable = false)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

मुझे यह अपवाद देता है:

Caused by: org.hibernate.MappingException: Cannot use identity column key
generation with <union-subclass> mapping for: com.something.SuperClass

आईडी बनाने के लिए मेरे लिए सबसे अच्छा और सबसे सुविधाजनक तरीका क्या है? मैं अपनी विरासत की रणनीति को बदलना नहीं चाहता।

जवाबों:


230

यहां समस्या यह है कि आप "टेबल-प्रति-वर्ग" विरासत को मिलाते हैं और GenerationType.Auto । MsSQL में एक पहचान कॉलम पर विचार करें। यह कॉलम आधारित है। "तालिका-प्रति-वर्ग" रणनीति में आप प्रति कक्षा एक तालिका का उपयोग करते हैं और प्रत्येक में एक आईडी होती है।

प्रयत्न:

@GeneratedValue(strategy = GenerationType.TABLE)


2
सही समाधान। यहां तक ​​कि हाइबरनेट मंचों का भी यह समाधान नहीं लगता है, और वे मंच के चारों ओर जा रहे थे ।hibernate.org/…
स्प्रिंग मंकी

1
क्या यह मुद्दा केवल MySql के साथ है या इसका नियमित रूप से मैं एक वीडियो को प्रति कक्षा दृष्टिकोण के लिए देखता हूं और यह ठीक काम कर रहा था कि पोस्टग्रेज का उपयोग किया गया था
प्रशांत

1
मैं हाल ही में एक Dropwizard एप्लिकेशन का परीक्षण करते समय इसमें भाग गया। मेरे मामले में मैंने सत्र कारखाना बनाने के लिए DW द्वारा उपयोग किए गए समान कॉन्फ़िगरेशन विकल्पों का उपयोग करना सुनिश्चित करके इसे संबोधित किया। मुझे पूरा यकीन है कि संपत्ति "hibernate.id.new_generator_mappings" को सच करने के लिए निर्धारित है। यह DW 0.7.0, हाइबरनेट 4.3.1, DB H2 था।
sfitts

1
यह पूरी तरह से काम करता है। हालाँकि, यह अत्यधिक अनुशंसित है कि 'TABLE' आईडी जनरेशन रणनीति का उपयोग न करें क्योंकि यह बहुत सारी क्वेरीज़ (चयन, प्रविष्टि और अद्यतन) को ट्रिगर करता है और प्राथमिक कुंजी के लिए अद्वितीय मान उत्पन्न करने के लिए ताले बनाए रखता है। तो इसका एक वैकल्पिक हल क्या होगा यदि हमारे पास थोड़े बड़े इनहेरिटेंस परिदृश्य हों? यह निश्चित रूप से प्रदर्शन को काफी हद तक प्रभावित करेगा।
मैक

8

मुझे आश्चर्य है कि अगर यह एक डेटाबेस बोली विशिष्ट समस्या है, क्योंकि पोस्टग्रेक्यूएल के साथ एक यूट्यूब ट्यूटोरियल देखने के बाद अंतर्निहित डेटाबेस के रूप में मैंने देखा कि वीडियो का निर्माता डिफ़ॉल्ट रूप से डिफ़ॉल्ट @GeneratedValue के साथ एक ऐप चलाता है। मेरे मामले में (अंतर्निहित डेटाबेस MySQL है) मुझे जेनरेशनटाइप को @GeneratedValue रणनीति को संशोधित करना पड़ा था। ठीक उसी तरह जैसे कि zoidbeck प्रस्तावित करता है।

ये रहा वीडियो: https://www.youtube.com/watch?v=qIdM4KQOtH8


Postgres इनहेरिटेंस करने में सक्षम है इसलिए आप सही हो सकते हैं कि यह डेटाबेस विशिष्ट है: postgresql.org/docs/8.1/static/ddl-inherit.html वीडियो यह नहीं बताता है (या मैंने इसे याद किया) कि स्कीमा कैसे उत्पन्न होती है। तो हो सकता है कि NHibernate postgres dial इसे अपने आप से करने में सक्षम हो या इसके बजाय आपको 'INHERITS' मैन्युअल रूप से जोड़ना होगा। असल में मैं बता नहीं सकता।
zoidbeck

6
PostgreSQL पर, हाइबरनेट का उपयोग करने के लिए चूक करता है GenerationType.SEQUENCE। इसलिए यह अपने आप वहां काम करता है। यह बिल्कुल PostgreSQLs के साथ कुछ नहीं करना है INHERITS
हेनिंग

मैं एक ही ट्यूटोरियल का उपयोग कर रहा हूं और @Generated का उपयोग करके समस्या पैदा कर रहा था क्योंकि मैं MySql का उपयोग कर रहा हूं। और जब तक मैंने यह पोस्ट नहीं देखा तब तक बहुत बार डीबग करना
दीन जॉन

5

Zoidbeck के जवाब से सहमत हैं। आपको रणनीति बदलने की आवश्यकता है:

@GeneratedValue(strategy = GenerationType.TABLE)

लेकिन यह सब नहीं है, आपको एक नई तालिका बनाने की आवश्यकता है, जो आपके सार तालिका की प्राथमिक कुंजी अनुक्रम को बनाए रखेगा। अपनी मैपिंग को संशोधित करें

@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "ConfirmationCodeGenerator")
@TableGenerator(table = "SEQUENCES", name = "ConfirmationCodeGenerator")
public long getConfirmationCode() {
   return confirmationCode;
}

और डेटाबेस में एक नई तालिका निम्नानुसार दिखनी चाहिए: यहां छवि विवरण दर्ज करें

जब आप अपना एप्लिकेशन चलाते हैं, तो हाइबरनेट एक पंक्ति सम्मिलित करेगा जहां sequence_nameइकाई का नाम ( SuperClassइस उदाहरण में) sequence_next_hi_valueहोगा और मूल्य स्वचालित रूप से बढ़ा दिया जाएगा और सभी उपवर्गों की तालिकाओं को लागू करने के नए रिकॉर्ड के लिए उपयोग किया जाएगा।


2

हमारे मामले में, हम देव और उत्पादन के लिए एक PostreSQL डेटाबेस और परीक्षणों के लिए एक स्मृति hsqldb डेटाबेस का उपयोग करते हैं। हम आईडी बनाने के लिए दोनों मामलों में एक अनुक्रम का उपयोग कर रहे हैं। जाहिरा तौर पर पोस्टग्रेज के लिए GenerationType.AUTOचूक करता SEQUENCEहै, लेकिन हमारे स्थानीय परीक्षणों में विफल रहा (hsqldb के लिए कुछ और करने के लिए डिफ़ॉल्ट होना चाहिए)।

तो हमारे लिए काम किया समाधान, स्पष्ट रूप से उपयोग करें GenerationType.SEQUENCE


1

आप विरासत के लिए @MappedSuperclass का उपयोग कर सकते हैं


0

MySQL और PostgreSQL के बीच एक SQL मानक अनुपालन है। PostgreSQL Postgres SQL92 / 99 का एक अच्छा सबसेट समझता है और इन सबसेट के लिए कुछ ऑब्जेक्ट-ओरिएंटेड फीचर्स। पोस्टग्रेज्स जटिल रूटीन और नियमों को घोषणात्मक एसक्यूएल प्रश्नों, उपश्रेणियों, विचारों, बहु-उपयोगकर्ता समर्थन, लेनदेन, क्वेरी ऑप्टिमाइज़ेशन, इनहेरिटेंस और सरणियों से निपटने में सक्षम है। विभिन्न डेटाबेस में डेटा का चयन करने का समर्थन नहीं करता है।

माई एसक्यूएल MySQL अपनी नींव के रूप में SQL92 का उपयोग करता है। अनगिनत प्लेटफार्मों पर चलता है। मैसकल उन प्रश्नों का निर्माण कर सकता है जो विभिन्न डेटाबेस से तालिकाओं में शामिल हो सकते हैं। ANSI और ODBC सिंटैक्स दोनों का उपयोग करके बाएँ और दाएँ दोनों बाहरी जोड़ का समर्थन करता है। उस रिलीज से MySQL 4.1 के रूप में, MySQL उपश्रेणियों को संभाल लेगा। रिलीज़ 5 के रूप में समर्थित दृश्य।

विस्तृत विवरण के लिए कृपया देखें। http://www-css.fnal.gov/dsg/external/freeware/pgsql-vs-mysql.html


कृपया इस बारे में बुरा न मानें, लेकिन मुझे लगता है कि MySQL और PostgreSQL तुलना विषय के लिए अप्रासंगिक है (भले ही हाइबरनेट डिफॉल्ट उनके लिए अलग हैं)।
21
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.