2012-07-12 49 views
0

可能是一個新手Java的東西,但它在這裏。使用JPA調用INSERT存儲過程到Oracle 11g數據庫。在將數據傳送到數據庫表格方面,一切正常。Java Swing/JPA/Oracle插入兩次

我已經將JPA代碼包裝到Java Swing應用程序中。我的問題是數據不知何故被提交兩次。我提交數據時顯示JOptionPane.showMessageDialog。那隻顯示一次。但是當我查詢表時,表中有兩個條目。這裏是我的代碼....

按鈕代碼

JButton btnSubmit = new JButton("Submit"); 
btnSubmit.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent arg0) { 
     AddNewCustomer(); 
    } 
}); 
btnSubmit.setBounds(24, 341, 91, 23); 
frmNewCustomer.getContentPane().add(btnSubmit); 

操作方法

public void AddNewCustomer() { 
    Customer.AddCustomer(this.txtFirstName.getText(), 
      this.txtLastName.getText(), this.txtAddress.getText(), 
      this.txtCity.getText(), this.txtState.getText(), 
      this.txtEmail.getText(), this.txtPhone.getText()); 

    JOptionPane.showMessageDialog(frmNewCustomer, "Added new customer", 
      "Status", 1); 
} 

protected static void AddCustomer(String sFirstName, String sLastName, 
     String sAddress, String sCity, String sState, String sEmail, 
     String sPhone) { 
    try { 
     factory = Persistence 
       .createEntityManagerFactory(PERSISTENCE_UNIT_NAME); 
     EntityManager em = factory.createEntityManager(); 
     em.getTransaction().begin(); 

     Query q = em.createNamedQuery("AddCustomer"); 
     q.setParameter("p_PHONE", sPhone); 
     q.setParameter("p_STATE", sState); 
     q.setParameter("p_FIRST_NAME", sFirstName); 
     q.setParameter("p_ADDRESS", sAddress); 
     q.setParameter("p_EMAIL", sEmail); 
     q.setParameter("p_CITY", sCity); 
     q.setParameter("p_LAST_NAME", sLastName); 
     int r = q.executeUpdate(); 
     em.getTransaction().commit(); 

     List results = q.getResultList(); 
     if (results != null) { 
      Object id = results.get(0); 
      if (id != null) { 
       System.out.println(id.toString()); 
      } 
     } 
     em.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
+0

如果你所刪除'列出結果= q.getResultList();'(及以下幾行)? – 2012-07-12 09:35:02

+0

我這樣做的共振是從Insert SPROC中獲取新創建的ID和OUT參數。 SPROC有一個Sequence.nextVal的觸發器。 – Beachdog 2012-07-12 16:45:38

回答

0

您需要刪除調用getResultList(),這是執行相同的查詢再次(它是一個插入查詢,而不是選擇查詢)。無論如何您都不需要獲取ID,請參閱this question。您根本不需要使用查詢,但是因爲創建條目的適當方式應該使用entityManager.persist(obj)(假設您有一個JPA實體,因此您應該使用JPA實體)。

+0

該問題提到用於執行插入操作的存儲過程,這可能是使用命名查詢的原因。 – 2012-07-12 09:56:06

+0

啊。不過,他不需要執行兩次插入查詢。您需要創建第二個查詢並進行選擇,但這不會輕易保證您在多線程環境中獲得正確的對象。根據存儲過程的不同,可能需要用觸發器代替它,並按照打算使用的方式使用JPA。 – Thor84no 2012-07-12 10:04:30

+0

幾乎偏離主題:爲了在多用戶/多線程環境中保持安全,第二個查詢必須在與第一個相同的事務中執行並使用正確的隔離級別。但在這種情況下,似乎最好只是將其忽略掉。完全偏離主題:我仍然希望有一天能夠更好地支持Java ORM中的存儲過程。我不是他們的粉絲,但(通常是出於我無法控制的原因),我一直在其他項目上打他們。 – 2012-07-12 12:49:32

0

我解決了這個問題。更改代碼....

protected static void AddCustomer(String sFirstName,String sLastName, String sAddress, String sCity, String sState,String sEmail,String sPhone) 
{ 

    try { 
     factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); 
     EntityManager em = factory.createEntityManager(); 
     em.getTransaction().begin(); 

     Query q = em.createNamedQuery("AddCustomer"); 
     q.setParameter("p_PHONE", sPhone); 
     q.setParameter("p_STATE", sState); 
     q.setParameter("p_FIRST_NAME", sFirstName); 
     q.setParameter("p_ADDRESS", sAddress); 
     q.setParameter("p_EMAIL", sEmail); 
     q.setParameter("p_CITY", sCity); 
     q.setParameter("p_LAST_NAME", sLastName); 
     //int r = q.executeUpdate();     
     //em.getTransaction().commit(); 

     List results = q.getResultList(); 
     if(results != null) 
     {   
      Object id = results.get(0); 
      if(id != null) 
      { 
       System.out.println(id.toString()); 
      } 
      em.getTransaction().commit(); 
     } 
     em.close(); 
    } catch (Exception e) { 

     e.printStackTrace(); 
    } 

} 
+0

請將您的答案標記爲解決方案,謝謝。 – CSchulz 2012-07-13 08:52:30