0

我在删除实体时遇到了一个奇怪的问题,我认为这是因为错误的弹簧配置/错误,我无法准确指出它是什么。我可以读取,但每当我尝试删除时,我都会收到错误..

以下是我的设置.. 我有一个基于 spring 的事务管理委托给 jboss 的 jta。以下是我的弹簧配置

<context:annotation-config />
<context:component-scan base-package="com.blah.blah">
    <context:exclude-filter type="regex"
        expression="com.blah.blah.batch.*" />
</context:component-scan>

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="pmabDataSource" />
    <property name="persistenceUnitName" value="MABPersistenceEl" />
    <property name="jpaDialect" ref="eclipseLinkDialect" />
    <property name="persistenceXmlLocation" value="classpath:META-INF/persistence-eclipse.xml" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
            <property name="showSql" value="true" />
            <property name="generateDdl" value="false" />
        </bean>
    </property>

    <property name="jpaPropertyMap">
        <map>
            <entry key="eclipselink.target-server" value="JBOSS" />
            <entry key="eclipselink.target-database" value="Oracle" />
            <entry key="eclipselink.persistence-context.flush-mode" value="AUTO" />
            <entry key="eclipselink.jdbc.native-sql" value="false" />
            <entry key="eclipselink.weaving" value="false" />
            <entry key="eclipselink.logging.level" value="FINEST" />
            <entry key="eclipselink.logging.parameters" value="true" />
            <entry key="eclipselink.logging.exceptions" value="true" />
            <entry key="eclipselink.orm.throw.exceptions" value="true" />
        </map>
    </property>
</bean>

<bean id="eclipseLinkDialect" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" />

<tx:jta-transaction-manager />

持久化文件如下

<persistence version="1.0"
    xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">

    <persistence-unit name="MABPersistenceEl"
        transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>pmabDataSource</jta-data-source>
        <!-- ,,,, other things ommited for brevity/> -->
    </persistence-unit>
</persistence>

我的 basedao 像这样被注入 EntityManager

@PersistenceContext(unitName = "MABPersistenceEl")
protected EntityManager entityManager ;

在我派生的 dao 的某个地方,我有以下内容

UserRole newRole=entityManager.find(UserRole.class,urole.getId()) ;
entityManager.remove(newRole);

我得到以下 09:53:00,386 DEBUG Creating new EntityManager for shared EntityManager invocation 09:53:00,413 DEBUG [EntityManagerFactoryUtils]:328 Closing JPA EntityManager 09:53:04,119 DEBUGSharedEntityManagerCreator$SharedEntityManagerInvocationHandler:231 Creating new EntityManager for shared EntityManager 调用 09: 53:04,146 调试 [EntityManagerFactoryUtils]:328 关闭 JPA EntityManager 09:53:05,760 调试为共享 EntityManager 调用创建新 EntityManager 09:53:05,781 调试 [EntityManagerFactoryUtils]:328 关闭 JPA EntityManager

那就是 spring EntityManager 创建者在每次访问它时都会创建一个 entityManager,而不是为事务返回一个。这导致 EL 库发疯。java.lang.IllegalArgumentException: Entity must be managed to call remove: UserRole@419d,尝试合并分离的并再次尝试删除。在 org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.performRemove(UnitOfWorkImpl.java:3559) 在 org.eclipse.persistence.internal.jpa.EntityManagerImpl.remove(EntityManagerImpl.java:518)

如何配置 springs 实体管理器创建者以将实体管理器还给我进行事务处理,而不是每次都创建一个?

4

1 回答 1

0

我确实进行了以下更改,现在它可以工作了..代码:

<!-- the transactional advice (what 'happens'; see the <aop:advisor/> bean below) -->
<tx:advice id="pmabTxAdvice" transaction-manager="transactionManager">
    <!-- the transactional semantics... -->
    <tx:attributes>
        <!-- all methods starting with 'get' are read-only -->
        <!-- other methods use the default transaction settings (see below) -->
      <tx:method name="*" propagation="REQUIRED" read-only="false"/>
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:pointcut id="serviceOperation"
        expression="execution(* com.foo.foobar.abc.*.*.*(..))" />
    <aop:advisor advice-ref="pmabTxAdvice" pointcut-ref="serviceOperation" />
</aop:config>

希望这可以帮助某人

于 2012-07-27T21:32:18.473 回答