Note that there are some explanatory texts on larger screens.

plurals
  1. POResolving entities with Spring Data Neo4j returns wrong entity types
    text
    copied!<p>I'm experiencing some strange behavior when I'm looking up node entities with Spring Data Neo4j (SDN). If I use GraphRepository.findOne(long) it will return an entity with that identifier even though the entity is not of the same type.</p> <p>This is what my (very) simplified entity structure looks like:</p> <pre><code>@NodeEntity protected abstract class BaseEntity { @GraphId private Long id; @JsonIgnore @RelatedTo(type = RelationType.ENTITY_AUDIT) private Audit audit; } @NodeEntity public final class Person extends BaseEntity { @Indexed(indexType = IndexType.FULLTEXT) private String firstName; @Indexed(indexType = IndexType.FULLTEXT) private String lastName; } @NodeEntity public class Audit extends BaseEntity { @RelatedTo(type = RelationType.ENTITY_AUDIT, direction = Direction.INCOMING) private BaseEntity parent; private Long date; private String user; } </code></pre> <p>For every entity type, I've created repositories like this:</p> <pre><code>@Repository public interface PersonRepository extends GraphRepository&lt;Person&gt; {} @Repository public interface AuditRepository extends GraphRepository&lt;Audit&gt; {} </code></pre> <p>I've got an abstract base class for my service layer classes. That is what they roughly look like:</p> <pre><code>public abstract class MyServiceImpl&lt;T extends BaseEntity&gt; implements MyService&lt;T&gt; { private GraphRepository&lt;T&gt; repository; public MyServiceImpl(final GraphRepository&lt;T&gt; repository) { this.repository = repository; } @Override public T read(final Long identifier) throws EntityNotFoundException { return repository.findOne(identifier); } @Override public T create(final T entity) { return repository.save(entity); } } @Service public class PersonServiceImpl extends MyServiceImpl&lt;Person&gt; implements PersonService { private PersonRepository personRepository; @Autowired public PersonServiceImpl(final PersonRepository personRepository) { super(personRepository); this.personRepository = personRepository; } } </code></pre> <p>When I execute the following code, the result is not as expected:</p> <pre><code>Person person = new Person(); person.setFirstName("Test"); person.setLastName("Person"); personService.create(person); // suppose the person identifier is 1L final Audit audit = auditRepository.findOne(1L); </code></pre> <p>You'd expect that the AuditRepository would return null, but this in not the case. Instead, it returns an Audit with identifier 1L and null in all of its properties. It seems that as long as there's a node that corresponds to a given identifier, it will be returned, no mather what its type is. If Person and Audit would have had matching property names, they would contain their values too... Is all this expected behavior, or am I missing something?</p> <p>For now, I've solved this problem with the code below, where I do the type check myself.</p> <pre><code>public abstract class MyServiceImpl&lt;T extends BaseEntity&gt; implements MyService&lt;T&gt; { private GraphRepository&lt;T&gt; repository; public MyServiceImpl(final GraphRepository&lt;T&gt; repository) { this.repository = repository; } @Override public T read(final Long identifier) throws EntityNotFoundException { return get(identifier); } protected T get(final Long identifier) throws EntityNotFoundException { final T entity = repository.findOne(identifier); final Class&lt;T&gt; type = getServiceType(); if (entity == null || !(type.equals(repository.getStoredJavaType(entity)))) { throw new EntityNotFoundException(type, identifier); } return entity; } @SuppressWarnings("unchecked") private Class&lt;T&gt; getServiceType() { return (Class&lt;T&gt;) ((ParameterizedType) getClass().getGenericSuperclass()) .getActualTypeArguments()[0]; } } </code></pre> <p>If you need more configuration, please let me know.</p> <p>My framework versions are:</p> <pre><code>&lt;spring.version&gt;3.2.0.RC1&lt;/spring.version&gt; &lt;neo4j.version&gt;1.8&lt;/neo4j.version&gt; &lt;spring.data.neo4j.version&gt;2.1.0.RELEASE&lt;/spring.data.neo4j.version&gt; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload