Я хотел бы знать, возможно ли выполнить оператор SELECT и UPDATE в Hibernate всего за одну транзакцию.
Есть особая ситуация, которую я не могу изменить. Поэтому я должен вызвать функцию SQL, а затем ОБНОВИТЬ таблицу.
Эта функция создает временные элементы, которые используются для обновления таблицы.
Если он не вызывается в одной и той же транзакции, триггер вызывает сбой обновления.
Так что, пожалуйста, не говорите мне, что я должен изменить это: 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;
}
}
Hibernate, кажется, создает по крайней мере две транзакции для выполнения SELECT и UPDATE.
Если я изменю атрибут транзакции на:
@TransactionAttribute(TransactionAttributeType.MANDATORY)
создать транзакцию на клиенте (которую я всегда совершаю .. независимо от того, что происходит)
и я пишу:
String test = "SELECT module.current_user('userXYZ')";
query = em.createNativeQuery(test + ";" + nativeSql);
я получаю исполнение, похожее на "update возвращает что-то ....", но оно работает.
Было бы здорово, если бы кто-то помог мне решить эту проблему!
Спасибо
Edit:
Исключение не поможет, потому что это результат триггера из таблицы «обновить».
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;
я получаю ошибку, как описано выше: «Вы не настоящий человек»
Edit2:
Если у кого-то есть такая же проблема, решение так же просто, как глупо :)
Просто проверьте настройки Glassfish (JDBC - пулы соединений JDBC) и убедитесь, что вы не активировали:
Транзакция: нетранзакционные соединения: включено
Вот и все. После изменения этих настроек транзакция работает как положено. Так что это не было проблемой Hibernate ...
Привет!