Kotlin 中 JPA 双向引用的 StackOverflowError

问题描述 投票:0回答:2

我的数据类如下:

@Entity
@Table(name = "SECTIONS")
data class Section(

        @Id @GeneratedValue
        @Column(name = "ID")
        var id: Long = 0,

        @Column(name = "NAME")
        var name: String = "",

        @OneToMany(
                mappedBy = "section",
                fetch = FetchType.EAGER,
                cascade = arrayOf(CascadeType.ALL),
                orphanRemoval = true
        )
        var fields: MutableList<Field> = mutableListOf()
)

@Entity
@Table(name = "FIELDS")
data class Field(

        @Id @GeneratedValue
        @Column(name = "ID")
        var id: Long = 0,

        @Column(name = "NAME")
        var name: String = "",

        @ManyToOne
        @JoinColumn(name = "SECTION_ID")
        var section: Section? = null
)

可以看到,Section 和 Field 之间存在双向映射。当我创建一个Section对象、一个Field对象并将Field对象添加到Section对象的字段列表中时,它工作得很好。但是,当我还将 Field 的section引用设置为Section对象然后保留时,我得到了一个StackOverflowError:

@Test
fun testCascadeSaving() {
    val section = Section(name = "Section 1")
    val field = Field(name = "Field 1")

    section.fields.add(field)
    field.section = section

    val savedSection = sectionRepository.save(section)
    val savedField = savedSection.fields[0]

    // This causes an StackOverflowError
    val f = fieldRepository.findOne(savedField.id)
}

我必须注释 field.section =section 行才能使上面的代码正常工作。

有什么想法为什么设置双向关系会导致此错误吗?

java jpa kotlin stack-overflow bidirectional
2个回答
9
投票

我实际上已经成功解决了这个问题 - 我所要做的就是重写至少一个实体中的 toString() 方法。 Kotlin 提供的实现包括递归调用彼此的 toString() 方法,从而导致 StackOverflowError

@Entity
@Table(name = "FIELDS")
data class Field(

        @Id @GeneratedValue
        @Column(name = "ID")
        var id: Long = 0,

        @Column(name = "NAME")
        var name: String = "",

        @ManyToOne
        @JoinColumn(name = "SECTION_ID")
        var section: Section? = null
) {
    override fun toString(): String {
        return "Field(id=$id, name=$name)"
    }
}

0
投票

我偶然发现了同样的问题。从昨天开始就一直在寻找解决方案。谢谢你救了我。

我问你的问题是你是怎么发现Kotlin提供的实现包含递归调用对方的toString()方法的。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.