Spring Data Neo4j 4 : Failed to convert from type

2019-08-12 07:40发布

Having this Repository method

@Query("MATCH (i:`Interest`) WHERE not(i-[:PARENT]->()) return i")
public Page<Interest> findAllByParentIsNull(Pageable pageRequest);

It cause (it didn't respect the specification):

org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.util.LinkedHashSet<?> to type org.springframework.data.domain.Page<?> for value '[com.nearofme.model.Interest@12a4479, com.nearofme.model.Interest@15bdfb3, com.nearofme.model.Interest@1af6067, com.nearofme.model.Interest@1c17d4d, com.nearofme.model.Interest@df65f4, com.nearofme.model.Interest@3b140d, com.nearofme.model.Interest@1e24566, com.nearofme.model.Interest@da49c9]'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type java.util.LinkedHashSet<?> to type org.springframework.data.domain.Page<?>
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:192)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:176)
    at org.springframework.data.repository.core.support.QueryExecutionResultHandler.postProcessInvocationResult(QueryExecutionResultHandler.java:75)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:439)

Debugging the code shows that a conversion is needed at the GraphRepositoryQuery level :

    @Override
    public final Object execute(Object[] parameters) {
        Class<?> returnType = graphQueryMethod.getMethod().getReturnType();
        Class<?> concreteType = graphQueryMethod.resolveConcreteReturnType();

        Map<String, Object> params = resolveParams(parameters);
        // could be converted here 
        return execute(returnType, concreteType, getQueryString(), params);
    }

The current code convert the result at GraphRepositoryImpl with the private method updatePage that should be used in the GraphRepositoryQuery

@Override
    public Page<T> findAll(Pageable pageable, int depth) {
        Collection<T> data = session.loadAll(clazz, convert(pageable.getSort()), new Pagination(pageable.getPageNumber(), pageable.getPageSize()), depth);
        return updatePage(pageable, new ArrayList<T>(data));
    }

1条回答
Root(大扎)
2楼-- · 2019-08-12 08:15

So my current temporary solution is to update GraphRepositoryQuery with :

@Override
    public final Object execute(Object[] parameters) {
        Class<?> returnType = graphQueryMethod.getMethod().getReturnType();
        Class<?> concreteType = graphQueryMethod.resolveConcreteReturnType();

        Map<String, Object> params = resolveParams(parameters);

        Object result = execute(returnType, concreteType, getQueryString(), params);
        if (params.size()>0){
            Object param = params.values().toArray()[0];
            if (param instanceof Pageable){
                Pageable pageable = (Pageable) param;
                result = updatePage(pageable, new ArrayList((Collection) result));
            }               
        }   
        return result;
    }

    private Page updatePage(Pageable pageable, List results) {
        int pageSize = pageable.getPageSize();
        int pageOffset = pageable.getOffset();
        int total = pageOffset + results.size() + (results.size() == pageSize ? pageSize : 0);

        return new PageImpl(results, pageable, total);
    }

No more need to convert inside the GraphRepositoryImpl but it still working

查看更多
登录 后发表回答