2012-01-17 68 views
0

我想知道是否可以在一個事務中在Hibernate中運行SELECT和UPDATE語句。 有一個非常特殊的情況,我不能改變。所以我必須調用一個SQL函數,然後更新一個表。 這個函數創建一些臨時的東西,用來更新表格。 如果在同一事務中未調用它,觸發器將導致更新失敗。在一個事務中使用JTA運行本機SELECT和UPDATE

所以,請不要告訴我,我應該改變:D我會如果我可以。 但無論如何...這裏是我的代碼應該在一個事務中運行,但不這樣做的:

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
public int nativeUpdateWithParams(String currentUser, boolean setCurrentUser, String nativeSql, Object...obj) {   
    try { 
     Query query; 
     if (nativeSql != null) { 
      if (setCurrentUser) { 
       String sql = "SELECT module.current_user(:param1)"; 
       query = em.createNativeQuery(sql); 
       query.setParameter("param1", currentUser); 
       query.getSingleResult(); 
      } 
      query = em.createNativeQuery(nativeSql); 
      int i=0; 
      for (Object param:obj) { 
       i++; 
       query.setParameter("param"+i, param); 
      } 
      int result = query.executeUpdate(); 
      return result; 
     } else { 
      return 0; 
     } 
    } catch (Exception ex) {      
     ex.printStackTrace(); 
    } finally {    
     return 0;    
    } 
} 

休眠似乎至少創建兩個交易執行SELECT和UPDATE。 如果我改變Transactionattribute到:

@TransactionAttribute(TransactionAttributeType.MANDATORY) 

在客戶端創建一個交易(我總是犯..不管是什麼happends) 和我寫:

String test = "SELECT module.current_user('userXYZ')"; 
query = em.createNativeQuery(test + ";" + nativeSql); 

我得到一個execption類似「更新返回的東西....」,但它的工作原理。 如果有人能夠幫助我解決這個問題,這將是非常好的!

謝謝

編輯: 異常不會幫助一點,因爲它是從「更新」表觸發的結果。

Caused by: org.postgresql.util.PSQLException: FEHLER: You are not a real person. 
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1525) 
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1309) 
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:188) 
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:452) 
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:354) 
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:308) 
at org.hibernate.engine.query.NativeSQLQueryPlan.performExecuteUpdate(NativeSQLQueryPlan.java:210) 
... 72 more 

要獲取詳細: 如果我做一個控制檯上顯示以下/ Postgres的它就像一個魅力:

begin transaction; 
SELECT module.current_user('userXYZ'); 
update public.carrier set carrier_comment='whatever' where carrier_id=57300; 
commit; 

我的作品!

,如果我那樣做:

SELECT module.current_user('userXYZ'); 
update public.carrier set carrier_comment='whatever' where carrier_id=57300; 

我得到如上descriped錯誤:「你是不是一個真正的人」

EDIT2: 如果有人曾經有相同的問題,解決方案就像愚蠢:) 只需檢查您的Glassfish設置(JDBC - JDBC連接池)並確保您沒有激活:

Transac :非事務性連接:啓用

那就是它。更改此設置後,交易按預期工作。所以這不是休眠問題...

問候!

回答

0

當然可以。你爲什麼不能?當你告訴Hibernate從DB獲取一個對象時,你認爲Hibernate做了什麼?然後更新這個對象?它執行SQL select查詢來獲取對象,然後執行SQL更新查詢來更新它。

+0

但我不是在談論一個hibernate對象。上述這種情況不起作用。如果我做了 開始交易; SELECT module.current_user('user'); UPDATE ....; 承諾; 然後它的工作。我認爲TransactionAttributeType.REQUIRES_NEW意味着這個函數在一個事務中執行。但它似乎不是...... – djnose

+0

如果您遇到異常,請包括異常的完整堆棧跟蹤。使用REQUIRES_NEW標記方法可確保使用新事務來執行方法中的每個事務。這可以。不要認爲這是交易的問題,並向我們展示完整的異常堆棧跟蹤(以及使用的實際代碼)。 –

+0

查看編輯後!謝謝你的幫助! – djnose

相關問題