Hibernate 使用@ManyToMany时堆栈溢出错误
在尝试了几个小时并在谷歌上搜索了一个类似的问题之后,我仍然无法解决这个问题: 我正在构建一个sprint引导应用程序(在Kotlin中),它使用JPA(也使用hibernate)和H2(我认为这不相关)。我想在类用户和成就之间建立一个多对多关系模型(这样一个用户可以有多个成就,一个成就可以由多个用户实现)。以下是模型类:Hibernate 使用@ManyToMany时堆栈溢出错误,hibernate,spring-boot,jpa,kotlin,h2,Hibernate,Spring Boot,Jpa,Kotlin,H2,在尝试了几个小时并在谷歌上搜索了一个类似的问题之后,我仍然无法解决这个问题: 我正在构建一个sprint引导应用程序(在Kotlin中),它使用JPA(也使用hibernate)和H2(我认为这不相关)。我想在类用户和成就之间建立一个多对多关系模型(这样一个用户可以有多个成就,一个成就可以由多个用户实现)。以下是模型类: @Entity data class User( @Id @GeneratedValue(strategy = GenerationType.
@Entity
data class User(
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
val id: Int = 0,
@Column(nullable = false)
val name: String,
@ManyToMany(cascade = [ CascadeType.PERSIST, CascadeType.MERGE ])
val achievements: MutableSet<Achievement> = HashSet()
)
然后,我在@Service@事务中预填充数据,如下所示:
val achievement = Achievement(key = "SOME_ACHIEVEMENT_KEY")
achievementRepository.save(achievement)
val user = User(name = "John Doe")
userRepository.save(user)
并添加一个关系:
val foundAchievement = achievementRepository.findById(achievementId)
val foundUser = userRepository.findById(userId)
foundAchievement.ifPresent { achievement ->
foundUser.ifPresent { user ->
user.achievements.add(achievement)
userRepository.save(user)
}
}
如果我现在尝试通过在以下URL之一上执行GET来访问数据:
http://localhost:8080/achievements/2/users
http://localhost:8080/users/3/achievements
我得到了一个java.lang.StackOverflower错误,日志显示hibernate正在一次又一次地尝试查询成就和用户(直到堆栈溢出为止的无休止循环)
下面是我的问题:
好的,问题是双向关系和Kotlin自动生成的equals()和hashCode()的组合 因为我使用的是Kotlin数据类,所以它会为主构造函数中定义的每个属性自动生成hashCode()和equals()。我从主构造函数中取出@ManyToMany注释属性,问题消失了:
@Entity
data class Achievement(
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
val id: Int = 0,
val key: String
) {
@ManyToMany(mappedBy = "achievements")
val users: MutableSet<User> = HashSet()
}
@实体
数据类成绩(
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
val id:Int=0,
val键:字符串
) {
@许多(mappedBy=“成就”)
val用户:MutableSet=HashSet()
}
@实体
数据类用户(
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
val id:Int=0,
@列(nullable=false)
val名称:String
) {
@ManyToMany(cascade=[CascadeType.PERSIST,CascadeType.MERGE])
val成就:MutableSet=HashSet()
}
http://localhost:8080/achievements/2/users
http://localhost:8080/users/3/achievements
@Entity
data class Achievement(
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
val id: Int = 0,
val key: String
) {
@ManyToMany(mappedBy = "achievements")
val users: MutableSet<User> = HashSet()
}
@Entity
data class User(
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
val id: Int = 0,
@Column(nullable = false)
val name: String
) {
@ManyToMany(cascade = [CascadeType.PERSIST, CascadeType.MERGE])
val achievements: MutableSet<Achievement> = HashSet()
}