SpringSource/spring-data-neo4j — Issue #34: ArrayIndexOutOfBoundsException when using with HighAvailabilityGraphDatabase
Author: rgan
Created: 2012-02-10 23:31:55+00:00
State: open

Attempting to use Spring-Data-Neo4j with the HighlyAvailableGraphDatabase version 1.6.M03 results in an ArrayIndexOutOfBounds exception. See sample code and stack trace below.
This error is thrown in AbstractConstructorEntityInstantiator.stateTakingConstructorInstantiator() method on line 141 because getInterfaces() returns an empty array for the type: HighlyAvailableGraphDatabase.LookupNode.
The LookupNode extends WrappedNode which in turn implements org.neo4j.graphdb.Node. But in Java, class.getInterfaces() only returns the immediate interfaces only. If this is replaced with ClassUtils.getAllInterfaces() then the sample code below works.

public static void main(String[] args) {
ConfigurableApplicationContext applicationContext =
new ClassPathXmlApplicationContext("/context.xml");
ClubRepository repo = applicationContext.getBean(ClubRepository.class);
Club club = new Club();
club.setName("foo");
repo.save(club);

for (Club c : repo.findAll()) {
System.out.println("Club:" + c.id + " - " + c.getName());
}
}

@NodeEntity
public class Club {

@Indexed(indexName = "club-name", indexType = IndexType.FULLTEXT)
private String name;

@GraphId
Long id;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

public interface ClubRepository extends GraphRepository, NamedIndexRepository {

Club findByName(String name);
}
--------------------------
package com.thoughtworks.neo4jtest;

import org.neo4j.kernel.HighlyAvailableGraphDatabase;

public class MyHighlyAvailableGraphDatabase extends HighlyAvailableGraphDatabase {
public MyHighlyAvailableGraphDatabase(String storeDir, String configFile) {
super(storeDir,
HighlyAvailableGraphDatabase.loadConfigurations(configFile));
}
}

Context.xml:

---------------------------------- Stack trace --------------------------
Exception in thread "main" org.springframework.dao.InvalidDataAccessApiUsageException: java.lang.ArrayIndexOutOfBoundsException: 0; nested exception is java.lang.IllegalArgumentException: java.lang.ArrayIndexOutOfBoundsException: 0
at org.springframework.data.neo4j.support.Neo4jExceptionTranslator.translateExceptionIfPossible(Neo4jExceptionTranslator.java:43)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:163)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy25.save(Unknown Source)
at com.thoughtworks.neo4jtest.Main.main(Main.java:14)
Caused by: java.lang.IllegalArgumentException: java.lang.ArrayIndexOutOfBoundsException: 0
at org.springframework.data.neo4j.support.mapping.AbstractConstructorEntityInstantiator.createEntityFromState(AbstractConstructorEntityInstantiator.java:62)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedInstantiator.createEntityFromState(Neo4jEntityPersister.java:133)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedInstantiator.createEntityFromState(Neo4jEntityPersister.java:120)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.read(Neo4jEntityConverterImpl.java:84)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedConverter.read(Neo4jEntityPersister.java:168)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.createEntityFromState(Neo4jEntityPersister.java:186)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:239)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:227)
at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:287)
at org.springframework.data.neo4j.repository.AbstractGraphRepository.save(AbstractGraphRepository.java:108)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:322)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:307)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
... 4 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
at org.springframework.data.neo4j.support.mapping.AbstractConstructorEntityInstantiator.stateTakingConstructorInstantiator(AbstractConstructorEntityInstantiator.java:141)
at org.springframework.data.neo4j.support.mapping.AbstractConstructorEntityInstantiator.createInstantiator(AbstractConstructorEntityInstantiator.java:73)
at org.springframework.data.neo4j.support.mapping.AbstractConstructorEntityInstantiator.createEntityFromState(AbstractConstructorEntityInstantiator.java:53)
... 23 more