加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

使用TransactionRequiredException测试失败:加载JPA和Neo4J配置

发布时间:2020-12-15 02:09:17 所属栏目:Java 来源:网络整理
导读:我有一个JPA Web应用程序,其中包含一些针对JPA存储库的集成测试.目前还没有针对Neo4J存储库的集成测试. 现在,我已经为这个现有的JPA Web应用程序添加了一些Neo4J功能. 我现在正在使用Neo4J存储库和JPA存储库.我的实体和存储库的名称不同,并且位于不同的包中.
我有一个JPA Web应用程序,其中包含一些针对JPA存储库的集成测试.目前还没有针对Neo4J存储库的集成测试.

现在,我已经为这个现有的JPA Web应用程序添加了一些Neo4J功能.

我现在正在使用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类事务管理器与JPA事务管理器具有相同的名称(“transactionManager”),并覆盖它.

我会使用Spring提供的JPA事务管理器满足于Neo4J,但我想知道是否可行.

一些额外的信息……

我正在使用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 includen";
    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>

我尝试升级到search.maven.org上新版本的3.4.0版本,但现在构建提供了以下异常:

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

我在参考文档http://docs.spring.io/spring-data/neo4j/docs/3.4.0.RELEASE/reference/pdf/spring-data-neo4j-reference.pdf中看不到有关repositoryBaseClass的任何信息

源代码Javadoc只说:

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

这让我感到头疼,想知道什么是存储库代理,如果在我的情况下需要一个.

解决方法

我可以使用链式事务管理器在 Implementing Spring ChainedTransactionManager according to the “best efforts 1PC” pattern提供的解决方案解决问题,遵循Simon在 How do I properly set up cross-store persistence using Spring Data JPA + Neo4j?的提示

我只需要改变我的Neo4j配置.我甚至不需要触摸另一个JPA事务管理器中的任何内容.

这是我的Neo4j配置:

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

  private static Logger logger = LoggerFactory.getLogger(Neo4JRepositoryConfiguration.class);

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

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

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

  @Autowired
  LocalContainerEntityManagerFactoryBean entityManagerFactory;

  @Override
  public PlatformTransactionManager neo4jTransactionManager(
      GraphDatabaseService graphDatabaseService) {
    return new ChainedTransactionManager(
        new JpaTransactionManager(entityManagerFactory.getObject()),new JtaTransactionManagerFactoryBean(graphDatabaseService).getObject());
  }

}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读