我正在使用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使用关联创建并继续使用数据类?
答案 0 :(得分:3)
我做了一些调查,结果发现Spring Data Rest使用自定义Jackson模块将JSON反序列化为JPA实体:它使用PersistentEntityJackson2Module
类并使用内部类UriStringDeserializer
来解析具体实体实例URI引用,示例中为http://localhost:8080/post/33
。
问题是,这个自定义反序列化仅在Jackson的“标准反序列化”被触发时启动:使用空构造函数,然后使用setter解析&设置字段。在那一刻,UriStringDeserializer
将字符串转换为具体实体 - 您的示例的Post
实例。
当你使用数据类时,该类既没有空构造函数也没有setter,因此在Jackson的BeanDeserializer#deserializeFromObject
方法中,它分支为if (_nonStandardCreation)
为真,从那里调用进入{{ 1}},但不再移交给BeanDeserializerBase#deserializeFromObjectUsingNonDefault
,并且由于构造函数参数和json值之间的类型不匹配而直接失败。
您似乎需要创建要实现的功能请求。如果您决定自己实现,那么向BeanDeserializer提供PersistentEntityJackson2Module
可能是一个开始(不确定)。
但是,我不知道JPA本身如何首先使用数据类 - 毕竟它跟踪实体状态更改,但数据类不能进行状态更改。因此,最终可能无法使用数据类 - 最好记住。
注意:您可能无法简单地扩展/覆盖_delegateDeserializer
,因为它已注册到PersistentEntityJackson2Module