#json #spring #kotlin #spring-data-rest
#json #весна #котлин #пружина-данные-отдых
Вопрос:
У меня есть некоторые сущности в базе данных, которые я редактирую с помощью Spring Data Rest.
Все они имеют это в качестве базового класса:
@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 )
Вот средний класс (я не уверен, важно ли это, поэтому лучше иметь его, чем нет):
@Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) abstract class AbstractTextComponent( template: Template?, @field:ManyToOne(optional = false) open var font: Font, ): AbstractLabelComponent(template)
А вот и детский класс. Публикую только один, потому что все они ведут себя одинаково.
@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: MutableListlt;AbstractLabelComponentgt; = 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 } ], }
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 )
Я только что попробовал с другим компонентом, у которого нет 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: CrudRepositorylt;Template, Longgt;{ }
Комментарии:
1. Не могли бы вы, пожалуйста, добавить код для
Template
иFont
классов? Спасибо!2. Добавлено
Font
.Template
уже есть
Ответ №1:
Мне кажется, что у вас есть bold_font_id
столбец в таблице базы данных, но я не вижу такого свойства в ваших классах моделей, которое сопоставляется с таким столбцом. Убедитесь, что у вас есть свойство, соответствующее каждому столбцу в таблице базы данных, или, если нет, вам придется назначить значения по умолчанию в схеме базы данных при ее создании.
Комментарии:
1. Я проверил, что ни в суперклассе, ни в базовых классах, которые я скопировал здесь, нет поля bold_font_id. Однако есть один на другом компоненте, который я даже не тестировал раньше. Добавление класса к вопросу сейчас
2. Тогда в этом-то и проблема. Если вы попытаетесь сохранить объект, у которого нет
boldFont
свойства, вы получите сообщение об ошибке. Вы пробовали сTextAreaComponent
?3. Я этого не понимаю. У меня есть несколько типов компонентов, все они имеют свойство типа в json, и эти типы перечислены как JsonSubType в базовом классе. Наследование устанавливается в таблицу для каждого класса. Один из этих типов имеет жирный шрифт. У этого есть идентификатор полужирного шрифта в таблице. Остальное-нет.
4. Разве он неправильно распознает подтипы и пытается десериализовать компонент неправильного типа?
5. Не могли бы вы , пожалуйста, добавить соответствующие
Controller
Service
иRepository
классы к вашему вопросу? Спасибо!