I am trying to create a cluster of Java applications running the embedded Neo4J HA server but I am getting an error when starting any slave servers
Caused by: org.springframework.dao.InvalidDataAccessResourceUsageException: Error executing statement CREATE INDEX ON :`DeviceNode`(`deviceType`); nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: Error executing statement CREATE INDEX ON :`DeviceNode`(`deviceType`); nested exception is org.neo4j.cypher.CypherExecutionException: Modifying the database schema can only be done on the master server, this server is a slave. Please issue schema modification commands directly to the master.
at org.springframework.data.neo4j.support.query.CypherQueryEngine.query(CypherQueryEngine.java:56) ~[spring-data-neo4j-3.0.0.RELEASE.jar:na]
at org.springframework.data.neo4j.support.schema.SchemaIndexProvider.createIndex(SchemaIndexProvider.java:36) ~[spring-data-neo4j-3.0.0.RELEASE.jar:na]
at org.springframework.data.neo4j.support.mapping.EntityIndexCreator$1.doWithPersistentProperty(EntityIndexCreator.java:45) ~[spring-data-neo4j-3.0.0.RELEASE.jar:na]
at org.springframework.data.neo4j.support.mapping.EntityIndexCreator$1.doWithPersistentProperty(EntityIndexCreator.java:41) ~[spring-data-neo4j-3.0.0.RELEASE.jar:na]
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:261) ~[spring-data-commons-1.7.0.RELEASE.jar:na]
at org.springframework.data.neo4j.support.mapping.EntityIndexCreator.ensureEntityIndexes(EntityIndexCreator.java:41) ~[spring-data-neo4j-3.0.0.RELEASE.jar:na]
at org.springframework.data.neo4j.support.mapping.Neo4jMappingContext.updateStoredEntityType(Neo4jMappingContext.java:77) ~[spring-data-neo4j-3.0.0.RELEASE.jar:na]
at org.springframework.data.neo4j.support.mapping.Neo4jMappingContext.addPersistentEntity(Neo4jMappingContext.java:71) ~[spring-data-neo4j-3.0.0.RELEASE.jar:na]
at org.springframework.data.neo4j.support.mapping.Neo4jMappingContext.addPersistentEntity(Neo4jMappingContext.java:49) ~[spring-data-neo4j-3.0.0.RELEASE.jar:na]
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:170) ~[spring-data-commons-1.7.0.RELEASE.jar:na]
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:139) ~[spring-data-commons-1.7.0.RELEASE.jar:na]
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:65) ~[spring-data-commons-1.7.0.RELEASE.jar:na]
at org.springframework.data.neo4j.repository.query.CypherQueryBuilder.<init>(CypherQueryBuilder.java:37) ~[spring-data-neo4j-3.0.0.RELEASE.jar:na]
at org.springframework.data.neo4j.repository.query.CypherQueryCreator.create(CypherQueryCreator.java:72) ~[spring-data-neo4j-3.0.0.RELEASE.jar:na]
at org.springframework.data.neo4j.repository.query.CypherQueryCreator.create(CypherQueryCreator.java:35) ~[spring-data-neo4j-3.0.0.RELEASE.jar:na]
at org.springframework.data.repository.query.parser.AbstractQueryCreator.createCriteria(AbstractQueryCreator.java:109) ~[spring-data-commons-1.7.0.RELEASE.jar:na]
at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:88) ~[spring-data-commons-1.7.0.RELEASE.jar:na]
at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:73) ~[spring-data-commons-1.7.0.RELEASE.jar:na]
at org.springframework.data.neo4j.repository.query.DerivedCypherRepositoryQuery.<init>(DerivedCypherRepositoryQuery.java:59) ~[spring-data-neo4j-3.0.0.RELEASE.jar:na]
at org.springframework.data.neo4j.repository.query.GraphQueryMethod.createQuery(GraphQueryMethod.java:146) ~[spring-data-neo4j-3.0.0.RELEASE.jar:na]
at org.springframework.data.neo4j.repository.GraphRepositoryFactory$1.resolveQuery(GraphRepositoryFactory.java:113) ~[spring-data-neo4j-3.0.0.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:304) ~[spring-data-commons-1.7.0.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:161) ~[spring-data-commons-1.7.0.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:224) ~[spring-data-commons-1.7.0.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:210) ~[spring-data-commons-1.7.0.RELEASE.jar:na]
at org.springframework.data.neo4j.repository.GraphRepositoryFactoryBean.afterPropertiesSet(GraphRepositoryFactoryBean.java:69) ~[spring-data-neo4j-3.0.0.RELEASE.jar:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1571) ~[spring-beans-3.2.8.RELEASE.jar:3.2.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1509) ~[spring-beans-3.2.8.RELEASE.jar:3.2.8.RELEASE]
... 38 common frames omitted
The most important bit seems to be Modifying the database schema can only be done on the master server, this server is a slave. Please issue schema modification commands directly to the master
. I believe that the index is being created as the Repository interfaces are parsed by SDN.
Have I done something crazy somewhere, can I tell the slaves just to hang back a little and pull their schema from the Master which will get there in the end? I believe that my config is fairly standard:
<util:map id="config">
<entry key="org.neo4j.server.database.mode" value="HA"/>
<entry key="enable_remote_shell" value="true"/>
<entry key="ha.server_id" value="1"/>
<entry key="ha.initial_hosts" value="neo1:5001,neo2:5001,neo3:5001"/>
<entry key="ha.allow_init_cluster" value="true"/>
<entry key="ha.cluster_join_timeout" value="60s"/>
<entry key="ha.slave_only" value="false"/>
</util:map>
<bean id="graphDbFactory" class="org.neo4j.graphdb.factory.HighlyAvailableGraphDatabaseFactory"/>
<bean id="graphDbBuilder" factory-bean="graphDbFactory" factory-method="newHighlyAvailableDatabaseBuilder">
<constructor-arg value="#{neoloc}"/>
</bean>
<bean id="graphDbBuilderFinal" factory-bean="graphDbBuilder" factory-method="setConfig">
<constructor-arg ref="config"/>
</bean>
<bean id="graphDatabaseService" factory-bean="graphDbBuilderFinal" factory-method="newGraphDatabase" destroy-method="shutdown" />
<neo4j:config graphDatabaseService="graphDatabaseService"/>
<neo4j:repositories base-package="com.clarifimedia.data.repository"></neo4j:repositories>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.clarifimedia.data.converter.DateTimeToLongConverter"/>
<bean class="com.clarifimedia.data.converter.LongToDateTimeConverter"/>
</set>
</property>
</bean>
Configuration values are in fact read from JNDI but I have hardcoded above as a load of #{xyz}
wouldn't be so handy.
Versions
neo4j-2.0.1
neo4j-ha-2.0.1
spring-data-neo4j-3.0.0.RELEASE
spring-general-stuff-3.2.8.RELEASE
[Edit, tangent, bug?]
I tried to start three isolated masters by breaking the network, with the intent of fixing the network and seeing if an election took place. However on startup the webapp fails to start due to a TimeoutException.
Caused by: java.util.concurrent.TimeoutException: null
at org.neo4j.cluster.statemachine.StateMachineProxyFactory$ResponseFuture.get(StateMachineProxyFactory.java:300) ~[neo4j-cluster-2.0.1.jar:2.0.1]
at org.neo4j.cluster.client.ClusterJoin.joinByConfig(ClusterJoin.java:158) ~[neo4j-cluster-2.0.1.jar:2.0.1]
at org.neo4j.cluster.client.ClusterJoin.start(ClusterJoin.java:91) ~[neo4j-cluster-2.0.1.jar:2.0.1]
at org.neo4j.kernel.lifecycle.LifeSupport$LifecycleInstance.start(LifeSupport.java:503) ~[neo4j-kernel-2.0.1.jar:2.0.1]
ClusterJoin catches both InterruptedException and ExecutionException but not the TimeoutException as thrown by StateMachineProxyFactory$ResponseFuture. Given the while(true)
in the ClusterJoin class I think this is a bug or do I somehow have a bad mix of jar files (although both these classes are in neo4j-cluster-2.0.1).