我在 Kotlin 中使用 Spring 数据休息,如果我使用数据类,则通过 uri 的关联停止工作,出现错误 no String-argument constructor/factory method to deserialize from String value
数据类
@Entity
data class Comment(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long = 0,
var author: String? = null,
var content: String? = null,
@ManyToOne
var post: Post? = null) {
}
如果我使用一个简单的类,而不是关联工作正常。
@Entity
class Comment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) var id: Long = 0
var author: String? = null
var content: String? = null
@ManyToOne
var post: Post? = null
}
关联是通过 POST 请求
{"author":"John Doe","content":"Dummy Content", "post":"http://localhost:8080/post/33"}
完成的。知道为什么我在使用数据类时会出现此错误,我该怎么做才能通过 uri 使用关联创建并继续使用数据类?
最佳答案
我做了一些调查,结果发现 Spring Data Rest 使用自定义 Jackson 模块将 JSON 反序列化为 JPA 实体:它使用 PersistentEntityJackson2Module
类和使用内部类UriStringDeserializer
从实体 URI 引用中解析具体实体,http://localhost:8080/post/33
在你的例子中。
问题是,这种自定义反序列化仅在触发 Jackson 的“标准反序列化”时才开始:使用空构造函数,然后使用 setter 解析和设置字段。那一刻,UriStringDeserializer
将字符串转换为具体实体 - Post
你的例子的例子。
当您使用数据类时,该类既没有空构造函数也没有 setter ,因此在 BeanDeserializer#deserializeFromObject
jackson 的方法,它分支成if (_nonStandardCreation)
是真的,从那里电话进入BeanDeserializerBase#deserializeFromObjectUsingNonDefault
,但未移交给PersistentEntityJackson2Module
不再,并且由于构造函数参数和 json 值之间的类型不匹配而直接失败。
看来您需要创建一个功能请求才能实现它。如果您决定自己实现,请提供 _delegateDeserializer
到 BeanDeserializer 可能是一个开始(不确定)。
但是,我首先不知道 JPA 本身如何处理数据类 - 毕竟它跟踪实体状态更改,但数据类不能有状态更改。因此,毕竟可能无法使用数据类 - 最好记住。
注:您可能不能简单地扩展/覆盖 PersistentEntityJackson2Module
因为它在 RepositoryRestMvcConfiguration
中注册到多个 bean
关于spring-boot - Kotlin 数据类 No String-argument constructor with spring data rest,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50205092/