open Spring Data Neo4J contexts without killing the VM
I'm running a spring data neo-4j application (not web based) which works fine during normal operation.
If I close the Spring Context 'ctx.close()' the lock on the neo 4J database goes away.
Then, from the same instance of the application, if I grab another Context I see the lock come back, but if I try and read / write from that database from that context I get an error:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.data.neo4j.config.Neo4jConfiguration#0': Unsatisfied dependency expressed through bean property 'conversionService': : Error creating bean with name 'mappingInfrastructure' defined in class org.springframework.data.neo4j.config.Neo4jConfiguration: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public final org.springframework.data.neo4j.support.MappingInfrastructureFactoryBean org.springframework.data.neo4j.config.Neo4jConfiguration$$EnhancerByCGLIB$$64cefd6f.mappingInfrastructure() throws java.lang.Exception] threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'typeRepresentationStrategyFactory' defined in class org.springframework.data.neo4j.config.Neo4jConfiguration: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public final org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategyFactory org.springframework.data.neo4j.config.Neo4jConfiguration$$EnhancerByCGLIB$$64cefd6f.typeRepresentationStrategyFactory() throws java.lang.Exception] threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'graphDatabaseService': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.neo4j.kernel.EmbeddedGraphDatabase]: Constructor threw exception; nested exception is java.lang.IllegalStateException: Unable to lock store [C:app_datagelatodataneostore], this is usually a result of some other Neo4j kernel running using the same store.; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mappingInfrastructure' defined in class org.springframework.data.neo4j.config.Neo4jConfiguration: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public final org.springframework.data.neo4j.support.MappingInfrastructureFactoryBean org.springframework.data.neo4j.config.Neo4jConfiguration$$EnhancerByCGLIB$$64cefd6f.mappingInfrastructure() throws java.lang.Exception] threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'typeRepresentationStrategyFactory' defined in class org.springframework.data.neo4j.config.Neo4jConfiguration: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public final org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategyFactory org.springframework.data.neo4j.config.Neo4jConfiguration$$EnhancerByCGLIB$$64cefd6f.typeRepresentationStrategyFactory() throws java.lang.Exception] threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'graphDatabaseService': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.neo4j.kernel.EmbeddedGraphDatabase]: Constructor threw exception; nested exception is java.lang.IllegalStateException: Unable to lock store [C:app_datagelatodataneostore], this is usually a result of some other Neo4j kernel running using the same store.
Is there a way to successfully close and then re-open the Application Context within a single instance of an application (ie without shutting down the virtual machine) ?
I was initially calling shutdown() on the graph database, but changed this as Michael Hunger told me not to do it.
our problem can be reproduced in our domain like this.
AbstractApplicationContext ctx = new FileSystemXmlApplicationContext("neo4jconfig.xml");
OurDomainService domainService = (OurDomainService) ctx.getBean(OurDomainServiceImpl.class);
// This works
domainService.save(data);
// this releases the lock
ctx.close();
// this re-creates the lock and the context looks actvive
ctx = new FileSystemXmlApplicationContext("neo4jconfig.xml");
domainService = (OurDomainService) ctx.getBean(OurDomainServiceImpl.class);
// this errors out
domainService.save(data);
Here's the XML file we use to create the context.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/data/neo4j
http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:spring-configured/>
<context:annotation-config/>
<context:component-scan base-package="OurData" />
<neo4j:config storeDirectory="c:/app_data/data"/>
<neo4j:repositories base-package="OurData"/>
</beans>
You shouldn't do that, in your case the spring-context should handle the lifecycle.
What happens when you restart in your case?
You shut down the application-context with
ctx.close()
You should probably use a WebApplicationContext(Utils) to get your configured Spring Context via your web.xml. Like this:
WebApplicationContext springContext =
WebApplicationContextUtils.getWebApplicationContext(getServletContext());
Looking at my last comment and your responses have edited my complete answer.
The two main files below.
The first one uses WrappingNeoServerBootstrapper
A bootstrapper for the Neo4j Server that takes an already instantiated {@link org.neo4j.kernel.GraphDatabaseAPI}, and optional configuration, and launches a server using that database. Use this to start up a full Neo4j server from within an application that already uses the {@link EmbeddedGraphDatabase} or the {@link HighlyAvailableGraphDatabase}. This gives your application the full benefits of the server's REST API, the Web administration interface and statistics tracking.
package sandbox;
import org.neo4j.server.WrappingNeoServerBootstrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.neo4j.support.Neo4jTemplate;
public class GalaxyServiceTest {
private final static Logger slf4jLogger = LoggerFactory.getLogger(GalaxyServiceTest.class);
@Autowired
private GalaxyService galaxyService;
@Autowired
private Neo4jTemplate template;
public static void main(String args[]) throws InterruptedException {
GalaxyServiceTest main = new GalaxyServiceTest();
ApplicationContextLoader loader = new ApplicationContextLoader();
loader.load(main, "/spring/helloWorldContext.xml");
// The server starts with loading of above Context.xml
WrappingNeoServerBootstrapper neoServer = loader.getApplicationContext().getBean("serverWrapper", WrappingNeoServerBootstrapper.class);
//process something in repository
main.doSomething();
// do a graceful stop
int stop = neoServer.stop(0);
slf4jLogger.info("stopping Server status code {} ", stop);
//Restart the server
neoServer.start();
slf4jLogger.info("Restarting Server ");
// Process something in Repository
main.doSomething();
}
public void doSomething() {
galaxyService.makeSomeWorlds();
Iterable<World> allWorlds = galaxyService.getAllWorlds();
for (World world : allWorlds) {
slf4jLogger.info("World Name is {}", world.toString());
}
}
}
The application Context definition xml
<context:annotation-config />
<context:spring-configured/>
<context:component-scan base-package="sandbox" />
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager">
<bean id="jotm" class="org.springframework.data.neo4j.transaction.JotmFactoryBean"/>
</property>
</bean>
<neo4j:config graphDatabaseService="graphDatabaseService" />
<bean id="serverWrapper" class="org.neo4j.server.WrappingNeoServerBootstrapper"
init-method="start" destroy-method="stop">
<constructor-arg ref="graphDatabaseService" />
</bean>
<bean id="graphDatabaseService" class="org.neo4j.kernel.EmbeddedGraphDatabase"
destroy-method="shutdown">
<constructor-arg value="target/test-db"/>
</bean>
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
<neo4j:repositories base-package="sandbox"></neo4j:repositories>
</beans>
I hope this helps.
链接地址: http://www.djcxy.com/p/11794.html上一篇: 更新语句会使字段更新为NULL或最大值