首页 > 解决方案 > Spring data/Hibernate:传递给持久化的分离实体

问题描述

我得到“传递给持久化的分离实体”,但我不明白有问题的对象如何处于分离状态。
首先是一些上下文。

JpaRepository每个用户和角色两个:

@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在从存储库中检索到它之后立即处于分离状态。

标签: hibernatejpaspring-data-jpaspring-kotlin

解决方案


由于您在私有方法上有@Transactional,并且还从同一个类调用了一个,因此没有事务,因此没有用于保存的分离状态(请参阅this)。不确定您是否可以在 run() 或此类上应用 @Transactional。无论如何,也许您应该使用公共 @Transactional 方法创建新的“服务”类,然后从您的类中调用此服务。


推荐阅读