列表不为空时不调用字段 setter
Field setter not called when list is not empty
我有一个 parent 实体,其中包含 child 个实体的列表。我正在使用 Spring Data Rest
,所以没有自定义控制器。
这些是我的实体:
@Entity
class Template(
childComponents: MutableList<AbstractLabelComponent> = mutableListOf(),
){
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
var id: Long? = null
@JsonManagedReference
@OneToMany(mappedBy = "template", cascade = [CascadeType.ALL], orphanRemoval = true)
private var components: MutableList<AbstractLabelComponent> = childComponents
set(value){
field.clear()
field.addAll(value)
field.forEach { it.template = this }
}
fun addComponent(component: AbstractLabelComponent){
component.template = this
this.components.add(component)
}
}
和 child 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),
JsonSubTypes.Type(value = ImageComponent::class, name = ImageComponent.TYPE)
)
abstract class AbstractLabelComponent(
@field:ManyToOne
@field:JsonBackReference
@field:JoinColumn(name="template_id")
open var template: Template?
){
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
open var id: Long? = null
}
这是我要发布到 API:
的 json
{
"components": [
{
"id": 2300,
},
{
"id": 2302,
}
],
"id": 1789
}
我省略了一些简单的字段以使其更具可读性。我没有组件存储库,模板存储库除了扩展基本的 crud 存储库之外没有其他代码。
起初,创建 child 组件没有任何问题,但未设置 template_id
字段。这就是为什么我为 components
字段创建 setter 来设置模板。当我将组件添加到没有组件的模板时,这很好用,但是我注意到,当我尝试添加更多组件时,它们最终又没有模板 ID。
我在 setter 中添加了一个断点,结果并没有调用它。我想可能是因为如果列表不为空,则 JPA 不会设置列表,而是向其中添加元素。我对吗?如果是这样,有没有办法告诉它改用 addComponent 方法以便我可以设置模板?或者任何其他方式来确保设置对模板的引用?
事实证明,这两种情况的区别不在于数据库中存在的组件数量,而在于实体是否有任何变化。不确定,但如果没有更改,JPA 似乎不会保留实体,并且可能也不会费心设置此类关系。可能有更好的解决方案,但解决方法是如果实体不是新实体,则从前端在 JSON 中设置模板 ID。
我有一个 parent 实体,其中包含 child 个实体的列表。我正在使用 Spring Data Rest
,所以没有自定义控制器。
这些是我的实体:
@Entity
class Template(
childComponents: MutableList<AbstractLabelComponent> = mutableListOf(),
){
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
var id: Long? = null
@JsonManagedReference
@OneToMany(mappedBy = "template", cascade = [CascadeType.ALL], orphanRemoval = true)
private var components: MutableList<AbstractLabelComponent> = childComponents
set(value){
field.clear()
field.addAll(value)
field.forEach { it.template = this }
}
fun addComponent(component: AbstractLabelComponent){
component.template = this
this.components.add(component)
}
}
和 child 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),
JsonSubTypes.Type(value = ImageComponent::class, name = ImageComponent.TYPE)
)
abstract class AbstractLabelComponent(
@field:ManyToOne
@field:JsonBackReference
@field:JoinColumn(name="template_id")
open var template: Template?
){
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
open var id: Long? = null
}
这是我要发布到 API:
的 json{
"components": [
{
"id": 2300,
},
{
"id": 2302,
}
],
"id": 1789
}
我省略了一些简单的字段以使其更具可读性。我没有组件存储库,模板存储库除了扩展基本的 crud 存储库之外没有其他代码。
起初,创建 child 组件没有任何问题,但未设置 template_id
字段。这就是为什么我为 components
字段创建 setter 来设置模板。当我将组件添加到没有组件的模板时,这很好用,但是我注意到,当我尝试添加更多组件时,它们最终又没有模板 ID。
我在 setter 中添加了一个断点,结果并没有调用它。我想可能是因为如果列表不为空,则 JPA 不会设置列表,而是向其中添加元素。我对吗?如果是这样,有没有办法告诉它改用 addComponent 方法以便我可以设置模板?或者任何其他方式来确保设置对模板的引用?
事实证明,这两种情况的区别不在于数据库中存在的组件数量,而在于实体是否有任何变化。不确定,但如果没有更改,JPA 似乎不会保留实体,并且可能也不会费心设置此类关系。可能有更好的解决方案,但解决方法是如果实体不是新实体,则从前端在 JSON 中设置模板 ID。