我按照教程http://www.baeldung.com/spring-data-rest-relationships进行了操作。 我还观察到我可以通过提供关系链接直接创建关联。
curl -i -X POST -H "Content-Type:application/json" -d '{"name":"My Library"}' http://localhost:8080/libraries
curl -i -X POST -d '{"title":"Books", "library":"http://localhost:8080/libraries/1"}' -H "Content-Type:application/json" http://localhost:8080/books
使用常规类时,这在Java和Kotlin中都可以正常工作。
但是,如果我在Kotlin中使用数据类,则会出现以下错误
2018-04-26 14:13:43.730 ERROR 79256 --- [nio-8080-exec-2] behRestResponseEntityExceptionHandler:org.springframework.http.converter.HttpMessageNotReadableException:JSON解析错误:无法构造com的实例。 baeldung.models.Library(尽管至少存在一个Creator):没有String-argument构造函数/工厂方法从String值反序列化('http://localhost:8080/libraries/1');嵌套异常是com.fasterxml.jackson.databind.exc.MismatchedInputException:无法构造com.baeldung.models.Library的实例(尽管至少存在一个Creator):没有String-argument构造函数/工厂方法从String值反序列化(' http://localhost:8080/libraries/1')在[来源:(org.apache.catalina.connector.CoyoteInputStream); line:1,column:29](通过引用链:com.baeldung.models.Book [“library”])
我的项目中有相关的kotlin-spring,kotlin-jpa和kotlin-noarg插件。
答案 0 :(得分:2)
尝试在主要构造函数上添加@JsonCreator(mode = JsonCreator.Mode.DISABLED)
批注。无需禁用com.fasterxml.jackson.module:jackson-module-kotlin
。
说明:
KotlinValueInstantiator
类)。可能的解决方案:
由于koltin-jpa模块为JPA添加了默认的空构造函数,因此可以通过显式禁用它来指示Jackson不使用JSON创建器,而是指示默认的空构造函数。
示例:
@Entity
class Book @JsonCreator(mode = JsonCreator.Mode.DISABLED) constructor(
@ManyToMany
val libraries: ModifiableList<Library> = ArrayList(),
): AbstractPersistable<Long>(), Identifiable<Long>
答案 1 :(得分:0)
Kotlin数据类非常严格。它告诉你,基本上,它不能构建你的POKO,它列出了它尝试的一些方法。其中一个是String构造函数。其他人则通过私人现场操纵(这是它正常运作的方式)。
kotlin中的数据类,如果它们具有声明为private val name:String
的字段,则转换为(在java中)private final String name;
它不能分配给final
字段(这是很脏的尝试分配到私有字段,但是当它是最终的时候是不可能的; JVM不会允许它,并且没有getName()
或setName()
函数可以用作另一个水合方法。
一些选项:
var
而不是val
。 private var name:String
是与private String name
等价的java,它将使用基于字段的(脏)水合作用。compile("com.fasterxml.jackson.module:jackson-module-kotlin")
查看this project 示例kotlin类应该适合您:
import org.springframework.hateoas.Identifiable
import java.time.LocalDate
import javax.persistence.*
import javax.validation.constraints.*
@Entity
data class Employee(@Pattern(regexp = "[A-Za-z0-9]+")
@Size(min = 6, max = 32)
val name: String,
@Email
@NotNull
val email: String?,
@PastOrPresent
val hireDate: LocalDate = LocalDate.now(),
@OneToMany(mappedBy = "employee", cascade = [CascadeType.ALL])
val forms:List<Form> = listOf(),
@OneToMany(mappedBy = "employee", cascade = [CascadeType.ALL])
val reports:List<Report> = listOf(),
@Id @GeneratedValue( strategy = GenerationType.IDENTITY) private val id: Long? = null): Identifiable<Long> {
override fun getId() = id
constructor(name:String): this(name,"$name@foo.com")
}
答案 2 :(得分:0)
与科特琳都很好。
只需将“数据类”替换为“类”。
Jackson在“数据类”中找不到空的构造函数。并使用其他反序列化器...而不是Uri ...