首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Aspectj编译时基于编织的事务不能工作(来自WebService调用的JPA)

Aspectj编译时基于编织的事务不能工作(来自WebService调用的JPA)
EN

Stack Overflow用户
提问于 2012-02-03 18:01:05
回答 3查看 4K关注 0票数 2

我试图在编译时编织中使用aspectj,以支持像Spring的@Transactional和@Configurable这样的注释。我正在使用org.springframework.orm.jpa.JpaTransactionManager事务管理器,当我试图在entityManager.persist(实体)中调用entityManager.persist(实体)时,在日志中看到的如下所示:

代码语言:javascript
复制
insurance-module-0.1-SNAPSHOT 19:57:55.199 [http-bio-8084-exec-49] TRACE org.hibernate.loader.Loader - Bound [6] parameters total
insurance-module-0.1-SNAPSHOT 19:57:55.199 [http-bio-8084-exec-49] TRACE org.hibernate.loader.Loader - processing result set
insurance-module-0.1-SNAPSHOT 19:57:55.199 [http-bio-8084-exec-49] DEBUG org.hibernate.loader.Loader - result set row: 0
insurance-module-0.1-SNAPSHOT 19:57:55.199 [http-bio-8084-exec-49] TRACE o.h.t.descriptor.sql.BasicExtractor - found [1] as column [id3_]
insurance-module-0.1-SNAPSHOT 19:57:55.199 [http-bio-8084-exec-49] DEBUG org.hibernate.loader.Loader - result row: EntityKey[com.vendio.insurance.domain.db.InsuranceRate#1]
insurance-module-0.1-SNAPSHOT 19:57:55.199 [http-bio-8084-exec-49] TRACE org.hibernate.loader.Loader - done processing result set (1 rows)
insurance-module-0.1-SNAPSHOT 19:57:55.200 [http-bio-8084-exec-49] TRACE org.hibernate.loader.Loader - total objects hydrated: 0
insurance-module-0.1-SNAPSHOT 19:57:55.200 [http-bio-8084-exec-49] DEBUG o.h.e.StatefulPersistenceContext - initializing non-lazy collections
insurance-module-0.1-SNAPSHOT 19:57:55.200 [http-bio-8084-exec-49] TRACE org.hibernate.impl.SessionImpl - after transaction completion
insurance-module-0.1-SNAPSHOT 19:57:55.201 [http-bio-8084-exec-49] TRACE o.s.t.s.TransactionSynchronizationManager - Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@5ec859c1] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@337cbe84] bound to thread [http-bio-8084-exec-49]
insurance-module-0.1-SNAPSHOT 19:57:55.209 [http-bio-8084-exec-49] DEBUG org.hibernate.SQL - select sequence_next_hi_value from hibernate_sequences where sequence_name = 'registered_policy' for update
insurance-module-0.1-SNAPSHOT 19:57:55.210 [http-bio-8084-exec-49] DEBUG org.hibernate.SQL - update hibernate_sequences set sequence_next_hi_value = ? where sequence_next_hi_value = ? and sequence_name = 'registered_policy'
insurance-module-0.1-SNAPSHOT 19:57:55.218 [http-bio-8084-exec-49] TRACE o.s.t.s.TransactionSynchronizationManager - Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@5ec859c1] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@337cbe84] bound to thread [http-bio-8084-exec-49]

,所以每个表的hibernate序列都会被更新,但是我的实体没有插入到数据库中.

如果我添加entityManager.flush(),就会出现一个异常,说明“没有正在进行的事务”。

这里发生什么事情?!

我的GenericDAO类如下所示:

代码语言:javascript
复制
public class GenericDAO<T extends Persistable> { 
 @PersistenceContext 
 protected EntityManager entityManager; 

 @PersistenceUnit 
 protected EntityManagerFactory entityManagerFactory;

 @Transactional
 public void saveOrUpdate(T entity) {
     entityManager.persist(entity);
 }

}

我从与saveOrUpdate一起导出的web服务中调用WSSpringServlet方法。

P.S.:我的Maven配置也是这样的:

代码语言:javascript
复制
   <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.4</version>
        <configuration>
            <complianceLevel>1.6</complianceLevel>
        <showWeaveInfo>true</showWeaveInfo>
            <aspectLibraries>
                <aspectLibrary>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-aspects</artifactId>
                </aspectLibrary>
            </aspectLibraries>
        </configuration>
        <executions>
            <execution>
                <goals>
                    <goal>compile</goal>
                </goals>
            </execution>
        </executions>
    </plugin>

在编译时,我得到了一些看起来足够体面的东西(我的方面被应用了):

代码语言:javascript
复制
    Join point 'method-call(void javax.persistence.EntityManager.persist(java.lang.Object))'
 in Type 'com.vendio.insurance.dao.GenericDAO' (GenericDAO.java:28) 
advised by afterThrowing advice from 'org.springframework.orm.jpa.aspectj.JpaExceptionTranslatorAspect' 
(spring-aspects-3.1.0.RELEASE.jar!JpaExceptionTranslatorAspect.class:14(from JpaExceptionTranslatorAspect.aj))

我的相关Spring配置是:

代码语言:javascript
复制
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<context:component-scan base-package="com.vendio.insurance" />
<context:spring-configured/>
 <!--    <bean class="org.springframework.transaction.aspectj.AnnotationTransactionAspect" factory-method="aspectOf">
    <property name="transactionManager" ref="transactionManager"/>
</bean>-->

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

所以一切看起来都很体面,但我找不到为什么这不管用的答案.

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-03-24 23:50:43

我在以下链接中找到了我的答案:http://forum.springsource.org/showthread.php?18953-DispatcherServlet-and-ContextLoaderListener

造成这个问题的原因是,我也在使用Spring,而且我在创建时不知道两个几乎相同的Spring上下文。因此,事务在第一个上下文(接收JAX调用的上下文)中由事务管理器管理,但我调用的实体管理器由第二个上下文(使用不同的事务管理器)管理。

解决方案是隔离DispatcherServlet的小型简化上下文定义,并将其余的bean留给ContextLoaderListener管理:

代码语言:javascript
复制
<listener> 
 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 
<context-param> 
 <param-name>contextConfigLocation</param-name> 
 <param-value>/WEB-INF/spring/application-context.xml</param-value> 
</context-param>

<servlet> 
 <servlet-name>spring-mvc-dispatcher-servlet</servlet-name> 
 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>2</load-on-startup> 
 <init-param> 
 <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/servlet-context.xml</param-value> 
 </init-param> 
</servlet> 

由于我使用了基于注释的MVC (带有@Controller注释),所以我还必须缩小上下文的范围:组件扫描的基本包在"servlet“上下文中。

下面引用的链接拯救了我的日子:

DispatcherServlet将始终使用-servlet.xml加载自己的配置文件。该文件将包含控制器、ViewResolvers和LocaleResolvers等web组件,但不包含中间层组件。 然后使用ContextLoaderListener加载包含中间层和数据层组件的文件。Spring将将所有这些组件合并到一个ApplicationContext中,从而使您的中间层组件可以从web层组件中访问。>Rob Harrop首席工程师,dm服务器

票数 3
EN

Stack Overflow用户

发布于 2012-02-03 19:03:39

如果使用EntityManager,则不必处理代码中的任何hibernate问题。这正是jpa的目的。

不久前我也遇到了同样的问题。

您的EntityManager必须注入@PersistenceContext。getEntityManager()做不到。

你的注释功能必须是公开的。

票数 0
EN

Stack Overflow用户

发布于 2014-11-08 05:03:12

,所以每个表的hibernate序列都会被更新,但是我的实体没有插入到数据库中.

尽管两种相同的Spring上下文没有问题,但我正在经历相同的症状。forceAjcCompile选项解决了这个问题:

代码语言:javascript
复制
            ...
            <java.version>1.6</java.version>
            <aspectj.version>1.7.0</aspectj.version>
            ...
            <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.6</version>
            <dependencies>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjrt</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjtools</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
            </dependencies>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <outxml>true</outxml>
                <showWeaveInfo>false</showWeaveInfo>
                <verbose>false</verbose>
                <complianceLevel>${java.version}</complianceLevel>
                <forceAjcCompile>true</forceAjcCompile>
                <aspectLibraries>
                    <aspectLibrary>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-aspects</artifactId>
                    </aspectLibrary>
                </aspectLibraries>
                <source>${java.version}</source>
                <target>${java.version}</target>
                <Xlint>ignore</Xlint>
            </configuration>
        </plugin>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9133249

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档