关系未正确反序列化

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 或者如果没有,你将必须在创建它时在你的数据库模式中分配默认值。