【问题标题】:StackOverflowError with JPA bidirectional references in KotlinKotlin 中带有 JPA 双向引用的 StackOverflowError
【发布时间】:2017-11-05 22:41:16
【问题描述】:

我有如下数据类:

@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 对象的字段列表中时,它工作正常。但是,当我还将字段的部分引用设置为 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


    【解决方案1】:

    我实际上已经设法解决了这个问题——我所要做的就是在至少一个实体中覆盖 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)"
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-04-11
      • 2012-03-07
      • 1970-01-01
      • 1970-01-01
      • 2010-12-01
      • 2016-08-01
      • 2019-07-29
      • 2021-05-26
      • 1970-01-01
      相关资源
      最近更新 更多