0

私は次のような方法を持っています:

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

何か案は?継承関係あるの?

4

2 に答える 2

0

あなたのコードは非常に単純化されています。

使用される「em」は、どのクラスでも宣言されていません。

私は期待するだろう

@PersistenceContext
EntityManager em;

あなたのクラスの1つで。

両方のクラスにある場合は、エラーを説明します。この場合、同じトランザクションを共有しない 2 つの異なるエンティティ マネージャーが挿入されるためです。

これを回避するには、スーパークラスで抽象メソッド「getEm()」を使用し、子クラスでそれをオーバーライドして、そこに注入された em を提供する必要があります。

さらに、スーパークラスの @Transactional は、子クラスから呼び出されても効果がありません。これは、spring-aop-proxy を介してではなく、子から直接呼び出されるスーパーメソッド - spring がインターセプトする機会がないためです。

于 2013-09-05T21:02:40.163 に答える