Kotlin数据类没有带有弹簧数据的字符串参数构造函数

时间:2018-05-06 22:28:03

标签: spring-boot kotlin spring-data-rest

我正在使用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使用关联创建并继续使用数据类?

1 个答案:

答案 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

中的多个bean