I use Spring-Data Neo4j 2.2.0-RELEASE. (my following issue would be applicable to any other kind of entity mapping, why not JPA)
In my project, I have a public method annotated with @Transactional
Spring's annotation, since I want to update/save an entity inside it:
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);
}
My application-context.xml is the following:
<?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>
As we see in this configuration, aspectJ is used for transactions.
So, I tried to test another way of doing by changing my application-context.xml to use the proxy
feature instead of aspectJ
feature:
<?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>
This configuration works pretty well since @Transactional
(whose neo4jTransactionManager
parameter was of course removed) annotation is now taken in account for my service's method.
My question is, (no matter whether my project would work with simple proxy
method):
What did I miss or misconfigure in my first Spring's configuration that makes aspectJ transaction features failed?
I'm currently improving my technical skills with Spring, and read few articles about "Load-time weaving" for aspectJ. Might this be linked to my issue?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…