列表不为空时不调用字段 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。