当前位置: 首页 > 知识库问答 >
问题:

Spring数据-neo4j v6:未找到能够从类型 [MyDTO] 转换为类型 [org.neo4j.驱动程序.值] 的转换器

麹培
2023-03-14

情况

我正在将kotlin Spring data neo4j应用程序从spring-data-neo4jversion5.2.0.RELEASE迁移到version6.0.11

原始应用程序有几个带有自定义查询的存储库接口,这些接口将一些DTO作为参数,并使用各种DTO字段来构造查询。目前所有这些类型的查询都失败了

org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [MyDTO] to type [org.neo4j.driver.Value]

spring-data-neo4j v6的参考留档仅提供了一些示例,其中传递给@Repository接口的自定义查询方法的参数与与该存储库关联的@Node类的类型相同。留档没有明确声明只允许Node类的参数。

问题

在spring-data-neo4j v6中,有没有办法像在v5中一样,将任意DTO(不是< code>@Node类)传递给< code>@Repository接口中的自定义查询方法?

示例节点实体

@Node
data class MyEntity(
    @Id
    val attr1: String,
    val attr2: String,
    val attr3: String
)

DTO示例

data class MyDTO(
    val field1: String,
    val field2: String
)

示例存储库接口

@Repository
interface MyRepository : PagingAndSortingRepository<MyEntity, String> {

    // ConverterNotFoundException is thrown when this method is called
    @Query("MATCH (e:MyEntity {attr1: {0}.field1}) " +
           "CREATE (e)-[l:LINK]->(n:OtherEntity {attr2: {0}.field2))")
    fun doSomethingWithDto(dto: MyDTO)
}

将DTO注释为Node实体

基于参考文档https://docs . spring . io/spring-data/neo4j/docs/current/reference/html/# custom-queries . parameters中的以下内容

映射实体(带有@Node的所有内容)作为参数传递给使用自定义查询注释的函数,将转换为嵌套映射。

@Node
data class MyDTO(
    @Id
    val field1: String,
    val field2: String
)

在自定义查询中将{0}替换为$0

基于参考文档https://docs . spring . io/spring-data/neo4j/docs/current/reference/html/# custom-queries . parameters中的以下内容

您执行此操作的方式与在Neo4j浏览器或Cypher-Shell中发出的标准Cypher查询中使用$语法的方式完全相同(从Neo4j 4.0起,Cypher参数的旧{foo}语法已从html" target="_blank">数据库中删除)。

...

[在给出的清单中],我们通过参数的名称来引用参数。您也可以使用$0等。

@Repository
interface MyRepository : PagingAndSortingRepository<MyEntity, String> {
    
    // ConverterNotFoundException is thrown when this method is called
    @Query("MATCH (e:MyEntity {attr1: $0.field1}) " +
           "CREATE (e)-[l:LINK]->(n:OtherEntity {attr2: $0.field2))")
    fun doSomethingWithDto(dto: MyDTO)
}
  • spring-boot-starterv2.4.10
  • spring-data-neo4jv6.0.12
  • neo4j-java驱动程序v4.1.4
  • Neo4j服务器版v3.5.29

共有2个答案

澹台俊晖
2023-03-14

这个框架会强迫你为此编写一个自定义转换器,这太荒谬了。我在覆盖的用户类中为一组有限的可更新用户配置文件字段创建了一个@瞬态对象,我遇到了同样的错误。我想我只能将对象分解为方法参数中的组件字符串字段来解决这个问题。真是一团糟。

@Query("MATCH (u:User) WHERE u.username = :#{#username} SET u.firstName = :#{#up.firstName},u.lastName = :#{#up.firstName},u.intro = :#{#up.intro} RETURN u")
Mono<User> update(@Param("username") String username,@Param("up") UserProfile up);

找不到能够从类型[...UserProfile]输入[org.neo4j.driver.Value]

白哲茂
2023-03-14

RTFM自定义转换。。。

自己找到了解决方案。希望其他人也能从中受益。

创建自定义转换器

import mypackage.model.*
import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import org.neo4j.driver.Value
import org.neo4j.driver.Values
import org.springframework.core.convert.TypeDescriptor
import org.springframework.core.convert.converter.GenericConverter
import org.springframework.core.convert.converter.GenericConverter.ConvertiblePair
import java.util.HashSet

class DtoToNeo4jValueConverter : GenericConverter {
    override fun getConvertibleTypes(): Set<ConvertiblePair>? {
        val convertiblePairs: MutableSet<ConvertiblePair> = HashSet()
        convertiblePairs.add(ConvertiblePair(MyDTO::class.java, Value::class.java))
        return convertiblePairs
    }

    override fun convert(source: Any?, sourceType: TypeDescriptor, targetType: TypeDescriptor?): Any? {
        return if (MyDTO::class.java.isAssignableFrom(sourceType.type)) {
            // generic way of converting an object into a map
            val dataclassAsMap = jacksonObjectMapper().convertValue(source as MyDTO, object :
                    TypeReference<Map<String, Any>>() {})
            Values.value(dataclassAsMap)
        } else null
    }
}

在配置中注册自定义转换器

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.neo4j.core.convert.Neo4jConversions
import org.springframework.core.convert.converter.GenericConverter
import java.util.*


@Configuration
class MyNeo4jConfig {
    @Bean
    override fun neo4jConversions(): Neo4jConversions? {
        val additionalConverters: Set<GenericConverter?> = Collections.singleton(DtoToNeo4jValueConverter())
        return Neo4jConversions(additionalConverters)
    }
}
 类似资料:
  • 我必须运行一个本机查询来检索要插入到声明它的Jpa存储库以外的模型中的数据,当我执行函数loadValoriPreventivoUnica时,我有以下错误。我该如何解决这个问题?这是由于什么原因? 错误: [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap]键入[

  • 我有这门课: 这个问题: 但我有这个错误

  • 我知道这是另一个类似的问题,但我自己无法回答,这就是我写信给你寻求帮助的原因。 我尝试创建自己的@Query,并在两种情况下返回一个转换错误。我的猜测是服务有问题,但这是我的知识结束。 下面是我的代码: > 主实体 2.第二种模式 3.第三种模式 存储库 @Repository public interface UserRepository extends jparepository { } 服务

  • 我们有一个使用带有Postgres数据库的Spring boot1.3运行的应用程序。自定义用户类型是为数据库中的Json类型定义的。遵循并实现UserType以使用ObjectMapper返回Pojo。它工作得非常好。但是现在使用Spring boot1.4,我们得到了这个异常。 自定义用户类型中的代码片段。 我可以看到,找到了来自数据库的响应,objectmapper也对其进行了转换。返回时抛

  • 我将spring与JPA一起使用,并尝试使用@query与SQL query一起执行查询,并尝试将结果映射到一个对象。我有不同的实体类和映射到其他dto,因为我不想要所有的列。获取以下错误 如何解决上述问题。 如果问题无法解决,那么我们可以使用spring data JPA在不使用@Query的情况下解决问题吗?怎么做? 使用JPQL::编辑:: 获取以下错误