Kotlin数据类没有带有Spring数据其余部分的字符串参数构造函数 [英] Kotlin data class No String-argument constructor with spring data rest

查看:108
本文介绍了Kotlin数据类没有带有Spring数据其余部分的字符串参数构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将Spring数据与Kotlin结合使用,如果我使用数据类,则通过uri的关联将停止,并出现错误no String-argument constructor/factory method to deserialize from String value

I'm using Spring data rest with Kotlin and if I use data classes the associations via uri stops working with the error 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) {
}

如果我使用简单的类,则关联可以正常工作.

If I use a simple class instead the association works fine.

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

Any ideia why I have this error when I use a data class and what can I do to use the association creation via uri and keep using data classes?

推荐答案

我做了一些调查,结果发现Spring Data Rest使用自定义的Jackson模块将JSON反序列化为JPA实体:它使用PersistentEntityJackson2Module类并使用内部类UriStringDeserializer可以从实体URI引用(在您的示例中为http://localhost:8080/post/33)解析具体实体.

I did some investigation, and turns out Spring Data Rest uses a custom Jackson module to deserialize JSON into JPA entities: it uses PersistentEntityJackson2Module class and using the inner class UriStringDeserializer to resolve the concrete entities from entity URI references, http://localhost:8080/post/33 in your example.

问题是,此自定义反序列化仅在触发Jackson的标准反序列化"时才起作用:使用空构造函数,然后使用setter解析&的程序.设置字段.此时,UriStringDeserializer会将字符串转换为具体的实体-示例的Post实例.

Problem is, this custom deserialization only kicks in when the "standard deserialization" of Jackson is triggered: The one that uses empty constructor, then using setters to resolve & set the fields. At that moment, UriStringDeserializer converts the string into the concrete entity - Post instance of your example.

当您使用数据类时,该类既没有空的构造函数,也没有设置方法,因此在Jackson的BeanDeserializer#deserializeFromObject方法中,它分支为if (_nonStandardCreation)为真,从那里调用进入BeanDeserializerBase#deserializeFromObjectUsingNonDefault,但没有移交给PersistentEntityJackson2Module,并且由于构造函数参数和json值之间的类型不匹配而直接失败.

When you use a data class, the class neither has an empty constructor nor setters, therefore in BeanDeserializer#deserializeFromObject method of Jackson, it branches into if (_nonStandardCreation) being true, from there the call goes into BeanDeserializerBase#deserializeFromObjectUsingNonDefault , but not handed over to PersistentEntityJackson2Module anymore, and directly failing due to type mismatch between the constructor argument and the json value.

似乎您需要创建功能请求才能实现.如果您决定实现自己,则可以将_delegateDeserializer提供给BeanDeserializer可能是一个开始(不确定).

It seems you need to create a feature request for it to be implemented. If you decide to implement yourself, providing a _delegateDeserializer to the BeanDeserializer might be a start (not sure).

但是,我首先不知道JPA本身如何处理数据类-毕竟它跟踪实体状态变化,但是数据类不能具有状态变化.因此,可能根本无法使用数据类-最好记住这一点.

However, I don't know how JPA itself plays with data classes in the first place - after all it tracks the entity state changes, but a data class cannot have state changes. So, it might not be possible to use data classes after all - better to keep in mind.

注意:您可能不能简单地扩展/覆盖PersistentEntityJackson2Module,因为它已在RepositoryRestMvcConfiguration

Note: You probably cannot simply extend/override PersistentEntityJackson2Module because it is registered to multiple beans in RepositoryRestMvcConfiguration

这篇关于Kotlin数据类没有带有Spring数据其余部分的字符串参数构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆