Home > Net >  Relationship not deserialised properly
Relationship not deserialised properly

Time:12-06

I have a some entities in the database that I'm editing with Spring Data Rest.

All of them have this as a base 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
)

Here is a middle class (I'm not sure if it is important so better have it than not):

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
abstract class AbstractTextComponent(
    template: Template?,

    @field:ManyToOne(optional = false)
    open var font: Font,

): AbstractLabelComponent(template)

And here is a child class. Posting only one because all of them behave the same way.

@Entity
class TextComponent(
    template: Template? = null,
    font: Font,
): AbstractTextComponent(template){
  companion object {
    const val TYPE = "text"
  }
}

And here is the template that has a list of components:

@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
)

I'm sending the following JSON to the API:

{

    "components": [
        {
            "alignment": 0,
            "content": "",
            "fieldID": "TEXT",
            "font": "/api/fonts/9",
            "rotation": 0,
            "type": "text",
            "x": 84,
            "y": 36
        }
    ],
}

But I'm getting this error:

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

I figured it is because the font property in the constructor is not optional, so I made it optional. But then I received an error from the DB that font_id has no default value, so I think the real problem is that the font is not deserialized or passed properly.

Also weird that if I have the URI to the font in an array it complains that arrays can not be converted to Font, so I guess it can deserialize but it does not pass it to the constructor. Before that, I had it as a JSON of the Font but got the same error as now so I thought I should use URIs instead.

Here is the Font 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
)

I just tried with an other component that has no Font and got the same error that I mentioned that I get when the font is optional on my components:

java.sql.SQLException: Field 'bold_font_id' doesn't have a default value

Here is the other component that has no font:

@Entity
class CodeComponent(
    template: Template? = null,
    private var code: String = ""
): AbstractLabelComponent(template) {

Here is that one component that has bold_font. I wasn't using this while I copied the errors below:

@Entity
class TextAreaComponent(
    template: Template? = null,
    content: String = "",
    font: Font,
    @field:ManyToOne(optional = false)
    var boldFont: Font

): AbstractTextComponent(template, font,content)

Here is the repository of the template entity:

@Repository
interface TemplateRepository: CrudRepository<Template, Long>{

}

CodePudding user response:

It seems to me that you have a bold_font_id column in your database table, but I can't see any such property in your model classes that map to such a column. Make sure you have a property matching every column in your database table or if not, you will have to assign default values in your database schema while creating it.

  • Related