我想知道是否可以在一個事務中在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 :非事務性連接:啓用
那就是它。更改此設置後,交易按預期工作。所以這不是休眠問題...
問候!
但我不是在談論一個hibernate對象。上述這種情況不起作用。如果我做了 開始交易; SELECT module.current_user('user'); UPDATE ....; 承諾; 然後它的工作。我認爲TransactionAttributeType.REQUIRES_NEW意味着這個函數在一個事務中執行。但它似乎不是...... – djnose
如果您遇到異常,請包括異常的完整堆棧跟蹤。使用REQUIRES_NEW標記方法可確保使用新事務來執行方法中的每個事務。這可以。不要認爲這是交易的問題,並向我們展示完整的異常堆棧跟蹤(以及使用的實際代碼)。 –
查看編輯後!謝謝你的幫助! – djnose