Results 1 to 5 of 5

Thread: Inheritance question for Spring Data Neo4j

  1. #1

    Default Inheritance question for Spring Data Neo4j

    Hi,
    I'm running into a problem with Spring Data Neo4j and inheritance.
    My model looks like:
    @NodeEntity
    public abstract class Shape implements IEntity {
    @GraphId
    private Long id;
    }
    and
    public class Polygon extends Shape { ... }
    public class Circle extends Shape { ... }

    Now, I'm using a simple DAO:
    public interface IShapeNeo4JDAO extends GraphRepository<Shape> { ... }

    When doing:
    shapeDao.findAll();
    I am getting:
    Code:
    java.lang.IllegalArgumentException: java.lang.InstantiationException
    	at org.springframework.data.neo4j.support.mapping.AbstractConstructorEntityInstantiator.createEntityFromState(AbstractConstructorEntityInstantiator.java:63)
    	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.projectTo(Neo4jEntityPersister.java:213)
    	at org.springframework.data.neo4j.support.conversion.EntityResultConverter.doConvert(EntityResultConverter.java:51)
    	at org.springframework.data.neo4j.conversion.DefaultConverter.convert(DefaultConverter.java:43)
    	at org.springframework.data.neo4j.support.conversion.EntityResultConverter.convert(EntityResultConverter.java:82)
    	at org.springframework.data.neo4j.conversion.QueryResultBuilder$1.convert(QueryResultBuilder.java:102)
    	at org.springframework.data.neo4j.conversion.QueryResultBuilder$1.access$300(QueryResultBuilder.java:81)
    	at org.springframework.data.neo4j.conversion.QueryResultBuilder$1$1.underlyingObjectToObject(QueryResultBuilder.java:120)
    	at org.neo4j.helpers.collection.IteratorWrapper.next(IteratorWrapper.java:47)
    	at com.google.common.collect.Lists.newArrayList(Lists.java:145)
    	at com.google.common.collect.Lists.newArrayList(Lists.java:125)
    	at org.rest.persistence.service.AbstractService.findAll(AbstractService.java:52)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:601)
    	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    	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.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    	at $Proxy61.findAll(Unknown Source)
    	at com.geogrep.persistence.service.impl.ShapePersistenceIntegrationTest.givenAnEntityExists_whenEntitiesAreRetrieved_thenTheExistingEntityIsIndeedAmongThem(ShapePersistenceIntegrationTest.java:88)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:601)
    	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
    	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    	at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    Caused by: java.lang.InstantiationException
    	at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48)
    	at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
    	at org.springframework.data.neo4j.support.mapping.AbstractConstructorEntityInstantiator$2.create(AbstractConstructorEntityInstantiator.java:109)
    	at org.springframework.data.neo4j.support.mapping.AbstractConstructorEntityInstantiator.createEntityFromState(AbstractConstructorEntityInstantiator.java:56)
    	... 57 more
    Which kind of makes sense, as the type information is for Shape, so Shape is being instantiated (and fails because is abstract). Is there any way to inform Spring Data about the type information so that the result of the findAll() operation would be a list containing the correct Circle and Polygon entities?
    If not, what's the best way to construct this findAll operation - I'd like to be able to retrieve all shapes (entities that extend Shape) in the system.
    Any help is appreciated.
    Thanks.
    Eugen.

  2. #2

    Default

    Update: the much weirder behavior is that this exception happens inconsistently - one time, findAll() actually returns as expected, a mixture of Circle and Polygon, and some other time is fails with that exception; running the exact same tests again results in another test failing and another one passing - extremely strange and non deterministic. It may be related to the fact that the node instantiators are cached, so, depending on the order the tests run in, a cached instantiator will be used one time and a fresh one the next run, when the order of the tests is different.
    Last edited by eugenparaschiv; Jun 26th, 2012 at 05:20 PM.

  3. #3

    Default

    Turns out that it was the way I was persisting the entities - persisting them via the DAOs of the concrete child classes stores the type information properly; persisting them via the more generic DAO (for Shape) will not.

  4. #4

    Default

    I have found an extension to this problem. The solutions presented here works if you are not using the @TypAlias annotation. When using the @TypeAlias annotation the class lookup does not work which i kind of get but at the same time should this not be mapped to some class by the code that scans the annotations?

    The solution is to remove the @TypeAlias annotations from the inheritance tree. Unfortunately this also means that you will potentially brake your graph mapping by refactoring...

  5. #5
    Join Date
    Jan 2011
    Location
    Dresden, Germany
    Posts
    525

    Default

    Actually TypeAlias was explicitely added to support inheritance hierarchies, can you provide a failing unit-test?

    Thanks a lot

    Michael

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •