TransactionRequiredException Выполнение запроса обновления/удаления
Привет! Я использую hibernate JPA с spring и mongodb и запускаю свое приложение на Glassfish-4.0.
Мой класс обслуживания:
@Component
public class Test {
@PersistenceContext
EntityManager em;
EntityManagerFactory emf;
@Transactional
public String persist(Details details) {
details.getUsername();
details.getPassword();
Query query = em.createNativeQuery("db.details.find(username="+details.getUsername()+"&password="+details.getPassword());
em.getTransaction().begin();
em.persist(details);
em.getTransaction().commit();
em.flush();
em.clear();
em.close();
query.executeUpdate();
System.out.println("Sucessful!");
return "persist";
}
}
И мой spring-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="com.javapapers.spring.mvc" />
<context:annotation-config />
<mvc:annotation-driven />
<tx:annotation-driven transaction-manager="txManager" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="ogmTest"/>
</bean>
<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager">
</bean>
</beans>
Я применил некоторые изменения в коде, но они не влияют. Может кто-нибудь, пожалуйста, помогите мне разобраться в этом. Заранее спасибо.
Ответы
Ответ 1
Я не уверен, поможет ли это вашей ситуации (то есть, если она все еще существует), однако, после поиска в Интернете аналогичной проблемы.
Я создавал собственный запрос из модуля EntityManager для выполнения обновления.
Query query = entityManager.createNativeQuery(queryString);
Я получил следующую ошибку:
вызвано: javax.persistence.TransactionRequiredException: выполнение запроса на обновление/удаление
Многие решения предлагают добавить @Transactional к вашему методу. Просто это не изменило ошибку.
В некоторых решениях предлагается EntityTransaction
EntityManager для EntityTransaction
чтобы вы могли вызывать EntityTransaction
и фиксировать себя. Это выдает еще одну ошибку:
вызвано: java.lang.IllegalStateException: не разрешено создавать транзакции на совместно используемом EntityManager - вместо этого используйте транзакции Spring или EJB CMT
Затем я попробовал метод, который, по словам большинства сайтов, предназначен для использования диспетчеров управляемых сущностей приложений, а не контейнеров (как я считаю, Spring), и это было joinTransaction()
.
Работая с @Transactional
декорируя метод, а затем вызывая joinTransaction()
для объекта EntityManager непосредственно перед вызовом query.executeUpdate()
и моим собственным обновлением запросов, я работал.
Я надеюсь, что это помогает кому-то еще, испытывающему эту проблему.
Ответ 2
как форма конфигурации xml ясно, что вы собираетесь использовать транзакцию на основе spring. Убедитесь, что импорт, который вы используете для @Transactional, "org.springframework.transaction.annotation.Transactional"
в вашем случае это может быть "javax.transaction.Transactional"
приветствия
Четан Верма
Ответ 3
В моем случае у меня был неправильный @Transaction
импорт. Правильный:
org.springframework.transaction.annotation.Transactional
а не javax.transaction.Transactional
.
Ответ 4
Я также столкнулся с такой же проблемой, когда работаю с Hibernate и Spring Jpa Data Repository. Я забыл разместить @Transactional
в Spring методе репозитория данных.
Он работает для меня после аннотации с @Transactional
.
Ответ 5
Как насчет перемещения @Transactional
от метода до уровня класса?
Работал для меня в аналогичном случае, хотя я не на 100% уверен, почему.
Ответ 6
Я получил это исключение при попытке выполнить массовый запрос UPDATE в менеджере сущностей не-JTA (т.е. Локальном ресурсе) в Java SE. Я просто забыл обернуть мой код JPQL в
em.getTransaction().begin();
а также
em.getTransaction().commit();
Ответ 7
Я получил ту же ошибку.
Я просто добавил аннотацию @Transactional javax.transaction.Transactional в этом методе.
Ответ 8
Просто добавьте @Transactional на уровне метода или класса. Когда вы обновляете или удаляете записи, вам необходимо поддерживать постоянное состояние транзакции, и @Transactional
управляет этим.
и импортировать org.springframework.transaction.annotation.Transactional;
Ответ 9
Вам не нужно беспокоиться о начале и конце транзакции. Вы уже применили аннотацию @Transactional, которая внутренне открыла транзакцию, когда ваш метод запускается и заканчивается, когда заканчивается ваш метод. Поэтому требуется только сохранить ваш объект в базе данных.
@Transactional(readOnly = false, isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
public String persist(Details details){
details.getUsername();
details.getPassword();
Query query = em.createNativeQuery("db.details.find(username= "+details.getUsername()+"& password= "+details.getPassword());
em.persist(details);
System.out.println("Sucessful!");
return "persist";
}
РЕДАКТИРОВАТЬ: Проблема, похоже, связана с вашим конфигурационным файлом. Если вы используете JPA, тогда ваш файл конфигурации должен иметь конфигурацию
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory" />
<bean id="jpaAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
p:database="ORACLE" p:showSql="true" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:persistenceUnitName="YourProjectPU"
p:persistenceXmlLocation="classpath*:persistence.xml"
p:dataSource-ref="dataSource" p:jpaVendorAdapter-ref="jpaAdapter">
<property name="loadTimeWeaver">
<bean
class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
</property>
<property name="persistenceProvider" ref="interceptorPersistenceProvider" />
</bean>
Ответ 10
Мне ничего не показалось, пока я не понял, что мой метод был объявлен как public final
, а не только public
. Ошибка вызвана ключевым словом final
. При удалении его ошибка исчезла.
Ответ 11
После интеграции Spring 4 с Hibernate 5 в моем проекте и возникновения этой проблемы, я обнаружил, что могу помешать появлению ошибки, изменив способ получения сеанса от sessionFactory.openSession()
до sessionFactory.getCurrentSession()
.
правильный способ выработать эту ошибку может продолжаться с использованием того же сеанса для привязки транзакции .opensession всегда будет создавать новый сеанс, который не похож на первый, у которого выполняется транзакция. Использование getCurrentSession и добавление дополнительного свойства <property name="current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</property>
отлично работает для я.
Ответ 12
Я сталкивался с такой же исключение "TransactionRequiredException Выполнение обновления/удаления запроса", но для меня причина в том, что я создал еще один компонент в applicationContext.xml файл пружинной с именем "TransactionManager" отсылая к "org.springframework.jms.connection.JmsTransactionManage г", однако был еще один бобом с таким же названием„TransactionManager“ссылается на„org.springframework.orm.jpa.JpaTransactionManager“. Таким образом, бин JPA перезаписывается бином JMS.
После переименования имени JMS-компонента проблема решается.
Ответ 13
Я столкнулся с той же ошибкой, несмотря на добавление аннотации @Transactional на уровне класса и импорт org.springframework.transaction.annotation.Transactional.
Затем я понял, что, поскольку я использовал запрос гибернации, я импортировал javax.persistence.Query вместо импорта org.hibernate.query.Query. Поэтому добавление импорта org.hibernate.query.Query. решил проблему для меня.
Я надеюсь, что эта идея кому-то поможет.
Ответ 14
Столкнувшись с той же проблемой, я просто забыл активировать управление транзакциями с аннотацией @EnableTransactionManagement
.
Ref:
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/EnableTransactionManagement.html
Ответ 15
Сообщение об ошибке при запуске кода:
javax.persistence.TransactionRequiredException: выполнение запроса на обновление/удаление
Начните транзакцию entityManager → createNativeQuery → выполнить обновление → фиксацию транзакции entityManager, чтобы сохранить ее в своей базе данных. У меня это нормально работает с Hibernate и postgresql.
Код
entityManager.getTransaction().begin();
Query query = entityManager.createNativeQuery("UPDATE tunable_property SET tunable_property_value = :tunable_property_value WHERE tunable_property_name = :tunable_property_name");
query.setParameter("tunable_property_name", tunablePropertyEnum.eEnableJobManager.getName());
query.setParameter("tunable_property_value", tunable_property_value);
query.executeUpdate();
entityManager.getTransaction().commit();
Ответ 16
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Transactional
public int changepassword(String password, long mobile) {
// TODO Auto-generated method stub
session = factory.getCurrentSession();
Query query = session.createQuery("update User u set u.password='" + password + "' where u.mobile=" + mobile);
int result = query.executeUpdate();
return result;
}
add this code 200% it will work... might scenario is diff but write like this:)