关系未正确反序列化
Relationship not deserialised properly
我正在使用 Spring Data Rest.
编辑数据库中的一些实体
他们都以此为基础class:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes(
JsonSubTypes.Type(value = TextComponent::class, name = TextComponent.TYPE),
JsonSubTypes.Type(value = TextAreaComponent::class, name = TextAreaComponent.TYPE)
)
abstract class AbstractLabelComponent(
@field:ManyToOne
@field:JsonIgnore
open val template: Template?,
@field:Id
@field:GeneratedValue(strategy = GenerationType.AUTO)
open var id: Long? = null
)
这是一个中间的class(我不确定它是否重要所以有总比没有好):
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
abstract class AbstractTextComponent(
template: Template?,
@field:ManyToOne(optional = false)
open var font: Font,
): AbstractLabelComponent(template)
这里是 child class。只发一个,因为他们的行为都一样。
@Entity
class TextComponent(
template: Template? = null,
font: Font,
): AbstractTextComponent(template){
companion object {
const val TYPE = "text"
}
}
这是包含组件列表的模板:
@Entity
data class Template(
@field:OneToMany(mappedBy = "template", cascade = [CascadeType.ALL], orphanRemoval = true)
var components: MutableList<AbstractLabelComponent> = mutableListOf()
@field:Id
@field:GeneratedValue(strategy = GenerationType.AUTO)
open var id: Long? = null
)
我将以下 JSON 发送到 API:
{
"components": [
{
"alignment": 0,
"content": "",
"fieldID": "TEXT",
"font": "/api/fonts/9",
"rotation": 0,
"type": "text",
"x": 84,
"y": 36
}
],
}
但是我收到这个错误:
JSON parse error: Instantiation of [simple type, class
com.components.TextComponent] value failed for JSON property font due
to missing (therefore NULL) value for creator parameter font which is
a non-nullable type
我想是因为构造函数中的字体属性不是可选的,所以我把它设为可选。但是后来我从数据库收到一个错误,说 font_id
没有默认值,所以我认为真正的问题是字体没有反序列化或传递不正确。
同样奇怪的是,如果我在数组中有字体的 URI,它会抱怨数组无法转换为字体,所以我猜它可以反序列化,但它不会将它传递给构造函数。在此之前,我将它作为字体的 JSON 但得到了与现在相同的错误,所以我认为我应该改用 URI。
这是字体 class:
@Entity
data class Font(
var humanReadable: String = "",
private val width: Int = 1,
private val height: Int = 1,
@field:Id
@field:GeneratedValue(strategy = GenerationType.AUTO)
open var id: Long? = null
)
我刚刚尝试使用另一个没有 Font
的组件,得到了我提到的相同的错误,当我的组件上的字体是可选的时:
java.sql.SQLException: Field 'bold_font_id' doesn't have a default value
这是另一个没有字体的组件:
@Entity
class CodeComponent(
template: Template? = null,
private var code: String = ""
): AbstractLabelComponent(template) {
这是具有 bold_font 的一个组件。我在复制以下错误时没有使用它:
@Entity
class TextAreaComponent(
template: Template? = null,
content: String = "",
font: Font,
@field:ManyToOne(optional = false)
var boldFont: Font
): AbstractTextComponent(template, font,content)
这里是模板实体的仓库:
@Repository
interface TemplateRepository: CrudRepository<Template, Long>{
}
在我看来,您的数据库 table 中有一个 bold_font_id
列,但我在您的模型 类 中看不到任何这样的 属性映射到这样的列。确保你有一个 属性 匹配你的数据库中的每一列 table 或者如果没有,你将必须在创建它时在你的数据库模式中分配默认值。
我正在使用 Spring Data Rest.
编辑数据库中的一些实体他们都以此为基础class:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes(
JsonSubTypes.Type(value = TextComponent::class, name = TextComponent.TYPE),
JsonSubTypes.Type(value = TextAreaComponent::class, name = TextAreaComponent.TYPE)
)
abstract class AbstractLabelComponent(
@field:ManyToOne
@field:JsonIgnore
open val template: Template?,
@field:Id
@field:GeneratedValue(strategy = GenerationType.AUTO)
open var id: Long? = null
)
这是一个中间的class(我不确定它是否重要所以有总比没有好):
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
abstract class AbstractTextComponent(
template: Template?,
@field:ManyToOne(optional = false)
open var font: Font,
): AbstractLabelComponent(template)
这里是 child class。只发一个,因为他们的行为都一样。
@Entity
class TextComponent(
template: Template? = null,
font: Font,
): AbstractTextComponent(template){
companion object {
const val TYPE = "text"
}
}
这是包含组件列表的模板:
@Entity
data class Template(
@field:OneToMany(mappedBy = "template", cascade = [CascadeType.ALL], orphanRemoval = true)
var components: MutableList<AbstractLabelComponent> = mutableListOf()
@field:Id
@field:GeneratedValue(strategy = GenerationType.AUTO)
open var id: Long? = null
)
我将以下 JSON 发送到 API:
{
"components": [
{
"alignment": 0,
"content": "",
"fieldID": "TEXT",
"font": "/api/fonts/9",
"rotation": 0,
"type": "text",
"x": 84,
"y": 36
}
],
}
但是我收到这个错误:
JSON parse error: Instantiation of [simple type, class com.components.TextComponent] value failed for JSON property font due to missing (therefore NULL) value for creator parameter font which is a non-nullable type
我想是因为构造函数中的字体属性不是可选的,所以我把它设为可选。但是后来我从数据库收到一个错误,说 font_id
没有默认值,所以我认为真正的问题是字体没有反序列化或传递不正确。
同样奇怪的是,如果我在数组中有字体的 URI,它会抱怨数组无法转换为字体,所以我猜它可以反序列化,但它不会将它传递给构造函数。在此之前,我将它作为字体的 JSON 但得到了与现在相同的错误,所以我认为我应该改用 URI。
这是字体 class:
@Entity
data class Font(
var humanReadable: String = "",
private val width: Int = 1,
private val height: Int = 1,
@field:Id
@field:GeneratedValue(strategy = GenerationType.AUTO)
open var id: Long? = null
)
我刚刚尝试使用另一个没有 Font
的组件,得到了我提到的相同的错误,当我的组件上的字体是可选的时:
java.sql.SQLException: Field 'bold_font_id' doesn't have a default value
这是另一个没有字体的组件:
@Entity
class CodeComponent(
template: Template? = null,
private var code: String = ""
): AbstractLabelComponent(template) {
这是具有 bold_font 的一个组件。我在复制以下错误时没有使用它:
@Entity
class TextAreaComponent(
template: Template? = null,
content: String = "",
font: Font,
@field:ManyToOne(optional = false)
var boldFont: Font
): AbstractTextComponent(template, font,content)
这里是模板实体的仓库:
@Repository
interface TemplateRepository: CrudRepository<Template, Long>{
}
在我看来,您的数据库 table 中有一个 bold_font_id
列,但我在您的模型 类 中看不到任何这样的 属性映射到这样的列。确保你有一个 属性 匹配你的数据库中的每一列 table 或者如果没有,你将必须在创建它时在你的数据库模式中分配默认值。