3. 常见问题

1. 有查询结果,自定义Bean的为null

(1) 自定义的Bean 支持的类型 org.neo4j.driver.internal.types.TypeConstructor
(2) 属性转换时进行了特殊处理 org.springframework.data.neo4j.core.mapping.DtoInstantiatingConverter,属性为置为null
类型支持
Map
public enum TypeConstructor {
    ANY {
        @Override
        public boolean covers(Value value) {
            return !value.isNull();
        }
    },
    BOOLEAN,
    BYTES,
    STRING,
    NUMBER {
        @Override
        public boolean covers(Value value) {
            TypeConstructor valueType = typeConstructorOf(value);
            return valueType == this || valueType == INTEGER || valueType == FLOAT;
        }
    },
    INTEGER,
    FLOAT,
    LIST,
    MAP {
        @Override
        public boolean covers(Value value) {
            TypeConstructor valueType = typeConstructorOf(value);
            return valueType == MAP || valueType == NODE || valueType == RELATIONSHIP;
        }
    },
    NODE,
    RELATIONSHIP,
    PATH,
    POINT,
    DATE,
    TIME,
    LOCAL_TIME,
    LOCAL_DATE_TIME,
    DATE_TIME,
    DURATION,
    NULL;

    private static TypeConstructor typeConstructorOf(Value value) {
        return ((InternalValue) value).typeConstructor();
    }

    public boolean covers(Value value) {
        return this == typeConstructorOf(value);
    }
}
Object getPropertyValueFor(Neo4jPersistentProperty targetProperty, PersistentEntity<?, ?> sourceEntity,
			PersistentPropertyAccessor<?> sourceAccessor, EntityInstanceWithSource entityInstanceAndSource) {

		TypeSystem typeSystem = entityInstanceAndSource.getTypeSystem();
		MapAccessor sourceRecord = entityInstanceAndSource.getSourceRecord();

		String targetPropertyName = targetProperty.getName();
		PersistentProperty<?> sourceProperty = sourceEntity.getPersistentProperty(targetPropertyName);
		if (sourceProperty != null) {
			return sourceAccessor.getProperty(sourceProperty);
		}

		if (!sourceRecord.containsKey(targetPropertyName)) {
			log.warn(() -> String.format(""
					+ "Cannot retrieve a value for property `%s` of DTO `%s` and the property will always be null. "
					+ "Make sure to project only properties of the domain type or use a custom query that "
					+ "returns a mappable data under the name `%1$s`.", targetPropertyName, targetType.getName()));
		} else if (targetProperty.isMap()) {
			log.warn(() -> String.format(""
					+ "%s is an additional property to be projected. "
					+ "However, map properties cannot be projected and the property will always be null.",
					targetPropertyName));
		} else {
			// We don't support associations on the top level of DTO projects which is somewhat inline with the restrictions
			// regarding DTO projections as described in https://docs.spring.io/spring-data/jpa/docs/2.4.0-RC1/reference/html/#projections.dtos
			// > except that no proxying happens and no nested projections can be applied
			// Therefore, we extract associations kinda half-manual.

			Value property = sourceRecord.get(targetPropertyName);
			if (targetProperty.isCollectionLike() && !typeSystem.LIST().isTypeOf(property)) {
				log.warn(() -> String.format(""
						+ "%s is a list property but the selected value is not a list and the property will always be null.",
						targetPropertyName));
			} else {
				Class<?> actualType = targetProperty.getActualType();

				Function<Value, Object> singleValue;
				if (context.hasPersistentEntityFor(actualType)) {
					singleValue = p -> context.getEntityConverter().read(actualType, p);
				} else {
					ClassTypeInformation<?> actualTargetType = ClassTypeInformation.from(actualType);
					singleValue = p -> context.getConversionService().readValue(p, actualTargetType, targetProperty.getOptionalConverter());
				}

				if (targetProperty.isCollectionLike()) {
					List<Object> returnedValues = property.asList(singleValue);
					Collection<Object> target = CollectionFactory
							.createCollection(targetProperty.getType(), actualType, returnedValues.size());
					target.addAll(returnedValues);
					return target;
				} else {
					return singleValue.apply(property);
				}
			}
		}

		return null;
	}

2. 自定义CypherCql 执行查询方法时异常

参照下文:
java.lang.IllegalArgumentException: Cannot get or create persistent entity.
	at org.springframework.util.Assert.notNull(Assert.java:201) ~[spring-core-5.3.25.jar:5.3.25]
	at org.springframework.data.neo4j.core.TemplateSupport.getAndDecorateMappingFunction(TemplateSupport.java:253) ~[spring-data-neo4j-6.3.8.jar:6.3.8]
	at org.springframework.data.neo4j.core.Neo4jTemplate.createExecutableQuery(Neo4jTemplate.java:1052) ~[spring-data-neo4j-6.3.8.jar:6.3.8]
	at org.springframework.data.neo4j.core.Neo4jTemplate.toExecutableQuery(Neo4jTemplate.java:1044) ~[spring-data-neo4j-6.3.8.jar:6.3.8]
原因:
	(1)自定义查询语句时参数类型 用的是 QueryFragmentsAndParameters.java , 而非 PreparedQuery.java
	(2)使用 QueryFragmentsAndParameters 时会对 domainType 进行判断是否有 @Node 注解
		Supplier<BiFunction<TypeSystem, MapAccessor, ?>> mappingFunction = TemplateSupport
			.getAndDecorateMappingFunction(neo4jMappingContext, domainType, resultType);	
@Override
public <T> ExecutableQuery<T> toExecutableQuery(Class<T> domainType,
												QueryFragmentsAndParameters queryFragmentsAndParameters) {

	return createExecutableQuery(domainType, null, queryFragmentsAndParameters);
}


private <T> ExecutableQuery<T> createExecutableQuery(Class<T> domainType, @Nullable Class<?> resultType,
			QueryFragmentsAndParameters queryFragmentsAndParameters) {

	Supplier<BiFunction<TypeSystem, MapAccessor, ?>> mappingFunction = TemplateSupport
			.getAndDecorateMappingFunction(neo4jMappingContext, domainType, resultType);
	PreparedQuery<T> preparedQuery = PreparedQuery.queryFor(domainType)
			.withQueryFragmentsAndParameters(queryFragmentsAndParameters)
			.usingMappingFunction(mappingFunction)
			.build();
	return toExecutableQuery(preparedQuery);
}

@Override
public <T> ExecutableQuery<T> toExecutableQuery(PreparedQuery<T> preparedQuery) {

	return new DefaultExecutableQuery<>(preparedQuery);
}

3. 查询结果的开始节点和结束节点相反

Cyper: match p=(s)-[r]-(t) return p limit 3
	返回的结果 PathValue 中 s是start节点,t是end节点
	具有方向指向性的节点id是 Relationship 中的 startend,代表了关系的真实指向
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值