5

Spring Data Neo4j (SDN) でノード エンティティを検索しているときに、奇妙な動作が発生しています。GraphRepository.findOne(long) を使用すると、エンティティが同じタイプでなくても、その識別子を持つエンティティが返されます。

これは、私の(非常に)単純化されたエンティティ構造がどのように見えるかです。

@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;

}

すべてのエンティティ タイプに対して、次のようなリポジトリを作成しました。

@Repository
public interface PersonRepository extends GraphRepository<Person> {}

@Repository
public interface AuditRepository extends GraphRepository<Audit> {}

サービス層クラスの抽象基本クラスがあります。それは大まかに次のようになります。

public abstract class MyServiceImpl<T extends BaseEntity> implements MyService<T> {

    private GraphRepository<T> repository;

    public MyServiceImpl(final GraphRepository<T> 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<Person> implements PersonService {

    private PersonRepository personRepository;

    @Autowired
    public PersonServiceImpl(final PersonRepository personRepository) {
        super(personRepository);
        this.personRepository = personRepository;
    }

}

次のコードを実行すると、結果が期待どおりになりません。

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);

AuditRepository が null を返すことが予想されますが、そうではありません。代わりに、識別子が 1L で、すべてのプロパティが null の Audit を返します。特定の識別子に対応するノードが存在する限り、そのタイプが何であるかは関係なく返されるようです。Person と Audit が一致するプロパティ名を持っていた場合、それらには値も含まれます...これはすべて予想される動作ですか、それとも何か不足していますか?

今のところ、私は自分で型チェックを行う以下のコードでこの問題を解決しました。

public abstract class MyServiceImpl<T extends BaseEntity> implements MyService<T> {

    private GraphRepository<T> repository;

    public MyServiceImpl(final GraphRepository<T> 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<T> type = getServiceType();
        if (entity == null || !(type.equals(repository.getStoredJavaType(entity)))) {
            throw new EntityNotFoundException(type, identifier);
        }
        return entity;
    }

    @SuppressWarnings("unchecked")
    private Class<T> getServiceType() {
         return (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
                 .getActualTypeArguments()[0];
    }

}

さらに構成が必要な場合は、お知らせください。

私のフレームワークのバージョンは次のとおりです。

<spring.version>3.2.0.RC1</spring.version>
<neo4j.version>1.8</neo4j.version>
<spring.data.neo4j.version>2.1.0.RELEASE</spring.data.neo4j.version>
4

1 に答える 1

2

間違ったエンティティ タイプが返されて失敗する前にその動作がありましたが、指定したタイプが自動的にノードを投影するために使用されるように動作を変更しました。

public <S extends PropertyContainer, T> T createEntityFromStoredType(S state, MappingPolicy mappingPolicy) {..}

テンプレート。createEntityFromStoredType(node, null) は、保存された状態のオブジェクトを取得します。

public Class getStoredJavaType(Object entity) {} 

ノードまたは関係 (またはエンティティ) の格納されたクラスを提供します

動作を元に戻し、esp を失敗させることについて話し合いました。リポジトリで。

問題は、そのとき何が起こるべきかということです。例外?Null の結果ですか? ...

一般に、有効な生のノード ID を指定した場合、エラーまたは Null を返すことも正解のようには見えませんか?

于 2012-11-14T08:40:37.637 に答える