2012-04-12 6 views
7

मैं ओरेकल डेटाबेस का उपयोग कर रहा हूं और मेरे पास अनुक्रम और आईडी को सम्मिलित करने से पहले आईडी बनाने और ट्रिगर करने के लिए ट्रिगर है।जेपीए @ आईडी और डालने योग्य = झूठी, अद्यतन करने योग्य = झूठी फेंकता अपवाद

CREATE SEQUENCE CASE_SEQ START WITH 1001 INCREMENT BY 1 NOMAXVALUE; 

CREATE OR REPLACE TRIGGER CASE_TR_SEQ 
BEFORE INSERT ON CASE FOR EACH ROW 
BEGIN 
    SELECT CASE_SEQ.NEXTVAL INTO :NEW.CASE_ID FROM DUAL; 
END; 
/

तब मैं संपत्ति के साथ सरल इकाई है:

@Id 
@Column(name = "CASE_ID", insertable = false, updatable = false) 
private Long caseId; 

... जब मैं इस परियोजना का निर्माण करने की कोशिश मैं हो रही है:

Exception [EclipseLink-46] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): 
org.eclipse.persistence.exceptions.DescriptorException 
Exception Description: There should be one non-read-only mapping defined for the 
primary key field [CASE.CASE_ID]. 

जब मैं या तो insertable या updatable कीवर्ड निकालने , तो यह काम करता है। मुझे पता है कि जेपीए का उपयोग करके आईडी उत्पन्न करने के बहुत सारे समाधान हैं, जेपीए सेट (जेनरेट) आईडी सेट करने के लिए ओरेकल अनुक्रम (कॉल) का उपयोग कर सकते हैं। लेकिन मैं समझता हूं कि मेरे समाधान गलत क्यों हैं। मैं @Id एनोटेशन के साथ दोनों कीवर्ड का उपयोग क्यों नहीं कर सकता? मेरा विचार है: मैं जेपीए द्वारा केस आईडी डालने या अपडेट करने के लिए प्रतिबंधित करना चाहता हूं।

1) उचित आत्मा क्या है? मैं केवल @Id का उपयोग करना चाहिए:

@Id 
@Column(name = "CASE_ID") 
private Long caseId; 

या है बेहतर (सुरक्षित) को परिभाषित insertable = भी झूठी:

@Id 
@Column(name = "CASE_ID", insertable = false) 
private Long caseId; 

2) मुझे समझ में अर्थ नहीं है कि = updatable @Id के लिए झूठी (अद्यतन प्राथमिक कुंजी अर्थ नहीं है, लेकिन यह कच्चे एसक्यूएल के द्वारा ही संभव है), लेकिन इसका मतलब क्या() आप कुछ उदाहरण है जब यह फायदेमंद है:

@Id 
@Column(name = "CASE_ID", updatable = false) 
private Long caseId; 

संपादित 2012-04-13

मैं कुछ परीक्षण किया:

इकाई

@Id 
@Column(name = "CASE_ID") 
private Long caseId; 

जेपीए लोग इन

INSERT INTO CASE (CASE_ID, CASE_DATE, INFO) VALUES (?, ?, ?) 
bind => [3 parameters bound]|#] 

तो यह सुरक्षित नहीं है, क्योंकि जेपीए की कोशिश करता है की दुकान CASE_ID (जो तब से ओरेकल अनुक्रम से आईडी के आधार पर बदल दिया जाता है ट्रिगर)।

इकाई

@Id 
@Column(name = "CASE_ID", insertable = false) 
private Long caseId; 

विधि

public void createCase(final Case caseData) { 
    caseData.setCaseId(-1001L); 
    em.persist(caseData); 
} 

बनाएं जेपीए लोग इन

INSERT INTO CASE (CASE_DATE, INFO) VALUES (?, ?) 
bind => [2 parameters bound]|#] 

यह अच्छी बात है, क्योंकि CASE_ID डालने आदेश का हिस्सा नहीं है।

public void update() { 
    Case update = em.find(Case.class, 1023L); 
    update.setCaseId(1028L); 
} 

Exception [EclipseLink-7251] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): 
org.eclipse.persistence.exceptions.ValidationException 
Exception Description: The attribute [caseId] of class 
[com.wordpress.kamiluv.jsfprototype.model.entity.Case] is mapped to a primary 
key column in the database. Updates are not allowed. 

तो अब पिछले संस्करण सबसे सुरक्षित के रूप में लग रहा है, सही:

और CASE_ID का अद्यतन नहीं हो सके क्योंकि एनोटेशन आईडी है?

+1

http://stackoverflow.com/questions/3669883/hibernate-where-do-insertable-false-updatable-false-belong-in-composite-pr और http://stackoverflow.com/questions पर एक नज़र डालें/3805584/कृपया बताएं-सम्मिलित करने योग्य-झूठी-अद्यतन करने योग्य-झूठी और देखें कि यह आपकी सहायता करता है या नहीं। –

+0

@tech_learner दुर्भाग्य से – Ziletka

+1

मुझे यकीन नहीं है, अगर यह मदद करता है लेकिन क्या आप अपरिवर्तनीय कक्षा की तलाश में हैं? यदि फिर, इस पर एक नज़र डालें: http://www.mkyong.com/hibernate/hibernate-mutable-example-class-and-collection/ –

उत्तर

5

आप वर्तमान में अपने जेपीए एनोटेशन के साथ कह रहे हैं कि आपके पास @Id कॉलम है जिसे किसी भी तरह से सम्मिलित या अपडेट नहीं किया जा सकता है। आप डालने या अपडेट करने से पहले आईडी सेट करने में सक्षम होना चाहिए, लेकिन जेपीए को यह नहीं पता कि ऐसा कैसे किया जाए।यदि आप आईडी को अपने कोड में सेट नहीं करना चाहते हैं तो आपको जेपीए को किस रणनीति का उपयोग करना है (तालिका, अनुक्रम, पहचान, ऑटो) को बताने के लिए @Iener पर @GeneratedValue एनोटेशन का उपयोग करने की आवश्यकता होगी।

+0

ठीक है, लेकिन मैं किसी भी '@GeneratedValue' संभावनाओं का उपयोग नहीं करना चाहता , मैं डेटाबेस कॉलम में आईडी सेट करने के लिए ओरेकल ट्रिगर का उपयोग करना चाहता हूं। और '@Id' को हटाने का कोई अच्छा समाधान नहीं है क्योंकि जेपीए में '@Id' से जुड़ी कुछ कार्यक्षमताएं हैं: EntityManager ढूंढें (Case.class, caseId)। – Ziletka

+0

यदि आप केवल ओरेकल ट्रिगर का उपयोग करना चाहते हैं, तो @GeneratorValue (strategy = GenerationType.AUTO) आज़माएं। ओरेकल के बारे में निश्चित नहीं है, लेकिन मुझे एक सिबबेस टेबल पर ऑटो के साथ सफलता मिली है जिसने आईडी पीढ़ी को ही संभाला है। – bobz32

+0

यह काम करता है लेकिन मुझे लगता है कि यह अच्छा समाधान नहीं है, bacuase ATUTO रणनीति को विभिन्न अर्थों के लिए परिभाषित किया गया है ... DOC: ऑटो की एक रणनीति निर्दिष्ट करने के लिए EclipseLink को उपयोग करने की रणनीति का चयन करने की अनुमति देता है। आम तौर पर, ग्रहण लिंक रणनीति के रूप में तालिका चुनता है, क्योंकि यह सबसे पोर्टेबल रणनीति है। हालांकि, जब ऑटो निर्दिष्ट किया जाता है, डेटाबेस में डिफ़ॉल्ट तालिका बनाने के लिए स्कीमा पीढ़ी को कम से कम एक बार उपयोग किया जाना चाहिए। – Ziletka

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