1
votes

This is a surprise. The Spring-Data-Neo4j GraphRepository code doesn't appear to be able to distinguish between objects of different types.

If I query a repository for an id which is a different type of object I would have expected it not to exist, and not be be loaded - but my test below shows that the repository doesn't appear to be qualifying the exist/findOne call with the object type and so is erroneously loading a B instance as if it's an A.

Is this a bug or a feature?

@NodeEntity class A { @GraphId Long id }
interface ARepository extends GraphRepository<A> {}

@NodeEntity class B { @GraphId Long id }
interface BRepository extends GraphRepository<B> {}

def "objects of different types should not leak between repositories"() {
    given: "an A and B object in the neo4j database"
    def a = new A()
    def b = new B()
    aRepository.save(a)
    bRepository.save(b)

    assert a.id != b.id

    when: "the A repository is queried for a B-id"
    def exists = aRepository.exists(b.id)
    def result = aRepository.findOne(b.id)

    then: "it should not be exist, and should not be loaded"
    !exists   // This assertion fails
    !result   // This assertion also fails
}

It looks like delete similarly can delete objects of different types. I would have thought that all CRUD method would have been qualified by the label associated with the domain object that the repository is working for.

1

1 Answers

0
votes

There is a typesafety strategy/policy in SDN for controlling that behavior:

<bean id="typeSafetyPolicy" class="org.springframework.data.neo4j.support.typesafety.TypeSafetyPolicy">
    <constructor-arg type="org.springframework.data.neo4j.support.typesafety.TypeSafetyOption"><value>RETURNS_NULL</value></constructor-arg>
</bean>

or

@Bean TypeSafetyPolicy typeSafetyPolicy() { 
  return new TypeSafetyPolicy(TypeSafetyOption.RETURNS_NULL); 
}