【问题标题】:migrate hibernateTemplate to JPA 2 (executeWithNativeSession - doInHibernate)将 hibernateTemplate 迁移到 JPA 2 (executeWithNativeSession - doInHibernate)
【发布时间】:2014-11-02 08:55:54
【问题描述】:

我正在将我的代码从 hibernate 3(即使用 hibernate 模板)迁移到 JPA 2。我的项目也在使用 Spring。

当前项目使用 hibernatetempate as

hibernateTemplate.executeWithNativeSession(new HibernateCallback<Object>() {
            @Override
            public Object doInHibernate(Session session) throws SQLException {
                Query query = session.getNamedQuery("updateToProcessed");
                query.setParameter("Id", id);
                return query.executeUpdate();
            }
        });

updateToProcessed 是一个简单的更新 hql 查询。请帮助让我知道如何将其转换为 JPA(使用 entityManager)

我尝试过使用

Query query = entityManager.createNamedQuery("updateToProcessed");
        query.setParameter("Id", id);
        query.executeUpdate();

完整的方法是

@Override
    public void updateAllBatchDetails(final String id) {
            Query query = entityManager.createNamedQuery("updateToProcessed");
            query.setParameter("Id", id);
            query.executeUpdate();
    }

但我得到的错误是:

Caused by: javax.persistence.TransactionRequiredException: Executing an update/delete query
    at org.hibernate.jpa.spi.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:71)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:333)
    at com.sun.proxy.$Proxy143.executeUpdate(Unknown Source)

我已经在 applicationContext.xml 中配置了 transactionManager,比如

我期待这个答案,我已经在 applicationContext.xml 中配置了它,但我仍然收到该错误

<tx:annotation-driven transaction-manager="transactionManager"/>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
          p:entityManagerFactory-ref="entityManagerFactory"/>

但不知何故,@Transactional 正在工作,我不想使用。

这是 applicationContext.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:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <context:component-scan base-package="com.batch"/>
    <context:annotation-config/>
    <context:spring-configured/>

    <context:property-placeholder location="classpath:batch.properties"/>

    <tx:annotation-driven transaction-manager="transactionManager"/>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
          p:entityManagerFactory-ref="entityManagerFactory"/>

    <aop:aspectj-autoproxy/>

    <import resource="classpath:core/applicationContext.xml"/>
    <import resource="classpath:spring/applicationContext-resources.xml"/>
    <import resource="classpath:spring/applicationContext-batch.xml"/>


    <bean id="entityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
          p:persistenceUnitName="default"
          p:jpaVendorAdapter-ref="jpaVendorAdapter"
          p:dataSource-ref="dataSource" />

    <bean id="batchProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"
          p:location="classpath:batch.properties"/>


</beans>

【问题讨论】:

  • 该错误表明您没有正确设置事务。确保您已配置 JpaTransactionManager 并已将您希望事务性的方法标记为事务性,使用 @Transactional&lt;tx:annotation-driven /&gt; 或使用 &lt;tx:advice /&gt;&lt;aop:config /&gt; 元素。
  • 我期待这个答案,我已经在 applicationContext.xml 中配置了它,但我仍然收到该错误 但不知何故@Transactional 正在工作,我不想使用
  • 您配置它并不意味着它是正确的。从堆栈跟踪来看,它不是。我猜你有一个组件扫描和两次扫描相同的bean,导致一个代理和非代理实例。
  • 再次检查并确认组件扫描只完成一次。
  • 确保您在与&lt;tx:annotation-driven /&gt; 相同的上下文中进行扫描,否则将不会应用事务。还要确保,虽然您可能只有一次组件扫描,但配置只加载一次而不是两次。

标签: spring hibernate jpa spring-batch persistence.xml


【解决方案1】:

要执行批量更新,您应该执行以下操作:

final String updateQuery = "update Person p SET p.name = 'Other Name'";
final int update = entityManager.createQuery(updateQuery).executeUpdate();
System.out.println("updated rows " + update);

Spring 将为您处理提交。 [=


编辑:原因:javax.persistence.TransactionRequiredException

您是否配置了事务?要执行更新,您必须打开一个事务。

使用 Spring,您可以在方法中使用注解 @Transactional。

【讨论】:

  • 谢谢。我已经以这种方式尝试过: Query query = entityManager.createNamedQuery("updateToProcessed"); query.setParameter("id", Id);查询.executeUpdate();但它给了我错误:引起:javax.persistence.TransactionRequiredException:在 org.hibernate.jpa.spi.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:71) 执行更新/删除查询
  • 再次编辑问题。添加了 transactionManager 配置,但无法使用配置。
  • 你能发布使用EntityManager的方法吗?
  • 编辑了问题。方法已经在没有签名的情况下发布了,但现在完整的方法已经发布了。
  • 看看我评论里的编辑,需要用@Transactional注解
【解决方案2】:

对于这个问题,使用Tasklet 执行查询。
使用TaskletStep 配置步骤,您可以设置“事务管理器”以及“事务属性”,错误应该会消失。

【讨论】:

  • 谢谢。但是发现这样做太复杂了。我将它用作在其他条件下做出决定的决策者。
猜你喜欢
  • 2021-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-28
  • 2019-03-06
  • 1970-01-01
  • 2017-01-09
  • 1970-01-01
相关资源
最近更新 更多