我有以下数据类:
@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对象然后持久化时,我得到一个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 行发表评论,以使上述代码正常运行。
为什么设置双向关系会导致此错误?
答案 0 :(得分:3)
我实际上设法解决了这个问题 - 我所要做的只是在至少一个实体中覆盖 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)"
}
}