Java 使用Spring Boot JPA反序列化JSON类Kotlin时出现问题
我对Spring Boot JPA和Kotlin的Rest API有问题。每次尝试使用POST端点插入新记录时都会引发错误 出现的错误日志: JSON分析错误:无法构造Java 使用Spring Boot JPA反序列化JSON类Kotlin时出现问题,java,spring,spring-boot,kotlin,Java,Spring,Spring Boot,Kotlin,我对Spring Boot JPA和Kotlin的Rest API有问题。每次尝试使用POST端点插入新记录时都会引发错误 出现的错误日志: JSON分析错误:无法构造com.lp3bmobi.paintcar\u workshop\u api.model.VehicleType(尽管至少存在一个创建者):没有int/int参数构造函数/工厂方法从数值(3)反序列化 车辆类型类别 @Entity @Table(name="vehicle_types") @EntityList
com.lp3bmobi.paintcar\u workshop\u api.model.VehicleType
(尽管至少存在一个创建者):没有int/int参数构造函数/工厂方法从数值(3)反序列化
车辆类型类别
@Entity
@Table(name="vehicle_types")
@EntityListeners(AuditingEntityListener::class)
@JsonDeserialize
data class VehicleType (
@NotBlank
@Column(name = "type_name")
var typeName: String ?= null
//@JsonProperty("typeName") var typeName: String ?= null
) {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
var id: Long ?= null
//@JsonProperty("id") var id: Long = 0
constructor(id: Long, typeName: String?): this(typeName) {
this.id = id
}
// @JsonCreator constructor(id: Long, typeName: String?): this(typeName) {
// this.id = id
// }
}
@Entity
@Table(name="vehicles")
@EntityListeners(AuditingEntityListener::class)
data class Vehicle (
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
var id: Long ?= null,
@NotBlank
@Column(name = "model_name")
var modelName: String ?= null,
@NotBlank
@Column(name = "year")
var year: Int ?= null,
@NotBlank
@Column(name = "brand_id")
var brand: Int ?= null,
@NotBlank
@Column(name = "description")
var description: String ?= null,
@NotBlank
@Column(name = "approved")
var approved: Boolean ?= null,
@OneToOne(fetch = FetchType.LAZY) //cascade = arrayOf(CascadeType.ALL)
@JoinColumn(name = "vehicle_type_id", referencedColumnName = "id")
var vehicleType: VehicleType,
//@JsonProperty("vehicleType") var vehicleType: VehicleType ?= null,
)
车辆类别
@Entity
@Table(name="vehicle_types")
@EntityListeners(AuditingEntityListener::class)
@JsonDeserialize
data class VehicleType (
@NotBlank
@Column(name = "type_name")
var typeName: String ?= null
//@JsonProperty("typeName") var typeName: String ?= null
) {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
var id: Long ?= null
//@JsonProperty("id") var id: Long = 0
constructor(id: Long, typeName: String?): this(typeName) {
this.id = id
}
// @JsonCreator constructor(id: Long, typeName: String?): this(typeName) {
// this.id = id
// }
}
@Entity
@Table(name="vehicles")
@EntityListeners(AuditingEntityListener::class)
data class Vehicle (
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
var id: Long ?= null,
@NotBlank
@Column(name = "model_name")
var modelName: String ?= null,
@NotBlank
@Column(name = "year")
var year: Int ?= null,
@NotBlank
@Column(name = "brand_id")
var brand: Int ?= null,
@NotBlank
@Column(name = "description")
var description: String ?= null,
@NotBlank
@Column(name = "approved")
var approved: Boolean ?= null,
@OneToOne(fetch = FetchType.LAZY) //cascade = arrayOf(CascadeType.ALL)
@JoinColumn(name = "vehicle_type_id", referencedColumnName = "id")
var vehicleType: VehicleType,
//@JsonProperty("vehicleType") var vehicleType: VehicleType ?= null,
)
车辆控制器
@PostMapping("/vehicle/new")
fun createVehicle(@RequestBody vehicle: Vehicle): ResponseEntity<Vehicle?>? { //EntityModel<Vehicle>
try {
val _vehicle: Vehicle = vehicleRepository
//.save(Vehicle(vehicle.content))
//.save(Vehicle(0, vehicle.modelName, vehicle.year, vehicle.brand,
// vehicle.description, false, vehicle.vehicleType))
.save(vehicle)
return ResponseEntity<Vehicle?>(_vehicle, HttpStatus.CREATED)
} catch (e: java.lang.Exception) {
return ResponseEntity<Vehicle?>(null, HttpStatus.INTERNAL_SERVER_ERROR)
}
}
@PostMapping(“/vehicle/new”)
fun createVehicle(@RequestBody vehicle:vehicle):响应?{//EntityModel
试一试{
val_车辆:车辆=车辆存储库
//.保存(车辆(车辆内容))
//.保存(车辆(0,车辆.modelName,车辆.year,车辆.brand,
//车辆.说明,错误,车辆.车辆类型)
.拯救(车辆)
返回响应性(_车辆,HttpStatus.CREATED)
}catch(e:java.lang.Exception){
返回响应属性(null,HttpStatus.INTERNAL\u SERVER\u错误)
}
}
错误消息似乎是说Spring找不到使用单个Int参数的VehicleType
的构造函数,所以最明显的是给它一个
您可以通过添加另一个辅助构造函数来实现这一点:
constructor(id: Int): this(null) {
this.id = id.toLong()
}
(免责声明:我自己没有试过……请让我们知道它是否有效!)
如果现有的次要参数采用Int而不是Long,那么另一个选项是为其其他参数提供默认值(在这种情况下,您还需要添加注释,以确保它在字节码中生成额外的构造函数)
我不知道当属性被定义为Long时,为什么要尝试使用Int;也许这与
referencedColumnName=“id”
列有关?在任何情况下,Kotlin在long和int(以及其他数字类型)之间的差异方面都比Java或C等语言严格一些。作为一种风格,String?=null
等都令人困惑! Kotlin没有?=
运算符。 我花了不少时间才弄明白那只是String?=null
,即类型为nullable String的参数,默认为null。 令人惊讶的是,即使编译器不在乎,间距也能给人类带来多大的不同……删除构造函数。它需要一个零参数构造函数,它使用反射填充该构造函数以将json转换为对象。当您将一个值设置为默认值时,就像将它们设置为null一样,实际上在koltin中会得到n+1个构造函数。如果您需要创建零参数构造函数。另外,作为补充说明,最好创建非实体的单独请求或响应类(尽管有不同意见),以便明确决定接收/发送哪些字段。例如:通过接受一个id并使用JPAs save方法,很容易覆盖其他人的数据。即使按照您的建议,添加带有参数int的二级构造函数,同样的错误仍会继续