Populate Database application - Null pointer exception

340 views
Skip to first unread message

Chris

unread,
May 6, 2012, 1:55:43 PM5/6/12
to ne...@googlegroups.com
Hi All,

I'm trying to start actually populating a db and start working with cypher and graph performance - instead of unit tests. My first hurdle is understanding the spring configuration and linking to the DB, which I find is missing from the SDN reference manual. I created a new class to get me off the groud with some nodes and some relationships. I get a null pointer exception when I try creating a node, my repositories are null and so is Neo4jOperations, I do get the graphDatabaseService from my spring context though. The code is a mess because i've been trying to get it working. How do I point neo4jOperations at the graphDB? I thought the spring context would make the link. Neo4jOperations has a getGraphDatabase method but no setGraphDatabase. I have also moved everything in the main method into populate() but still get NPE.


@ContextConfiguration({"/spring/springContext.xml"})
@Transactional
public class DBPopulatorApp {

    public static void main(String[] args) {
       
        final FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext("src/main/resources/spring/springContext.xml");
       
        try {
            GraphDatabaseService graph = (GraphDatabaseService) ctx.getBean("graphDatabaseService");
            Transaction tx = graph.beginTx();
            try{
                DatabasePopulator dp = new DatabasePopulator();
                dp.populate();
                tx.success();
            } catch (Exception e)
            {
                e.printStackTrace();
                tx.failure();
            } finally {
                tx.finish();
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }
        finally {
            ctx.close();
        }
    } // main
}

@ContextConfiguration({"/spring/springContext.xml"})
@Transactional
public class DatabasePopulator {

    @Autowired protected ResourceRepository resourceRepository;
    @Autowired Neo4jOperations template;
   
    public DatabasePopulator()
    {
    }
   
    @Transactional
    public void populate()
    {
        final FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext("src/main/resources/spring/springContext.xml");
        GraphDatabaseService graph = (GraphDatabaseService) ctx.getBean("graphDatabaseService");
        Transaction tx = graph.beginTx();
        try{
            Resource res1 = template.save( new Resource("123", "Desk") );
            Resource res2 = template.save( new Resource("124", "Computer") );
            ...
           tx.success();
    } catch () {tx.failure();} finally{tx.finish();}
    }
}

springContext.xml
<?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-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

    <context:spring-configured/>
    <context:annotation-config/>
   
    <!-- -->
    <neo4j:config storeDirectory="target/repository-db" graphDatabaseService="graphDatabaseService"/>
    
    <neo4j:repositories base-package="jackal.mytest.repository"/>
   
    <bean id="graphDatabaseService" class="org.neo4j.kernel.EmbeddedGraphDatabase"
                destroy-method="shutdown">
        <constructor-arg index="0" value="target/repository-db"/>
    </bean>
    
    <tx:annotation-driven mode="proxy"/>
    
</beans>

Thanks!

Michael Hunger

unread,
May 7, 2012, 4:29:06 AM5/7/12
to ne...@googlegroups.com
Chris,

@ContextConfiguration  only works for unit-tests for other ways of intitializing the spring config:
- a main class using ClassPathXmlApplicationContext
- a webapp with WebApplicationContext (ServletLifecycleListener)
- the spring context makes the link
- you must not instantiate classes on your own if you want to use spring dependency injection rather declare the class in the context as a spring bean and get it from the context.


Michael

Chris

unread,
May 7, 2012, 9:02:09 AM5/7/12
to ne...@googlegroups.com
Hi Michael,

Thanks for clarifying, is working now.  I do have a few questions about my results

I thought nodes with the same name/id wouldn't be created but that node would be updated in repo? I ran my populate() method a few times to see and when I loop through all the nodes in my repository I have multiple results(identical fields)

Related to question above, I modify a property in my Resource class, like add a description that's not set in the constructor, then call template.save(res1); and it throws an IllegalStateException (I'll post code below). Note this only throws it when I add relationships through my res1 (Resource) variable.


Thanks!

// throws IllegalStateException
@Transactional
    public void populate()

    {
       
        Resource res1 = template.save( new Resource("123", "Desk") );
        Resource res2 = template.save( new Resource("124", "Computer") );
        ResourceService rs1 = template.save( new ResourceService("5001", "Resource Service 1", "http://example.com"));
        template.save(res1.addResourceService(rs1));
        template.save(res1.linkResource(res2));
        res1.setDescription("Desk that holds my computer at 123 Example Avenue");
        template.save(res1);

    }

Exception in thread "main" java.lang.IllegalStateException: Relationship[5] has been deleted in this tx
    at org.neo4j.kernel.impl.core.LockReleaser$CowEntityElement.assertNotDeleted(LockReleaser.java:128)
    at org.neo4j.kernel.impl.core.LockReleaser$CowEntityElement.getPropertyAddMap(LockReleaser.java:121)
    at org.neo4j.kernel.impl.core.LockReleaser$CowRelElement.getPropertyAddMap(LockReleaser.java:196)
    at org.neo4j.kernel.impl.core.LockReleaser.getCowPropertyAddMap(LockReleaser.java:525)
    at org.neo4j.kernel.impl.core.NodeManager.getCowPropertyAddMap(NodeManager.java:1138)
    at org.neo4j.kernel.impl.core.Primitive.getProperty(Primitive.java:149)
    at org.neo4j.kernel.impl.core.RelationshipProxy.getProperty(RelationshipProxy.java:90)
    at org.springframework.data.neo4j.support.typerepresentation.AbstractIndexingTypeRepresentationStrategy.getJavaType(AbstractIndexingTypeRepresentationStrategy.java:89)
    at org.springframework.data.neo4j.support.mapping.TRSTypeAliasAccessor.readAliasFrom(TRSTypeAliasAccessor.java:39)
    at org.springframework.data.neo4j.support.mapping.TRSTypeAliasAccessor.readAliasFrom(TRSTypeAliasAccessor.java:29)
    at org.springframework.data.convert.DefaultTypeMapper.readType(DefaultTypeMapper.java:72)
    at org.springframework.data.convert.DefaultTypeMapper.getDefaultedTypeToBeUsed(DefaultTypeMapper.java:116)
    at org.springframework.data.convert.DefaultTypeMapper.readType(DefaultTypeMapper.java:93)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.read(Neo4jEntityConverterImpl.java:74)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedConverter.read(Neo4jEntityPersister.java:168)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.createEntityFromState(Neo4jEntityPersister.java:189)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:245)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:227)
    at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:295)
    at org.springframework.data.neo4j.fieldaccess.OneToNRelationshipEntityFieldAccessorFactory$OneToNRelationshipEntityFieldAccessor.persistEntities(OneToNRelationshipEntityFieldAccessorFactory.java:80)
    at org.springframework.data.neo4j.fieldaccess.OneToNRelationshipEntityFieldAccessorFactory$OneToNRelationshipEntityFieldAccessor.setValue(OneToNRelationshipEntityFieldAccessorFactory.java:74)
    at org.springframework.data.neo4j.fieldaccess.DefaultEntityState.setValue(DefaultEntityState.java:113)
    at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.setEntityStateValue(SourceStateTransmitter.java:78)
    at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.access$100(SourceStateTransmitter.java:39)
    at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter$4.doWithAssociation(SourceStateTransmitter.java:134)
    at org.springframework.data.mapping.model.BasicPersistentEntity.doWithAssociations(BasicPersistentEntity.java:185)
    at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyPropertiesTo(SourceStateTransmitter.java:130)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.write(Neo4jEntityConverterImpl.java:149)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedConverter.write(Neo4jEntityPersister.java:176)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:238)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:227)
    at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:295)
    at jackal.mytest.example.DatabasePopulator.populate(DatabasePopulator.java:83)
    at jackal.mytest.example.DatabasePopulator$$FastClassByCGLIB$$f3e9df42.invoke(<generated>)
    at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
    at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:688)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)
    at jackal.mytest.example.DatabasePopulator$$EnhancerByCGLIB$$7911dbed.populate(<generated>)
    at jackal.mytest.example.DBPopulatorApp.main(DBPopulatorApp.java:15)


// this method works
@Transactional
    public void populate()

    {
       
                Resource res1 = template.save( new Resource("123", "Desk") );
            Resource res2 = template.save( new Resource("124", "Computer") );
        ResourceService rs1 = template.save( new ResourceService("5001", "Resource Service 1", "http://example.com"));
        template.save(rs1.addResource(res1));
        template.save(res2.linkResource(res1));
        res1.setDescription("Desk that holds my computer at 123 Example Avenue");
        template.save(res1);

Michael Hunger

unread,
May 7, 2012, 9:51:26 AM5/7/12
to ne...@googlegroups.com
Hi,

Am 07.05.2012 um 15:02 schrieb Chris:

Hi Michael,

Thanks for clarifying, is working now.  I do have a few questions about my results

I thought nodes with the same name/id wouldn't be created but that node would be updated in repo? I ran my populate() method a few times to see and when I loop through all the nodes in my repository I have multiple results(identical fields)
I think you're talking about uniqueness? Did you add @Indexed(unique=true) to the correct fields?


Related to question above, I modify a property in my Resource class, like add a description that's not set in the constructor, then call template.save(res1); and it throws an IllegalStateException (I'll post code below). Note this only throws it when I add relationships through my res1 (Resource) variable.

in the example below, what do addResourceService and linkResource do? and return?

Would it be possible to create a failing test (or sample project) for this behavior and share it? That would be great.

Thanks

Michael

Chris

unread,
May 7, 2012, 6:21:15 PM5/7/12
to ne...@googlegroups.com
Hi Michael,

I tried adding them when you gave me Tag advice but I get an error
"The attribute unique is undefined for the annotation type Indexed"

I'm still getting started with github but will push project when I'm setup.

They create the corresponding relationship and add it to my @relatedToVia collection. they return the relationship, off the top of my head (on road) is something like

public ResourceRelationship linkResource(Resource res)
{
    ResourceRelationship rr = new ResourceRelationship(this, res);
    this.resourceRelationships.add(rr);
    return rr;
}

I get around the problem by setting the description in the constructor, just weird that it works for my unit tests and not here... if it helps any, when I debug after setting the description I see the correct field values for the node but all my relationships are empty collections.

Thank you

Michael Hunger

unread,
May 7, 2012, 6:44:18 PM5/7/12
to ne...@googlegroups.com
What version of SDN are you using?

Today we released SDN 2.1.RC1

Michael

Chris

unread,
May 8, 2012, 10:04:10 AM5/8/12
to ne...@googlegroups.com
2.0.1.RELEASE

Michael Hunger

unread,
May 8, 2012, 10:34:24 AM5/8/12
to ne...@googlegroups.com
Please try to post your sample project (with a readme that describes the issue, otherwise it is really hard to follow) 
I don't mind if on github or as zip-file.

thanks a lot

Michael
Reply all
Reply to author
Forward
0 new messages