我的方法如下:
package com.abc.pkg.service.db.impl;
public class OperationServiceImpl extends BaseService implements OperationService {
@Transactional
@Override
public String update(Operation operation,User user) {
BigDecimal count=(BigDecimal)em.createNativeQuery("select count(*) from RBMCORE.T_RBM_OPSCREENS_OPERATIONS where s_name= ? and id!= ?").setParameter(1, operation.getName()).setParameter(2, operation.getId()).getSingleResult();
if(count.intValue()>0)
return "This operation name is used by another operation. Please change it";
super.removeOpAppRelation(operation.getId(), -1);
Operation oldOperation=operationRepository.save(operation);
List<Operation> operations=new ArrayList<Operation>();
operations.add(operation);
}
}
和super.insertOpAppRelation方法的内容是:
package com.abc.pkg.service.db.impl;
public abstract class BaseService {
@PersistenceContext
protected EntityManager em;
@Transactional
protected void removeOpAppRelation(int opId,int appId){
String sql="delete table a where 1=1";
if(opId>0)
sql+=" and op_id="+opId;
if(appId>0)
sql+=" and app_id="+appId;
em.createNativeQuery(sql).executeUpdate();
}
}
触发removeOpAppRelation方法,抛出此异常:
javax.persistence.TransactionRequiredException:执行 更新/删除查询
在我的appcontext.xml中我有这些:
<tx:annotation-driven transaction-manager="transactionManager"/>
<context:component-scan base-package="com.abc.pck"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="rbmDataSource"/>
<property name="packagesToScan" value="com.ttech.rbm.model"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">none</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
作为交易经理,我正在使用:
org.springframework.orm.jpa.JpaTransactionManager
有什么想法吗?它与继承有关吗?
答案 0 :(得分:0)
您的代码非常简化。
使用的“em”未在任何类中声明。
我希望有一个
@PersistenceContext
EntityManager em;
在你的一个课程中。
如果它在两个类中都会解释您的错误,因为在这种情况下,将注入两个不同的实体管理器,这些实体管理器不会共享同一个事务。
为了避免这种情况,你应该在你的超类中使用抽象方法“getEm()”并在你的子类中覆盖它,提供注入那里的em。
此外,当从子类调用时,超类上的@Transactional将不起作用,因为直接从子类调用的超级方法而不是通过spring-aop-proxy - spring没有机会拦截。
答案 1 :(得分:0)
找到它。我传递给事务管理器的实体管理器不是AOP安全的。因此,它在使用它执行查询时不会启动事务。我打开并管理自己的交易,问题解决了。感谢您的回复