Я использую Spring-Data Neo4j 2.2.0-RELEASE. (моя следующая проблема будет применима к любому другому типу сопоставления сущностей, почему бы не JPA)
В моем проекте у меня есть общедоступный метод, аннотированный аннотацией @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("test@test.com");
creator.participateIn(meeting); // this line leads to a NotInTransactionException since it signals that no transaction context is associated.
meeting.setCreator(creator);
}
Мой application-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>
Как мы видим в этой конфигурации, аспектJ используется для транзакций.
Итак, я попытался протестировать другой способ сделать это, изменив свой application-context.xml на использование функции proxy
вместо функции aspectJ
:
<?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
):
Что я пропустил или неправильно сконфигурировал в своей первой конфигурации Spring, из-за чего функции транзакции аспектаJ не работают?
В настоящее время я улучшаю свои технические навыки с помощью Spring и прочитал несколько статей о «ткачестве времени загрузки» для аспектаJ. Может быть, это связано с моей проблемой?
1 ответ
Попробуйте добавить <context:load-time-weaver/>
, чтобы включить изменение времени загрузки, и добавьте файл spring-sizes.jar в путь к классам.
См. http: //static.springsource.org/spring/docs/current/spring-framework-reference/html/aop.html#aop-aj-ltw-spring для получения дополнительной информации.
Изменить
Для общих приложений Java, то есть не работающих в веб-контейнере или контейнере приложения, вам необходимо включить инструмент Java с помощью параметра javaagent:
java -javaagent:path/to/spring-instrument.jar your.Main
Если вы хотите создать свои собственные аспекты, вам необходимо предоставить файл META-INF / aop.xml с объявлениями аспектов. (Не требуется только для аспектов Spring, это уже предусмотрено в spring-aspect.jar).
Наконец, вместо этого вы можете использовать переплетение времени компиляции, используя плагин maven aspectj, например:
<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>
Похожие вопросы
Связанные вопросы
Новые вопросы
java
Java — это высокоуровневый объектно-ориентированный язык программирования. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег часто используется вместе с другими тегами для библиотек и/или фреймворков, используемых разработчиками Java.
Caused by: java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
java.lang.VerifyError: (class: services/MeetingServices$$EnhancerByCGLIB$$73b088b5, method: setMeetingRepository signature: (Lrepositories/MeetingRepository;)V) Inconsistent stack height 1 != 0
. Похоже на известную ошибку (stackoverflow.com/questions/9027009/aspectj-verifyerror). Я использую Java 7. Я только что попробовал совет: добавить-XX:-UseSplitVerifier
в параметры виртуальной машины, но ошибка все равно возникает.