2013-03-25 109 views
3

我使用Spring-数据的Neo4j 2.2.0-RELEASE。 (我以下的问题将适用于任何其他类型的实体映射,为什么不JPA)春/ @Transactional被完全忽略

在我的项目,我有@Transactional Spring的注解公开的方法,因为我想更新/保存里面的实体:

public class MeetingServices { 

    private UserRepository userRepository; 

    private MeetingRepository meetingRepository; 

    public void setUserRepository(UserRepository userRepository) { 
     this.userRepository = userRepository; 
    } 

    public void setMeetingRepository(MeetingRepository meetingRepository) { 
     this.meetingRepository = meetingRepository; 
    } 

    @Transactional("neo4jTransactionManager") 
    public void save(Meeting meeting) { 
     User creator = userRepository.getUserByEmail("[email protected]"); 
     creator.participateIn(meeting); // this line leads to a NotInTransactionException since it signals that no transaction context is associated. 
     meeting.setCreator(creator); 
    } 

我的应用程序的context.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:neo4j="http://www.springframework.org/schema/data/neo4j" 
     xmlns:tx="http://www.springframework.org/schema/tx" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/data/neo4j 
     http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> 

    <bean id="graphDatabaseService" class="org.neo4j.kernel.EmbeddedGraphDatabase"> 
     <constructor-arg value="target/neo4jgraph" /> 
    </bean> 

    <neo4j:config graphDatabaseService="graphDatabaseService" /> 

    <bean id="meetingServices" class="services.MeetingServices"> 
     <property name="userRepository"><ref bean="userRepository"/></property> 
     <property name="meetingRepository"><ref bean="meetingRepository"/></property> 
    </bean> 

    <bean id="userServices" class="services.UserServices"> 
     <property name="userRepository"><ref bean="userRepository"/></property> 
    </bean> 

    <bean id="neo4jTransactionManager" 
     class="org.springframework.transaction.jta.JtaTransactionManager"> 
     <property name="transactionManager"> 
      <bean class="org.neo4j.kernel.impl.transaction.SpringTransactionManager"> 
       <constructor-arg ref="graphDatabaseService" /> 
      </bean> 
     </property> 
     <property name="userTransaction"> 
      <bean class="org.neo4j.kernel.impl.transaction.UserTransactionImpl"> 
       <constructor-arg ref="graphDatabaseService" /> 
      </bean> 
     </property> 
    </bean> 

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

    <!-- auto-generated repositories for Neo4j storage --> 
    <neo4j:repositories base-package="repositories"/> 

    <context:spring-configured/> 

    <context:annotation-config/> 

</beans> 

正如我们在这个配置中看到,AspectJ是用于交易。

所以,我试图测试通过改变我的应用程序的context.xml做的另一种方式,而不是使用aspectJ特征proxy功能:

<?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:neo4j="http://www.springframework.org/schema/data/neo4j" 
     xmlns:tx="http://www.springframework.org/schema/tx" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/data/neo4j 
     http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> 

    <bean id="graphDatabaseService" class="org.neo4j.kernel.EmbeddedGraphDatabase"> 
     <constructor-arg value="target/neo4jgraph" /> 
    </bean> 

    <neo4j:config graphDatabaseService="graphDatabaseService" /> 

    <bean id="meetingServices" class="services.MeetingServices"> 
     <property name="userRepository"><ref bean="userRepository"/></property> 
     <property name="meetingRepository"><ref bean="meetingRepository"/></property> 
    </bean> 

    <bean id="userServices" class="services.UserServices"> 
     <property name="userRepository"><ref bean="userRepository"/></property> 
    </bean> 

    <tx:annotation-driven mode="proxy" /> 


    <neo4j:repositories base-package="repositories"/> 

    <context:spring-configured/> 

    <context:annotation-config/> 

</beans> 

这种配置工作得很好,因为@Transactional(其neo4jTransactionManager参数当然被删除了)注释现在被考虑在我的服务的方法中。

我的问题是,(不管我的项目是否会用简单的方法proxy工作):

我是怎么在我的第一个春天的配置,使AspectJ的交易功能无法错过或错误配置?

目前我提高我的技术技能与Spring,并了解“装载时织”为AspectJ的几篇文章。可能这与我的问题有关?

回答

3

尝试增加<context:load-time-weaver/>启用负载时织入和弹簧aspects.jar中添加到类路径。

更多信息,请参见http://static.springsource.org/spring/docs/current/spring-framework-reference/html/aop.html#aop-aj-ltw-spring

编辑

对于一般的Java应用程序,即在Web或应用程序容器没有运行,则需要启用通过javaagent选择了Java instrumentatioin:

java -javaagent:path/to/spring-instrument.jar your.Main 

如果你想编织自己的方面,你需要提供一个META-INF/aop.xml文件与文件方面的声明。 (不需要春天的方面,它已经在spring-aspect.jar中提供)。

最后,您可以使用编译时织代替,using the maven aspectj plugin,例如:

<plugin> 
      <groupId>org.codehaus.mojo</groupId> 
      <artifactId>aspectj-maven-plugin</artifactId> 
      <configuration> 
       <complianceLevel>1.6</complianceLevel> 
       <aspectLibraries> 
        <aspectLibrary> 
         <groupId>org.springframework</groupId> 
         <artifactId>spring-aspects</artifactId> 
        </aspectLibrary> 
       </aspectLibraries> 
      </configuration> 
      <executions> 
       <execution> 
        <goals> 
         <goal>compile</goal> 
        </goals> 
       </execution> 
      </executions> 
     </plugin> 
+0

我已经尝试过这一点,但我结束了这一点:'产生的原因:java.lang.IllegalStateException:类加载器[sun.misc .Launcher $ AppClassLoader]不提供'addTransformer(ClassFileTransformer)'方法。指定自定义的LoadTimeWeaver或使用Spring的代理启动Java虚拟机:-javaagent:org.springframework.instrument.jar' – Mik378 2013-03-25 14:26:36

+0

添加选项为主营发射语句:java -javaagent:C:/项目/富/ lib中/全球/春天-instrument.jar foo.Main参考实例 – 2013-03-25 14:43:27

+0

我只是你的建议:)但导致这个:'的java.lang:所致。VerifyError :(类:services/MeetingServices $$ EnhancerByCGLIB $$ 73b088b5,方法:setMeetingRepository签名:(Lrepositories/MeetingRepository;)V)不一致的堆栈高度1!= 0'。听起来像一个已知的错误(http://stackoverflow.com/questions/9027009/aspectj-verifyerror)。我使用Java 7 ..我刚刚尝试了这个建议:将'-XX:-UseSplitVerifier'添加到虚拟机选项,但仍然出现错误。 – Mik378 2013-03-25 15:07:50