Spring数据Neo4j:没有为字段

时间:2015-09-08 10:50:20

标签: java neo4j spring-data-neo4j graphaware

注入的转换器在我的测试类中无法识别,即使我在日志文件条目中清楚地看到转换器已成功注入。 注意:我正在使用一个非常规数据库以及 GraphUnit 来进行Spring数据存储库单元测试。

TestContextConfiguration

@Configuration
@ComponentScan(basePackages = "com.example.analytics",
    excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION, value = Configuration.class),
        @ComponentScan.Filter(type = FilterType.REGEX, pattern = { "com.example.analytics.config.DatabaseConnectionProperties" })
    })
@EnableNeo4jRepositories("com.example.analytics.repository")
@EnableTransactionManagement(mode = AdviceMode.PROXY)
@EnableAutoConfiguration(exclude = { MainConfiguration.class, DatabaseConnectionConfiguration.class })
public class TestContextConfiguration extends Neo4jConfiguration {

  private static final Logger LOG = LoggerFactory.getLogger(TestContextConfiguration.class);

  @Autowired
  private StringToLocalDateTimeConverter stringToLocalDateTimeConverter;
  @Autowired
  private LocalDateTimeToStringConverter localDateTimeToStringConverter;

  public TestContextConfiguration() {
    setBasePackage("com.example.analytics.model");
  }

  @Bean(name = "graphDatabaseService", destroyMethod = "shutdown")
  public GraphDatabaseService getGraphDatabaseService() {
    LOG.debug("Returning an impermanent database for test context.");
    return new TestGraphDatabaseFactory().newImpermanentDatabaseBuilder()
        .setConfig(GraphDatabaseSettings.nodestore_mapped_memory_size, "10M")
        .setConfig(GraphDatabaseSettings.string_block_size, "60")
        .setConfig(GraphDatabaseSettings.array_block_size, "300")
        .newGraphDatabase();
  }

  @Bean
  @DependsOn("graphDatabaseService")
  public Neo4jTemplate neo4jTemplate() {
    return new Neo4jTemplate(getGraphDatabaseService());
  }

  public TypeRepresentationStrategy<Relationship> relationshipTypeRepresentationStrategy() throws Exception {
    return new NoopRelationshipTypeRepresentationStrategy();
  }


  @Bean
  @DependsOn({ "stringToLocalDateTimeConverter", "localDateTimeToStringConverter" })
  protected ConversionService neo4jConversionService() throws Exception {
    LOG.debug("Adding local date time to string and vice versa converters to TEST Context ...");
    ConversionService conversionService = super.neo4jConversionService();
    ConverterRegistry registry = (ConverterRegistry) conversionService;

    if(stringToLocalDateTimeConverter == null )
      LOG.warn("stringToLocalDateTimeConverter was NOT injected!");
    if(localDateTimeToStringConverter == null )
      LOG.warn("localDateTimeToStringConverter was NOT injected!");

    registry.addConverter(stringToLocalDateTimeConverter);
    registry.addConverter(localDateTimeToStringConverter);
    LOG.debug("Addition of Converter from LocalDateTime to String and vice-versa to TEST context has been completed!");

    return conversionService;
  }

}

LocalDateTimeToStringConverter

@Component
public class LocalDateTimeToStringConverter implements Converter<LocalDateTime, String> {

    private static final Logger LOG = LoggerFactory.getLogger(LocalDateTimeToStringConverter.class);

    @Value("${neo4j.dateTime.format:yyyy-MM-dd HH:mm:ss}")
    private String dateTimeFormat;

    @Override
    public String convert(@NonNull final LocalDateTime source) {
        LOG.debug("Converting LocalDateTime into String using the format: {}", dateTimeFormat);
        return String.valueOf(source.format(DateTimeFormatter.ofPattern(dateTimeFormat)));
    }

}

StringToLocalDateTimeConverter

@Component
public class StringToLocalDateTimeConverter implements Converter<String, LocalDateTime> {

    private static final Logger LOG = LoggerFactory.getLogger(StringToLocalDateTimeConverter.class);

    @Value("${neo4j.dateTime.format:yyyy-MM-dd HH:mm:ss}")
    private String dateTimeFormat;

    /**
     * Convert the source of type S to target type T.
     *
     * @param source the source object to convert, which must be an instance of S (never {@code null})
     * @return the converted object, which must be an instance of T (potentially {@code null})
     * @throws IllegalArgumentException if the source could not be converted to the desired target type
     */
    @Override
    public LocalDateTime convert(@NonNull final String source) {
        return LocalDateTime.parse(source, DateTimeFormatter.ofPattern(dateTimeFormat));
    }

    @PostConstruct
    public void uponConstruction(){
        LOG.debug("Construction of the class {} has been completed!", this.getClass().getName());
        LOG.debug("Date time format has been initialised to {} ", dateTimeFormat);
    }
}

抽象测试类

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestContextConfiguration.class)
@TestExecutionListeners(inheritListeners = false, listeners = { DataSourceDependencyInjectionTestExecutionListener.class })
public abstract class AbstractRepositoryTest<T extends DatabasePopulator> {

  public static final String RESET_DATABASE_CYPHER = "MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE r, n";
  private static final Logger LOG = LoggerFactory.getLogger(AbstractRepositoryTest.class);
  public static final Integer DEFAULT_PAGE_NUMBER = 0;
  public static final Integer DEFAULT_PAGE_SIZE = 20;

  protected static GraphDatabaseService graphDatabaseService;

  protected static ExecutionEngine executionEngine;

  protected T databasePopulator;

  public AbstractRepositoryTest() {
    this.databasePopulator = assignDatabasePopulator();
  }

  @BeforeClass
  public static void initialiseEmbeddedDatabase() {
    LOG.debug("Initialising embedded temporary graph database for executing unit tests ...");
    executionEngine = new ExecutionEngine(graphDatabaseService);
  }

  @AfterClass
  public static void shutdownEmbeddedDatabase() {
    LOG.debug("Shutting down embedded temporary graph database ...");
    graphDatabaseService.shutdown();
  }

  @Autowired
  public void setGraphDatabaseService(final GraphDatabaseService graphDatabaseService) {
    LOG.debug("Injecting embedded graph database instance ...");
    AbstractRepositoryTest.graphDatabaseService = graphDatabaseService;
  }

  public abstract T assignDatabasePopulator();

  @Before
  public void setUpTestData() {
    databasePopulator.populate(graphDatabaseService);
    LOG.debug("Temporary database has been successfully populated with test data-set!");

  }

  @After
  public void tearDown() {
    LOG.debug("Emptying the temporary database used for unit test ...");
    if (executionEngine != null) {
      executionEngine.execute(RESET_DATABASE_CYPHER);
      LOG.debug("Temporary database has been emptied!");
    }
  }

  protected Pageable getDefaultPageable() {
    BiFunction<Integer, Integer, Pageable> biFunction = PageRequest::new;
    return biFunction.apply(DEFAULT_PAGE_NUMBER, DEFAULT_PAGE_SIZE);
  }

}

实际测试类

public class PersonRepositoryTest extends AbstractRepositoryTest<CypherFilesPopulator> {

  public static final String CQL_DATASET_FILE = "src/test/resources/person-repository-dataset.cql";

  private static final Logger LOG = LoggerFactory.getLogger(PersonRepositoryTest.class);

  @Autowired
  private PersonRepository personRepository;

  @Test
  public void should_find_person_with_multiple_accounts() {
    final List<Person> persons = personRepository.findOnesWithSeveralAccounts(getDefaultPageable()).getContent();
    assertThat(persons, hasSize(1));

    Person expectedResult = new PersonBuilder()
        .setTitle("Prof.").setFirstName("Helen").setLastName("Olson")
        .setDateOfBirth(LocalDateTime.of(1989, 10, 19, 6, 41, 24))
        .createPerson();

    assertThat(persons, hasItem(expectedResult));
  }



  @Override
  public CypherFilesPopulator assignDatabasePopulator() {

    return new CypherFilesPopulator() {
      private final Logger LOGGER = LoggerFactory.getLogger(CypherFilesPopulator.class);

      @Override
      protected String[] files() throws IOException {
        LOGGER.debug("Initialising cypher files populator ....");
        return new String[]{ CQL_DATASET_FILE };
      }
    };
  }


}

记录文件条目

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.2.4.RELEASE)

2015-09-08 12:15:21,596  INFO nalytics.repository.PersonRepositoryTest:  47 - Starting PersonRepositoryTest on Viswanaths-MacBook-Pro.local with PID 1175 (/Users/viswanathj/projects/myproject/xyz-cleanup-utility/target/test-classes started by viswanathj in /Users/viswanathj/projects/myproject/xyz-cleanup-utility)
2015-09-08 12:15:21,597 DEBUG nalytics.repository.PersonRepositoryTest:  50 - Running with Spring Boot v1.2.4.RELEASE, Spring v4.1.6.RELEASE
2015-09-08 12:15:21,804  INFO ation.AnnotationConfigApplicationContext: 510 - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@63070bab: startup date [Tue Sep 08 12:15:21 CEST 2015]; root of context hierarchy
2015-09-08 12:15:22,587  INFO ion.AutowiredAnnotationBeanPostProcessor: 153 - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2015-09-08 12:15:22,795 DEBUG nalytics.config.TestContextConfiguration:  53 - Returning an impermanent database for test context.
2015-09-08 12:15:23,407 DEBUG converter.StringToLocalDateTimeConverter:  38 - Construction of the class com.example.analytics.converter.StringToLocalDateTimeConverter has been completed!
2015-09-08 12:15:23,408 DEBUG converter.StringToLocalDateTimeConverter:  39 - Date time format has been initialised to yyyy-MM-dd HH:mm:ss 
2015-09-08 12:15:23,414 DEBUG n.analytics.report.client.InfogramClient:  43 - Access to Infogr.am REST API service is set-up using your Infogr.am API account ...
2015-09-08 12:15:23,414 DEBUG n.analytics.report.client.InfogramClient:  44 - Henceforth, each request to the Infogr.am REST API service will be signed along with 'api_key' parameter
2015-09-08 12:15:25,007 DEBUG nalytics.config.TestContextConfiguration:  75 - Adding local date time to string and vice versa converters to conversion service to TEST Context ...
2015-09-08 12:15:25,008 DEBUG nalytics.config.TestContextConfiguration:  86 - Addition of Converter from LocalDateTime to String and vice-versa to TEST context has been completed!
2015-09-08 12:15:25,029  INFO rk.transaction.jta.JtaTransactionManager: 490 - Using JTA UserTransaction: org.neo4j.kernel.impl.transaction.UserTransactionImpl@4a9869a8
2015-09-08 12:15:25,030  INFO rk.transaction.jta.JtaTransactionManager: 501 - Using JTA TransactionManager: org.neo4j.kernel.impl.transaction.SpringTransactionManager@75e0a54c
2015-09-08 12:15:25,122  INFO roperties$SimpleAuthenticationProperties: 403 - 

Using default password for shell access: <password was here>


2015-09-08 12:15:25,153  INFO .CrshAutoConfiguration$CrshBootstrapBean: 125 - Configuring property ssh.port=2000 from properties
2015-09-08 12:15:25,154  INFO .CrshAutoConfiguration$CrshBootstrapBean: 125 - Configuring property ssh.auth_timeout=600000 from properties
2015-09-08 12:15:25,154  INFO .CrshAutoConfiguration$CrshBootstrapBean: 125 - Configuring property ssh.idle_timeout=600000 from properties
2015-09-08 12:15:25,154  INFO .CrshAutoConfiguration$CrshBootstrapBean: 125 - Configuring property ssh.default_encoding=UTF-8 from properties
2015-09-08 12:15:25,155  INFO .CrshAutoConfiguration$CrshBootstrapBean: 125 - Configuring property auth=simple from properties
2015-09-08 12:15:25,155  INFO .CrshAutoConfiguration$CrshBootstrapBean: 125 - Configuring property auth.simple.username=user from properties
2015-09-08 12:15:25,155  INFO .CrshAutoConfiguration$CrshBootstrapBean: 125 - Configuring property auth.simple.password=<password was here> from properties
2015-09-08 12:15:26,255  INFO nalytics.repository.PersonRepositoryTest:  56 - Started PersonRepositoryTest in 4.88 seconds (JVM running for 5.387)
2015-09-08 12:15:26,259 DEBUG lytics.repository.AbstractRepositoryTest:  59 - Injecting embedded graph database instance ...
2015-09-08 12:15:26,260 DEBUG lytics.repository.AbstractRepositoryTest:  47 - Initialising embedded temporary graph database for executing unit tests ...
2015-09-08 12:15:26,674 DEBUG lytics.repository.AbstractRepositoryTest:  68 - Temporary database has been successfully populated with test data-set!
2015-09-08 12:15:26,817  INFO eldaccess.DelegatingFieldAccessorFactory:  74 - No FieldAccessor configured for field: class java.time.LocalDateTime dateOfBirth rel: false idx: false
2015-09-08 12:15:26,831 DEBUG lytics.repository.AbstractRepositoryTest:  74 - Emptying the temporary database used for unit test ...
2015-09-08 12:15:26,855 DEBUG lytics.repository.AbstractRepositoryTest:  77 - Temporary database has been emptied!

java.lang.AssertionError: 
Expected: a collection containing <Person{title='Prof.', firstName='Helen', lastName='Olson', dateOfBirth=1989-10-19T06:41:24}>
     but: was <Person{title='Prof.', firstName='Helen', lastName='Olson', dateOfBirth=null}>F

我用来预先填充我的非永久性数据库的cypher文件的内容如下所示

// Create 5 person nodes
MERGE (p1:Person {title:'Prof.', firstName:'Helen', lastName:'Olson', dateOfBirth:'1989-10-19 06:41:24'});
MERGE (p2:Person {title:'Dr.', firstName:'Bruce', lastName:'Hermiston', dateOfBirth:'1992-10-03 10:54:21'});
MERGE (p3:Person {title:'Mr.', firstName:'Regan', lastName:'Rice', dateOfBirth:'1973-10-05 00:43:54'});
MERGE (p4:Person {title:'Prof.', firstName:'Alysha', lastName:'Crooks', dateOfBirth:'1976-01-15 20:13:31'});
MERGE (p5:Person {title:'Prof.', firstName:'Arturo', lastName:'Turner', dateOfBirth:'1989-07-11 03:30:21'});
MATCH (p:Person) set p:_Person;

有人可以帮忙解释一下我在这里缺少什么吗?

0 个答案:

没有答案