2013-03-25 96 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