I'm moving from SDN 3 to SDN 4 and from Neo4j 2.3 to 3.0.1
I have a following Search Cypher query:
@Query(value = "START d=node:node_auto_index({autoIndexQuery}) MATCH (d:Decision) RETURN d")
Page<Decision> searchDecisions(@Param("autoIndexQuery") String autoIndexQuery, Pageable page);
Param autoIndexQuery
in my test equals to following Lucene query:
(name:rdbma~0.33)^3 OR description:rdbma OR (name:mosyl~0.33)^3 OR description:mosyl
Right now
decisionRepository.searchDecisions(autoIndexQuery, new PageRequest(page, size));
returns null
but works fine on SDN 3 and Neo4j 2.3 and returns a Decision
nodes.
This is my Neo4jTestConfig:
@Configuration
@EnableNeo4jRepositories(basePackages = "com.example")
@EnableTransactionManagement
public class Neo4jTestConfig extends Neo4jConfiguration implements BeanFactoryAware {
private static final String NEO4J_EMBEDDED_DATABASE_PATH_PROPERTY = "neo4j.embedded.database.path";
@Resource
private Environment environment;
private BeanFactory beanFactory;
@SuppressWarnings("deprecation")
@Bean(destroyMethod = "shutdown")
public GraphDatabaseService graphDatabaseService() {
// @formatter:off
GraphDatabaseService graphDb = new GraphDatabaseFactory()
.newEmbeddedDatabaseBuilder(new File(environment.getProperty(NEO4J_EMBEDDED_DATABASE_PATH_PROPERTY)))
.setConfig(GraphDatabaseSettings.node_keys_indexable, "name,description")
.setConfig(GraphDatabaseSettings.node_auto_indexing, "true").
newGraphDatabase();
// @formatter:on
return graphDb;
}
/**
* Hook into the application lifecycle and register listeners that perform
* behaviour across types of entities during this life cycle
*
*/
@EventListener
public void handleBeforeSaveEvent(BeforeSaveEvent event) {
Object entity = event.getEntity();
if (entity instanceof BaseEntity) {
BaseEntity baseEntity = (BaseEntity) entity;
if (baseEntity.getCreateDate() == null) {
baseEntity.setCreateDate(new Date());
} else {
baseEntity.setUpdateDate(new Date());
}
}
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
public BeanFactory getBeanFactory() {
return beanFactory;
}
@Bean
public org.neo4j.ogm.config.Configuration getConfiguration() {
// @formatter:off
org.neo4j.ogm.config.Configuration config = new org.neo4j.ogm.config.Configuration();
config.driverConfiguration()
.setDriverClassName("org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver");
// @formatter:on
return config;
}
@Override
public SessionFactory getSessionFactory() {
return new SessionFactory(getConfiguration(), "com.example");
}
}
What can be wrong with my configuration and how to get it working on SDN 4?
UPDATED
Also, I have found the following answer Can't configure node_auto_index with InProcessServer() SDN 4 but can't find ServerControls and TestServerBuilders in my classpath.
This is my database index configuration:
@Transactional
public class SearchDaoImpl implements SearchDao {
@Autowired
private DecisionRepository decisionRepository;
@PostConstruct
public void init() {
EmbeddedDriver embeddedDriver = (EmbeddedDriver) Components.driver();
GraphDatabaseService databaseService = embeddedDriver.getGraphDatabaseService();
try (Transaction t = databaseService.beginTx()) {
Index<Node> autoIndex = databaseService.index().forNodes("node_auto_index");
databaseService.index().setConfiguration(autoIndex, "type", "fulltext");
databaseService.index().setConfiguration(autoIndex, "to_lower_case", "true");
databaseService.index().setConfiguration(autoIndex, "analyzer", StandardAnalyzerV36.class.getName());
t.success();
}
}
...
}
Right now I don't know where in my code is a correct place for adding
Components.setDriver(new EmbeddedDriver(graphDatabaseService()));
as suggested in the answers below
UPDATED 2
@SuppressWarnings("deprecation")
@Bean(destroyMethod = "shutdown")
public GraphDatabaseService graphDatabaseService() {
// @formatter:off
GraphDatabaseService graphDatabaseService = new GraphDatabaseFactory()
.newEmbeddedDatabaseBuilder(new File(environment.getProperty(NEO4J_EMBEDDED_DATABASE_PATH_PROPERTY)))
.setConfig(GraphDatabaseSettings.node_keys_indexable, "name,description")
.setConfig(GraphDatabaseSettings.node_auto_indexing, "true").
newGraphDatabase();
// @formatter:on
Components.setDriver(new EmbeddedDriver(graphDatabaseService));
return graphDatabaseService;
}
@Override
public SessionFactory getSessionFactory() {
return new SessionFactory("com.example");
}
The following configuration fails with:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getSession' defined in com.techbook.domain.configuration.Neo4jTestConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.neo4j.ogm.session.Session]: Factory method 'getSession' threw exception; nested exception is org.neo4j.ogm.exception.ServiceNotFoundException: Driver: null
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
By setting the driver class name property, the EmbeddedDriver will create a private instance of the GraphDatabaseService
, which is not what you want because you are initialising it yourself. Instead, you need to tell the Components class to explicitly use the driver you are providing:
Components.setDriver(new EmbeddedDriver(graphDatabaseService()));
This should wire up the components as you expect.