2012-05-16 23 views
37

मेरे पास बैकएंड पर पोस्टग्रेस डीबी से कनेक्ट किया गया है, और एक जावा क्लास 'जजमेंट' डीबी में तालिका 'निर्णय' मैपिंग कर रहा है, जब मैंने डीबी में निर्णय जारी रखने की कोशिश की, तो उसने फेंक दिया निम्न त्रुटियों:हाइबरनेट को अगली अनुक्रम मान नहीं मिल सका

Caused by: org.hibernate.exception.SQLGrammarException: could not get next sequence value 
... 
Caused by: org.postgresql.util.PSQLException: ERROR: relation "hibernate_sequence" does not exist 

मेरी प्रलय वर्ग इस

@Entity 
@Table(name = "JUDGEMENTS") 
public class Judgement implements Serializable, Cloneable { 

    private static final long serialVersionUID = -7049957706738879274L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "JUD_ID") 
    private Long _judId; 
... 

और मेरी मेज निर्णय की तरह लग रहा है:

Column |   Type    |      Modifiers       
-------------+-----------------------------+--------------------------------------------------------- 
jud_id  | bigint      | not null default nextval('judgements_id_seq'::regclass) 
rating  | character varying(255)  | 
last_update | timestamp without time zone | 
user_id  | character varying(255)  | 
id   | integer      | 
Indexes: 
    "judgements_pkey" PRIMARY KEY, btree (jud_id) 
Foreign-key constraints: 
    "judgements_id_fkey" FOREIGN KEY (id) REFERENCES recommendations(id) 
    "judgements_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(user_id) 

और मेरे पास डीबी

में कोई वर्ग नाम 'judgements_id_seq' है और कोई मुझे बता सकता है कि क्या गलत है ??? धन्यवाद।

उत्तर

72

हाइबरनेट की पोस्टग्रेएसक्यूएल बोली बहुत उज्ज्वल नहीं है। यह आपके प्रति-सीरियल अनुक्रमों के बारे में नहीं जानता है, और यह मानते हुए कि वैश्विक डेटाबेस-व्यापी अनुक्रम है जिसे "हाइबरनेट_यूसेन्स" कहा जाता है जिसे इसका उपयोग किया जा सकता है।


(अद्यतन: ऐसा लगता है कि नए हाइबरनेट संस्करणों डिफ़ॉल्ट प्रति-तालिका दृश्यों जब GenerationType.IDENTITY निर्दिष्ट किया जाता है का उपयोग कर सकते अपने संस्करण का परीक्षण करें और नीचे के बजाय इसका उपयोग करता है, तो यह आप के लिए काम करता है।।)


आपको प्रत्येक अनुक्रम को स्पष्ट रूप से निर्दिष्ट करने के लिए अपने मैपिंग को बदलने की आवश्यकता है। यह कष्टप्रद, दोहराव, और व्यर्थ है।

@Entity 
@Table(name = "JUDGEMENTS") 
public class Judgement implements Serializable, Cloneable { 

    private static final long serialVersionUID = -7049957706738879274L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="judgements_id_seq") 
    @SequenceGenerator(name="judgements_id_seq", sequenceName="judgements_id_seq", allocationSize=1) 
    @Column(name = "JUD_ID") 
    private Long _judId; 
... 

allocationSize=1 काफी महत्वपूर्ण है। यदि आप इसे छोड़ देते हैं, तो हाइबरनेट अंधाधुंध मान लेगा कि अनुक्रम को INCREMENT 50 के साथ परिभाषित किया गया है, इसलिए जब इसे अनुक्रम से मूल्य प्राप्त होता है तो यह उस मूल्य और उसके नीचे 49 मान अद्वितीय जेनरेट की गई कुंजी के रूप में उपयोग कर सकता है। यदि आपका डेटाबेस अनुक्रम 1 - डिफ़ॉल्ट रूप से बढ़ता है - तो इसके परिणामस्वरूप अद्वितीय उल्लंघनों का परिणाम होगा क्योंकि हाइबरनेट मौजूदा कुंजी का पुन: उपयोग करने का प्रयास करता है।

ध्यान दें कि एक समय में एक कुंजी प्राप्त करना परिणामस्वरूप प्रति अतिरिक्त अतिरिक्त यात्रा में परिणाम देगा। जहां तक ​​मैं बता सकता हूं कि हाइबरनेट INSERT ... RETURNING का उपयोग करने के लिए सक्षम रूप से जेनरेट की गई कुंजी को वापस करने में सक्षम नहीं है, और न ही यह स्पष्ट रूप से जेडीबीसी जेनरेट की गई कुंजी इंटरफ़ेस का उपयोग कर सकता है। यदि आप इसे अनुक्रम का उपयोग करने के लिए कहते हैं, तो यह पर मूल्य प्राप्त करने के लिए insert पर कॉल करेगा, जिसके परिणामस्वरूप दो राउंड ट्रिप होंगे। उस लागत को कम करने के लिए, आप अंतर्निहित डेटाबेस अनुक्रम मैपिंग और पर सेट करने के लिए याद रखने के लिए बहुत सारे आवेषण के साथ मुख्य अनुक्रमों पर अधिक वृद्धि सेट कर सकते हैं। इससे हाइबरनेट को nextval कम बार कॉल करने और चाबियों को कैश करने के लिए चाबियों को कैश करने का कारण बन जाएगा।

मुझे यकीन है कि आप उपरोक्त से देख सकते हैं कि मैं पोस्टग्रेएसक्यूएल के साथ इसका उपयोग करने के परिप्रेक्ष्य से कम से कम हाइबरनेट डिजाइन विकल्पों से सहमत नहीं हूं। उन्हें getGeneratedKeys का उपयोग करना चाहिए या का उपयोग कुंजी के लिए DEFAULT के साथ करना चाहिए, डेटाबेस को इस पर ध्यान दें कि बिना हाइबरनेट के अनुक्रमों के नाम पर स्वयं को परेशान करना या उन्हें स्पष्ट पहुंच देना।

बीटीडब्ल्यू, यदि आप पीजी के साथ हाइबरनेट का उपयोग कर रहे हैं तो आप संभवतः an oplock trigger for Pg भी चाहते हैं ताकि हाइबरनेट की आशावादी लॉकिंग सामान्य डेटाबेस लॉकिंग के साथ सुरक्षित रूप से बातचीत कर सके। इसके बिना या ऐसा कुछ आपके हाइबरनेट अपडेट अन्य नियमित SQL क्लाइंट्स के माध्यम से किए गए परिवर्तनों को रोक देगा। मुझसे पूछो कि मैं कैसे जानता हूं।

+0

क्या आप मुझे इसी तरह की समस्या से मदद करने के इच्छुक हैं? यहां लिंक है: http: // stackoverflow।कॉम/प्रश्न/25252541/जेनरेट-टू-ए-जावा-अमूर्त-सुपरक्लास-ओवर-माइस्क्ल – CodeMed

+0

@ क्रेग रिंगर मैंने एपोकेशन आकार = 1 जोड़कर समस्या हल कर ली है, लेकिन क्या यह एक उचित तरीका है? –

+0

'@ जेनरेटेड वैल्यू (रणनीति = जेनरेशन टाइप .इडेंटिटी)' ने मेरे लिए स्प्रिंग डेटा जेपीए, पोस्टग्रेएसक्यूएल 9.5, और जेडीबीसी चालक के वी 9.4 के साथ काम किया। –

38

मुझे लगता है कि @GeneratedValue(strategy = GenerationType.IDENTITY) का उपयोग करने के लिए हाइबरनेट को PostgreSQL पर 'धारावाहिक' कॉलम का उपयोग करने के लिए मिलता है।

+0

धन्यवाद आदमी, मैंने रणनीति संपत्ति का उपयोग नहीं किया है, यही कारण है कि त्रुटि हो रही है। –

2

मैं भी एक MySQL करने के लिए PostgreSQL प्रवास के बारे में कुछ नोट्स जोड़ने के लिए करना चाहते हैं:

  1. अपने DDL में, वस्तु नामकरण में का इस्तेमाल करते हैं '_' (अंडरस्कोर) शब्द अलग होने के लिए चरित्र ऊंट मामले सम्मेलन के लिए। उत्तरार्द्ध MySQL में ठीक काम करता है लेकिन PostgreSQL में बहुत से मुद्दों को लाता है।
  2. आपके मॉडल वर्ग-पहचान फ़ील्ड में @GeneratedValue एनोटेशन के लिए पहचान रणनीति हाइबरनेट 3.2 और बेहतर में PostgreSQLDialect के लिए ठीक काम करती है। इसके अलावा, ऑटो रणनीति MySQLDialect के लिए सामान्य सेटिंग है।
  3. यदि आप अपने मॉडल कक्षाओं को @Table के साथ एनोटेट करते हैं और तालिका के नाम के बराबर इन्हें एक शाब्दिक मान सेट करते हैं, तो सुनिश्चित करें कि आपने सार्वजनिक स्कीमा के तहत संग्रहीत करने के लिए टेबल बनाए हैं।

जहां तक ​​मुझे अब याद है, आशा है कि ये सुझाव आपको कुछ मिनटों का परीक्षण और त्रुटि झुकाव दे सकते हैं!

+0

FWIW मिश्रित मामला ठीक है। मामले को संरक्षित करने के लिए आपको बस "डबल कोट" करना होगा। यह वास्तव में एसक्यूएल मानक व्यवहार है, MySQL बस इसे अनदेखा करता है। –

2

मुझे लगता है कि आपके पास पहले से ही पर्याप्त उत्तर है, लेकिन मुझे बिल्कुल वही त्रुटि मिली और मेरी समस्या एक और थी। और मैंने इसे हल करने की कोशिश करने में थोड़ा सा समय बर्बाद कर दिया।

मेरे मामले में समस्या पोस्टग्रेज़ में अनुक्रम का मालिक था। इसलिए, यदि ऊपर दिए गए किसी भी समाधान ने आपकी समस्या का समाधान नहीं किया है, तो जांच करें कि अनुक्रम का स्वामी उपयोगकर्ता/भूमिका है जिसके पास अनुमति होनी चाहिए।

CREATE SEQUENCE seq_abcd 
    START WITH 1 
    INCREMENT BY 1 
    NO MINVALUE 
    NO MAXVALUE 
    CACHE 1; 

ALTER TABLE public.seq_abcd OWNER TO USER_APP; 

मुझे आशा है कि यह किसी के लिए भी उपयोगी हो सकता है:

एक नमूना का पालन करता है।

7
मैं पहले की तरह ही त्रुटि मिली

, प्रकार अपने डेटाबेस CREATE SEQUENCE hibernate_sequence START WITH 1 INCREMENT BY 1 NOCYCLE;

में इस क्वेरी मेरे लिए काम है कि, अच्छी किस्मत ~

+0

यह वास्तव में समस्या का समाधान नहीं करता है यदि हमारे पास एकाधिक अनुक्रम हैं जिन्हें – aggietech

+0

कम से कम पोस्टग्रेज़ के लिए उपयोग किया जाना आवश्यक है, यह "कोई चक्र नहीं है" और "NOCYCLE" नहीं है –

11

आप GenerationType की रणनीति GenerationType.IDENTITY के साथ अपने @GeneratedId स्तंभ स्थापित करने के लिए के बजाय जरूरत .यूयू

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Column(name = "JUD_ID") 
private Long _judId; 
0

हमारे द्वारा उपयोग किए जा रहे डेटाबेस को Postgres SQL कॉन्फ़िगरेशन फ़ाइल में search_path के अंतर्गत उल्लिखित किया जाना चाहिए। यह डेटाबेस नाम के साथ search_path सेट करके Postgressql कॉन्फ़िगरेशन फ़ाइल को संपादित करके किया जा सकता है उदाहरण के लिए: TESTDB।

  1. पोस्टग्रेस एसक्यूएल डाटाबेस के डेटा फ़ोल्डर के तहत postgressql.conf फ़ाइल खोजें।
  2. search_path = "$ user", सार्वजनिक, TESTDB सेट करें;
  3. परिवर्तन को प्रभावित करने के लिए पोस्टग्रेस एसक्यूएल सेवा को पुनरारंभ करें।

उपर्युक्त परिवर्तन करने के बाद यह मेरे लिए काम करता था।

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