2011-09-30 23 views
11

मैं जेपीए को हाइबरनेट (3.2.7) के साथ ओएमएम कार्यान्वयन के रूप में उपयोग कर रहा हूं। मेरे पास एक इकाई संशोधित की जा रही है और फिर विलय हो गई है। मेरे पास इस विशेषता पर कुछ विशेषताएँ सुनिश्चित करने के लिए @EntityListeners भी हैं।जेपीए - हाइबरनेट @ वर्जन गलत तरीके से

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

@Entity 
@EntityListeners({MyListener.class}) 
public class MyEntity { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private Long id; 

    private String myValue; 

    @Version  
    private Long version ; 
} 

और इस श्रोता::

public class MyListener { 

    @PreUpdate 
    public void preUpdate(MyEntity ua) { 
     ua.setMyValue("default"); 
    } 
} 

अब मान लीजिए कि मैं इन मूल्यों के साथ एक वस्तु db पर है: (आईडी = 1, myValue =

बेहतर व्याख्या करने के लिए, मैं इस वस्तु है 'defalut', संस्करण = 1)। मैंने इस ऑब्जेक्ट को पढ़ा है, अलग कर दिया है, इसे क्लाइंट को पास कर दिया है और इसे myValue = 'new' के साथ वापस ले लिया है और मर्ज ऑपरेशन कर रहा है (श्रोता मेरे 'वैल्यू को' डिफ़ॉल्ट 'में बदलता है और इसलिए ऑब्जेक्ट परिणाम डीबी को असम्बद्ध किया जाता है), फ़्लश और लेनदेन से बाहर निकलें (इसलिए प्रतिबद्ध है)। उसके बाद मुझे अपने ऑब्जेक्ट पर संस्करण = 2 मिलता है, लेकिन संस्करण = 1 डीबी पर।

क्या यह एक हाइबरनेट बग है? या एक जेपीए बग?

+0

क्या आप अपने विधि कॉल पदानुक्रम और कॉलिंग अनुक्रम के बारे में उल्लेख कर सकते हैं। हो सकता है कि आपकी विलय विधि अद्यतन विधि से पहले काम कर रही हो। – mbaydar

+0

मुझे लगता है कि हाइबरनेट गंदे चेक झूठी रिटर्न देता है, इसलिए आपकी ऑब्जेक्ट डीबी को स्पर्श नहीं करती है (कोई अपडेट क्वेरी उत्पन्न नहीं होती है), लेकिन पहली बार जब आप एक सेटर कहते हैं तो हाइबरनेट आपके संस्करण फ़ील्ड में वृद्धि कर रहा है। जब भी अद्यतन मूल्य डीबी में लिखा जाता है तो संस्करण फ़ील्ड केवल तभी बढ़ाया जाना चाहिए। यह शायद एक हाइबरनेट बग है। –

उत्तर

2

मैं कहूंगा कि यह एक अपेक्षित व्यवहार है। Hibernate manual के अनुसार, @PreUpdate "डेटाबेस अद्यतन ऑपरेशन से पहले निष्पादित" है। तो, हाइबरनेट ने पहले से ही यह पता लगाया है कि इसे गंदे चेक चलाकर अद्यतन करना है, और इसे सच करना है।

गंदे चेक @PreUpdate के बाद नहीं हो सकता है, क्योंकि हाइबरनेट को @PreUpdate पर कॉल नहीं करना चाहिए जब तक कि गंदे चेक सत्य न हो। और यदि कोई अपडेट चलाने जा रहा है, तो संस्करण को बढ़ाया जाना चाहिए।

क्या आपने के लिए @PreUpdate के बजाय श्रोता का उपयोग करने के बारे में सोचा है? मेरा मानना ​​है कि इस प्रक्रिया में काफी जल्दी है कि यह पूर्व-गंदा जांच होगी, और इस प्रकार वह व्यवहार होगा जो आप चाहते हैं।

0

मेरे लिए यह विनिर्देश उल्लंघन की तरह दिखता है। या हो सकता है कि यह बहुत मजबूत शब्द है, शायद यह कहने के लिए बेहतर है कि ऐसा कोने का मामला स्पष्ट रूप से पर्याप्त नहीं है। जेपीए 1.0 (हाइबरनेट 3.2.7 कार्यान्वयन में से एक होने) विनिर्देश काफी स्पष्ट रूप जब संस्करण अद्यतन किया जाना चाहिए मंत्र:

संस्करण विशेषता हठ प्रदाता क्रम जब वस्तु डेटाबेस के लिए लिखा है के द्वारा अद्यतन किया गया है।

भी लागू इकाई में बुनियादी विशेषता सेटिंग (जेपीए 2.0) जोर से है:

एक जीवन चक्र कॉलबैक विधि इकाई है जिस पर वह शुरू हो जाती है की गैर संबंध राज्य संशोधित कर सकते हैं।

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