2012-02-06 11 views
8

पर्यावरण:हाइबरनेट 4 के साथ मैन्युअल रूप से @ वर्जन फ़ील्ड कैसे सेट करें?

मुझे लगता है कि User इकाई है:

@Entity 
public class User implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Integer userId; 

    @Version 
    @Temporal(TemporalType.TIMESTAMP) 
    @Column(name = "VERSION", length = 19) 
    private Date version; 

    @Column(nullable = false, length = 20) 
    private String login; 

    // Getters and Setters 
} 

मैं जो उपयोगकर्ताओं को सूचीबद्ध एक खोज पृष्ठ है, तो मैं एक उपयोगकर्ता पर इसे संपादित करने के लिए क्लिक करें (दे रही है इसके userId URL में)।

संपादित रूप में, मैं सर्वर पर स्टोर कर उस संस्था के क्षेत्र और जब मैं बचाने मेरे उपयोगकर्ता मैं यह कर:

User user = entityManager.find(User.class, userId) 
user.setLogin(form.getLogin()); 
user.setVersion(form.getVersion()); 
user.setUserId(form.getUserId()); 
entityManager.merge(user); 

प्रश्न:

तो अगर मैं सही ढंग से समझ में आ आशावादी हाइबरनेट के साथ लॉकिंग, यदि मैं एक ही उपयोगकर्ता को संपादित करने के लिए अपने ब्राउज़र में 2 टैब खोलता हूं, तो पहले टैब पर लॉगिन अपडेट करें, और फिर दूसरे टैब पर लॉगिन, मेरे पास OptimisticLockException sho होना चाहिए क्या मैं नहीं हूँ

दरअसल, यह मेरे आवेदन पर मामला नहीं है ... मैंने सत्यापित किया है, form.getVersion() दोनों मामले में समान मान लौटाता है, भले ही दूसरे अपडेट में, user.version को पहले संपादन द्वारा अपडेट किया गया है।

क्या मुझे कुछ याद आ रही है?

EntityManager@RequestScoped बनाया गया है (इसलिए जब मैं विलय करने की कोशिश करता हूं तो मैं दो अलग-अलग EntityManager एस पर हूं ...)।

मैंने entityManager.lock(user, LockModeType.OPTIMISTIC_FORCE_INCREMENT)entityManager.merge(...) (as said here) से पहले करने की कोशिश की है, लेकिन इससे मदद नहीं मिली।

मैं जेबॉस 7.0.2 के साथ सीम 3 का उपयोग कर रहा हूं। फाइनल (जो हाइबरनेट 4 का उपयोग करता है)।

+0

क्या आप सुनिश्चित हैं कि इकाई प्रबंधक फ़्लश किया गया है (या लेनदेन प्रतिबद्ध है)? उत्पन्न SQL अद्यतन क्वेरी क्या है? –

+0

हां, [हाइबरनेट एसक्यूएल डंपिंग के सक्रियण] के साथ [http://stackoverflow.com/questions/9159752/how-to-get-jdbc-binding-parameters-from-hibernate-in-jboss-7) मैं देख सकता हूं एसक्यूएल अपडेट और जेडीबीसी 'वर्जन' फ़ील्ड बाइंडिंग जो 'यूजर' में 'वर्जन' में सेट है जो 'आईडीई आईडी =' में सेट है? और संस्करण =? '... मैंने' फ्लशइंटरसेप्टर 'विकसित किया है जिसे मेरे' अपडेट' फ़ंक्शन मौजूद होने के बाद कहा जाता है और जो 'entityManager.flush() 'करता है। –

उत्तर

4

असल में मुझे ऐसा करने का कोई तरीका मिला है ... लेकिन मुझे लगता है कि यह वास्तव में कुशल नहीं है (क्योंकि 1 और चयन अनुरोध है)।

User user = entityManager.find(User.class, userId) 
user.setLogin(form.getLogin()); 
user.setVersion(form.getVersion()); 
user.setUserId(form.getUserId()); 

entityManager.detach(user); 
entityManager.merge(user); 
entityManager.detach(user) साथ

, हाइबरनेट अब अपनी ही कहीं की नकल की मान के बजाय मेरी setted version मान का उपयोग करता ...

5

मैं सिर्फ इस पर कुछ और अधिक शोध किया था।

यह जेपीए कल्पना के अनुसार संस्करण क्षेत्र को संशोधित करने के लिए अनुमति नहीं है:

जेपीए 2.0 अंतिम युक्ति, धारा 3.4.2:

एक इकाई अपने संस्करण के राज्य का उपयोग कर सकते क्षेत्र या संपत्ति या संस्करण तक पहुंचने के लिए एप्लिकेशन द्वारा उपयोग के लिए एक विधि निर्यात करें, लेकिन संस्करण मान को संशोधित नहीं करना चाहिए। धारा 4.10, में उल्लिखित अपवाद के साथ केवल ऑब्जेक्ट में संस्करण विशेषता के मान को सेट या अद्यतन करने की अनुमति है।

नोट: सेक्शन 4.10 बैच अपडेट को संदर्भित करता है जो संस्करण विशेषता को अनदेखा करते हैं।

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