【发布时间】:2020-11-02 13:09:58
【问题描述】:
我得到“传递给持久化的分离实体”,但我不明白,有问题的对象如何处于分离状态。
首先是一些上下文。
每个用户和角色有两个JpaRepositorys:
@Repository
interface RoleRepository : JpaRepository<UserRole, Long> {
fun findByName(name: String): UserRole?
}
@Repository
interface BackendUserRepository : JpaRepository<BackendUser, Long> {
fun findByUserName(name: String): BackendUser?
}
BackendUser 实体 - 除了名称之外 - 有几个字段不应与此问题相关,外部字段角色来自其基类:
abstract class User(
@ManyToOne(fetch = FetchType.LAZY, cascade = arrayOf(CascadeType.ALL), optional = false)
@JoinColumn(referencedColumnName = "name", nullable = false)
var role: UserRole
) : UserDetails {
// ...
}
在应用程序启动时,我想确保此 ApplicationRunner 中存在管理员用户:
@Component
class InitialDataApplicationRunner : ApplicationRunner {
@Autowired
lateinit var roles: RoleRepository
@Autowired
lateinit var users: BackendUserRepository
override fun run(args: ApplicationArguments) {
// some other stuff
createAdminUser()
}
@Transactional
private fun createAdminUser() {
if (users.findByUserName("admin") == null) {
val adminRole = roles.findByName("admin")!!
val adminUser = BackendUser("admin", adminRole
// some more data here
)
users.save(adminUser)
}
}
}
应用程序在启动时抛出异常并关闭:
org.hibernate.PersistentObjectException:分离的实体传递给 坚持:my.package.name.user.UserRole
我在这里的理解是,adminRole 在从存储库中检索后立即处于分离状态。
- 为什么要分离?我曾假设该方法上的 @Transactional 注释会确保所有事情都发生在同一个持久性上下文中,而这不应该发生。
- 如何防止这种情况发生?有没有办法不用去掉级联选项
- 是否有任何关于 spring/jpa 和 hibernate 如何协同工作的良好信息源 - 到目前为止,我发现的任何东西都不能真正帮助我详细理解这些概念,以及存储库如何隐藏实体管理和会话概念您在尝试阅读 hibernate 时会发现。
【问题讨论】:
标签: hibernate jpa spring-data-jpa spring-kotlin