Тесты не выполняются с TransactionRequiredException: ни одна транзакция не выполняется, исключение происходит при загрузке конфигураций JPA и Neo4J

У меня есть веб-приложение JPA с некоторыми интеграционными тестами для репозиториев JPA. Интеграционных тестов для репозиториев Neo4J пока нет.

Теперь я добавил некоторые функциональные возможности Neo4J в это существующее веб-приложение JPA.

Я сейчас использую репозитории Neo4J, а также репозитории JPA. Мои сущности и репозитории имеют разные имена и находятся в разных пакетах.

Все мои тесты расширяют следующий класс:

@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { ApplicationConfiguration.class, WebSecurityTestConfiguration.class, WebConfiguration.class })
@Transactional
public abstract class AbstractControllerTest {
...
}

Тесты работают нормально, когда в конфигурации приложения нет

Neo4J configuration:
@Configuration
@ComponentScan(basePackages = { "it.robot.rest.config" })
@Import({ DatabaseConfiguration.class, Log4jWeb.class })
public class ApplicationConfiguration {
}

Но они добавляют ошибку при добавлении конфигурации Neo4J:

@Configuration
@ComponentScan(basePackages = { "it.robot.rest.config" })
@Import({ DatabaseConfiguration.class, Neo4JRepositoryConfiguration.class, Log4jWeb.class })
public class ApplicationConfiguration {
}

Исключение составляет:

javax.persistence.TransactionRequiredException: no transaction is in progress

Вот конфигурация Neo4J (я попробовал оба класса Neo4jConfiguration и CrossStoreNeo4jConfiguration, и я получил то же исключение):

@Configuration
@EnableNeo4jRepositories(basePackages = { "it.robot.data.neo4j.repository" } )
@EnableTransactionManagement
@ComponentScan(basePackages = { "it.robot.data.neo4j.service" })
public class Neo4JRepositoryConfiguration extends Neo4jConfiguration {

  public static final String URL = "http://localhost:7474/db/data/";
  public static final String LOGIN = "neo4j";
  public static final String PASSWORD = "mypassword";

  Neo4JRepositoryConfiguration() {
    setBasePackage("it.robot.data.neo4j.domain"); 
  }

  @Bean
  GraphDatabaseService graphDatabaseService() { 
    return new SpringCypherRestGraphDatabase(URL, LOGIN, PASSWORD);
  }

}

Вот конфигурация JPA:

@Configuration
@Import({ JpaService.class, Log4j.class })
@EnableTransactionManagement
@ComponentScan(basePackages = { "it.robot.data.config" })
@EnableJpaRepositories(basePackages = { "it.robot.data.jpa" }, repositoryFactoryBeanClass  = it.robot.data.jpa.repository.GenericRepositoryFactoryBean.class)
public class DatabaseConfiguration {
...
}

Похоже, что менеджер транзакций класса Neo4jConfiguration имеет то же имя ("actionManager "), что и менеджер транзакций JPA, и переопределяет его.

Я бы удовлетворился Neo4J с помощью диспетчера транзакций JPA, предоставленного Spring, но мне интересно, возможно ли это.

Некоторая дополнительная информация ...

Я использую spring-data-neo4j и spring-data-neo4j-rest версию 3.3.2.RELEASE

Я использую серверную базу данных Neo4J, а не встроенную, и, конечно, сервер Neo4J запущен.

Я отключил аутентификацию в базе данных, так как она стояла у меня на пути, и мой запрос curl не обновил пароль:

curl -H "Accept:application/json" 
 -H "Content-Type: application/json" 
 "http://localhost:7474/user/neo4j/password" 
 -X POST -d "{ \"password\" : \"myownpassword\" }"

Кажется, единственный пользователь, которого я знаю, не слишком громкий:

stephane@stephane-ThinkPad-X301:~> curl -H "Accept:application/json" -H "Content-Type: application/json" "http://localhost:7474/user/neo4j"
stephane@stephane-ThinkPad-X301:~> 
stephane@stephane-ThinkPad-X301:~>

Я не создал никакой «схемы / структуры» на графике и не уверен, что мне следует это делать.

Neo4J лица:

@NodeEntity
@SequenceGenerator(name = "id_generator", sequenceName = "sq_id_part")
public class Neo4JPart extends BaseEntity {

  @Column(nullable = false)
  private String name;
  @Column(nullable = false, unique = true)
  private String serialNumber;
  private Integer weight;
  @ManyToOne
  @JoinColumn(name = "manufacturer_id", nullable = false)
  private Neo4JManufacturer manufacturer;
  @Fetch
  @RelatedTo(type = "part", direction = Direction.BOTH)
  public Set<Neo4JPart> parts;

  public Neo4JPart() {
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getSerialNumber() {
    return serialNumber;
  }

  public void setSerialNumber(String serialNumber) {
    this.serialNumber = serialNumber;
  }

  public Integer getWeight() {
    return weight;
  }

  public void setWeight(Integer weight) {
    this.weight = weight;
  }

  public Neo4JManufacturer getManufacturer() {
    return manufacturer;
  }

  public void setManufacturer(Neo4JManufacturer manufacturer) {
    this.manufacturer = manufacturer;
  }

  public Set<Neo4JPart> getParts() {
    return parts;
  }

  public void setParts(Set<Neo4JPart> parts) {
    this.parts = parts;
  }

  public String toString() {
    String results = name + "'s compatible parts include\n";
    if (parts != null) {
      for (Neo4JPart part : parts) {
        results += "\t- " + part.name + "\n";
      }
    }
    return results;
  }

}

@MappedSuperclass
public class BaseEntity {

  @GraphId
  @GeneratedValue(strategy = GenerationType.AUTO, generator = "id_generator")
  @Column(name = "id")
  private Long id;

  @Version
  @Column(nullable = false)
  private int version;

  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public int getVersion() {
    return this.version;
  }

  public void setVersion(int version) {
    this.version = version;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }

    if (this.id == null || obj == null || !(this.getClass().equals(obj.getClass()))) {
      return false;
    }

    BaseEntity that = (BaseEntity) obj;

    return this.id.equals(that.getId());
  }

  @Override
  public int hashCode() {
    return id == null ? 0 : id.hashCode();
  }

}

И репозитории Neo4J:

public interface Neo4JPartRepository extends GraphRepository<Neo4JPart> {

  public Neo4JPart findByName(String name);

  public Neo4JPart findBySerialNumber(String serialNumber);

  public Page<Neo4JPart> findByManufacturer(@Param("manufacturer") Neo4JManufacturer manufacturer, Pageable page);

  public List<Neo4JPart> findByManufacturer(@Param("manufacturer") Neo4JManufacturer manufacturer);

  public Page<Neo4JPart> findByPartsName(String name, Pageable page);

}

public interface Neo4JManufacturerRepository extends GraphRepository<Neo4JManufacturer> {

  Neo4JManufacturer findByName(String name);

}

Зависимости Maven:

  <org.springframework.version>4.1.2.RELEASE</org.springframework.version>
  <hibernate.version>4.3.6.Final</hibernate.version>

  <dependencies>
    <dependency>
      <groupId>com.thalasoft</groupId>
      <artifactId>toolbox</artifactId>
      <version>0.0.1-SNAPSHOT</version>
    </dependency>
    <dependency>
      <groupId>com.mchange</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.2.1</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.34</version>
    </dependency>
    <dependency> 
      <groupId>com.oracle</groupId> 
      <artifactId>ojdbc6</artifactId> 
      <version>11.2.0.3</version> 
    </dependency>
    <dependency>
      <groupId>com.h2database</groupId>
      <artifactId>h2</artifactId>
      <version>1.3.172</version>
    </dependency>
    <dependency>
      <groupId>org.hsqldb</groupId>
      <artifactId>hsqldb</artifactId>
      <version>2.3.2</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>${hibernate.version}</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
      <version>${hibernate.version}</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate.javax.persistence</groupId>
      <artifactId>hibernate-jpa-2.1-api</artifactId>
      <version>1.0.0.Final</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-jpa</artifactId>
      <version>1.6.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>com.mysema.querydsl</groupId>
      <artifactId>querydsl-core</artifactId>
      <version>3.5.0</version>
    </dependency>
    <dependency>
      <groupId>com.mysema.querydsl</groupId>
      <artifactId>querydsl-apt</artifactId>
      <version>3.5.0</version>
    </dependency>
    <dependency>
      <groupId>com.mysema.querydsl</groupId>
      <artifactId>querydsl-jpa</artifactId>
      <version>3.5.0</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-commons</artifactId>
      <version>1.10.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>javax.validation</groupId>
      <artifactId>validation-api</artifactId>
      <version>1.1.0.Final</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.6.4</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.6.4</version>
    </dependency>
    <dependency>
      <groupId>org.lazyluke</groupId>
      <artifactId>log4jdbc-remix</artifactId>
      <version>0.2.7</version>
    </dependency>
    <dependency>
      <groupId>javax.mail</groupId>
      <artifactId>mail</artifactId>
      <version>1.4</version>
    </dependency>
    <dependency>
      <groupId>joda-time</groupId>
      <artifactId>joda-time</artifactId>
      <version>2.5</version>
    </dependency>
    <dependency>
      <groupId>org.jadira.usertype</groupId>
      <artifactId>usertype.jodatime</artifactId>
      <version>2.0.1</version>
    </dependency>
    <dependency>
      <groupId>javax.transaction</groupId>
      <artifactId>jta</artifactId>
      <version>1.1</version>
    </dependency>
    <dependency>
      <groupId>org.jasypt</groupId>
      <artifactId>jasypt</artifactId>
      <version>1.7</version>
    </dependency>
    <dependency>
      <groupId>org.assertj</groupId>
      <artifactId>assertj-core</artifactId>
      <version>1.6.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${org.springframework.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-oxm</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-neo4j</artifactId>
      <version>3.3.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-neo4j-rest</artifactId>
      <version>3.3.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-neo4j-cross-store</artifactId>
      <version>3.3.2.RELEASE</version>
    </dependency>
  </dependencies>

Я попытался обновить версию 3.4.0 новой версии, доступной на search.maven.org, но сборка теперь дает следующее исключение:

AnnotationFormatError: Invalid default: public abstract java.lang.Class org.springframework.data.neo4j.config.EnableNeo4jRepositories.repositoryBaseClass()

Я ничего не видел об этом repositoryBaseClass в справочной документацииhttp://docs.spring.io/spring-data/neo4j/docs/3.4.0.RELEASE/reference/pdf/spring-data-neo4j-reference.pdf

Исходный код Javadoc только говорит:

Configure the repository base class to be used to create repository proxies for this particular configuration.

И это заставило меня почесать голову, размышляя о том, что такое прокси-сервер хранилища и нужен ли он в моем случае.

Ответы на вопрос(1)

Ваш ответ на вопрос