2010-04-14 68 views
0

我有獨特= true的collumn ..在考試類.... 我發現,因爲事務automaticaly COMMITED如此給力的承諾,我使用 em.commit()JPA 2.0的EclipseLink檢查獨特

但是,我想知道如何檢查它是否是唯一的。運行查詢不是一個解決方案,因爲它可能是一個instert後檢查,因爲協調....

這是最好的方法來檢查uniqness?

List<Exam_Normal> exam_normals = exam.getExam_Normal(); 
    exam.setExam_Normal(null); 

    try { 
     em.persist(exam); 
     em.flush(); 

     Long i = 0L; 
     if (exam_normals != null) { 
      for (Exam_Normal e_n : exam_normals) { 
       i++; 
       e_n.setItem(i); 
       e_n.setId(exam); 
       em.persist(e_n); 
      } 
     } 
    } catch (Exception e) { 
     System.out.print("sfalma--"); 
    } 
} 

d

回答

3

不幸的是,JPA無法避免違反唯一約束時的事務回滾,因爲規範要求使用此異常來標記事務進行回滾。另外,因爲當您發出'鎖'調用使用JPA 2.0 API'鎖'調用不會確保只有鎖定線程可以插入對象。鎖'將阻止實體的更新但不阻止插入。

您需要像在代碼中一樣執行'persist',但儘可能使其保持接近事務的開始位置,或使操作在其自己的事務中進行。

如果'persist'必須是較大事務的一部分,並且如果持續失敗並不妨礙應用程序的這部分成功執行,那麼您應該存儲此事務中的Entity實例,您將能夠'merge'當您的應用程序從回滾中恢復後,將它們轉換爲任何後續事務。

+0

謝謝你的回覆... 那麼你會怎麼做我的情況? 鎖定沒有幫助,因爲你說.. 考試對象有獨特的collumn工作人員。 如何捕捉錯誤並通知用戶發生了唯一違規? – GorillaApe 2010-04-16 00:26:59

+0

啊,是的,當然,沒有考慮到這一行可能不存在的事實。感謝您指出了這一點。 – 2010-04-17 20:26:00

+0

它確實取決於您的應用程序,但需要記住的一些事情是:如果您可以將該行的創建與單個事務隔離,或使用JPA EntityManager.flush()API,則會在事務開始時插入該行您將節省在交易中的其他更改。如果您擔心失去考試實體中的信息,您可以隨時參考受管實體。事務回滾後,用戶在同一個實例中修復唯一性問題,並將同一個實例合併到新的TXN中的新EntityManager中。 – 2010-04-22 13:04:13

1

不過,我想知道如何檢查,如果它是獨一無二的。運行一個查詢不是一個解決方案,因爲它可能是一個插入後檢查,因爲併發...

JPA 2.0允許悲觀鎖定並添加三個鎖定模式。這可能是您的用例的一個選項。

一些參考:

+0

所以你的意思是我應該鎖定,然後檢查值是否存在,然後堅持和解鎖? – GorillaApe 2010-04-15 00:35:43

+0

@Parhs我想避免一個異常(並因此再次啓動,因爲事務將被標記爲回滾),是的。 – 2010-04-15 01:42:18

0

我假定列不是主鍵(@Id),在這種情況下,你的應用程序必須保證唯一性。該領域的唯一性保證可能必須來自其他地方。該領域的價值是什麼?這裏有一些想法

如果它是一個計數器,那麼你也許可以使用@Singleton狀態bean(JavaEE的6見this

如果使用的是EE5,然後無狀態Bean與@Entity映射到汽車生成的密鑰

+0

我正在使用java ee 6 不幸的是它不是一個計數器它是一個字符串... 它不是主鍵,但它必須是獨特的商業規則。 – GorillaApe 2010-04-15 00:32:31

+0

然後你將不得不保證你的應用程序的唯一性。如果我可能好奇,字符串的性質是什麼。價值是如何產生的? – 2010-04-15 00:42:24

+0

如何保證它?這是一個「名稱」莫名其妙...它是由用戶輸入生成的。 – GorillaApe 2010-04-15 00:52:00