2012-09-27 12 views
7

मैं प्ले फ्रेमवर्क 2 के साथ Ebean उपयोग कर रहा हूँ और कभी कभी यह इस तरह की OptimisticLockException साथ आता है:OptimisticLockException प्ले फ्रेमवर्क 2

play.core.ActionInvoker$$anonfun$receive$1$$anon$1: Execution exception [[OptimisticLockException: Data has changed. updated [0] rows sql[update manager set modification_time=?, session_id=?, expiration_date=? where id=? and rating=? and creation_time=? and modification_time=? and name=? and surname=? and login=? and password_hash=? and email=? and session_id=? and expiration_date=?] bind[null]]] 

यह तब हो जब गिने-चुने अभिनेताओं डेटाबेस का उपयोग करने के लिए शुरू करते हैं।

तो, प्रबंधक वर्ग है:

public class Manager extends Model { 
@Getter @Setter 
Long id; 

@Getter @Setter 
private String name; 

@Getter @Setter 
private String surname; 

@Column(unique = true) 
@Getter @Setter 
private String login; 

@Getter @Setter 
private String passwordHash; 

@Getter @Setter 
private String email; 

@Embedded 
@Getter @Setter 
private ManagerSession session; 

@Getter 
private Timestamp creationTime; 

@Getter 
private Timestamp modificationTime; 

@Override 
public void save() { 
    this.creationTime  = new Timestamp(System.currentTimeMillis()); 
    this.modificationTime = new Timestamp(System.currentTimeMillis()); 
    super.save(); 
} 

@Override 
public void update() { 
    this.modificationTime = new Timestamp(System.currentTimeMillis()); 
    super.update(); 
} 

} 

बचाने() और अद्यतन() का इस्तेमाल किया बजाय @PrePersist एनोटेशन हुक, Ebean की वजह से इसका समर्थन नहीं करता। जैसा कि मुझे पता है @ वीरसन एनोटेशन ऑलवे ऑप्टिस्टिक लॉक मोड लाता है, इसलिए मैं इस तरह की चाल का उपयोग शुरू करता हूं। मुझे पता है कि ऑप्टिस्टिकिस्ट लॉक क्या है, लेकिन इस स्थिति को कैसे हल किया जाना चाहिए, जब कई कलाकारों को एक ही डीबी रिकॉर्ड को संशोधित करना चाहिए, जहां अंतिम संशोधन जीतता है?

उत्तर

15

Solution:

समस्या: एक अलग EBean मॉडल सीधे सहेजा जा रहा है खेल फार्म से कारण बनता है या तो OptimisticLockException, या जब @version का उपयोग कर इसे NullPointerException कारण बनता है।

Form<Venue> form = form(Venue.class).bindFromRequest(); 
form.get().update(id); // this causes the exception 

समाधान: फ़ॉर्म पैरामीटर से बाध्य करने से पहले फ़ॉर्म को डेटाबेस से ऑब्जेक्ट की आपूर्ति करने का समर्थन करना चाहिए। अनुरोध में पाए गए पैरामीटर को ऑब्जेक्ट पर प्रासंगिक गुणों को ओवरराइट करना चाहिए। शायद bindFromRequest() से पहले भरने() फोन:

Form<Venue> form = form(Venue.class).fill(Venue.find.byId(id)).bindFromRequest(); 
form.get().update(id); 
+0

हाँ, आप सही हैं। लेकिन मेरी परेशानी यहाँ नहीं थी। कक्षा पदानुक्रम में गहरी @ वीरसन एनोटेशन में समस्या थी। वैसे भी, आपका उत्तर उस व्यक्ति के लिए बहुत उपयोगी है जो पहली बार ऐसी परेशानी का सामना कर रहा है। इसे स्वीकार करने दें। –

+0

फॉर्म * बाध्यकारी से पहले * venue.find.byId (आईडी)) * कॉल करने के लिए आपको ** आईडी ** कैसे मिलता है? –

2

मैं इस OptmistLockException समस्या हल हो गई जब अद्यतन करने के लिए कोशिश कर रहा बस नियंत्रक इकाई आईडी गुजर। उपयोगकर्ता को मूल्य बदलने से रोकने के लिए, मान छुपा हुआ क्षेत्र के रूप में पारित किया गया था।

<input type="hidden" name="id" value="@formVar(<identifierVariable>).value"/> 

नियंत्रक पक्ष पर, मैं जांचता हूं कि प्राप्त फ़ॉर्म में त्रुटियां हैं या नहीं। नकारात्मक मामले में, मैं प्रपत्र में संलग्न इकाई को अद्यतन करता हूं।

public static Result update() { 
    Form<Entity> filledForm = form.bindFromRequest(); 
    if (filledForm.hasErrors()) { 
     flashError("app.oh_snap", "app.change_things"); 
    } else { 
     Entity entity = filledForm.get(); 
     entity.update(); 
    } 
} 
+0

कोई भी चालाक उपयोगकर्ता यूआई से छिपे हुए फ़ील्ड का मूल्य ** सबसे महत्वपूर्ण रूप से ** ** को बदलने में सक्षम होगा। यह एक अच्छा समाधान नहीं हो सकता है। –

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