I get "detached entity passed to persist", but I do not understand, how the object in question can be in a detached state.
Here is some context first.
two JpaRepository
s for each users and roles:
@Repository
interface RoleRepository : JpaRepository<UserRole, Long> {
fun findByName(name: String): UserRole?
}
@Repository
interface BackendUserRepository : JpaRepository<BackendUser, Long> {
fun findByUserName(name: String): BackendUser?
}
The BackendUser
entity - besides the name - has several fields that should not be related to this question, the foreign field role comes from its base class:
abstract class User(
@ManyToOne(fetch = FetchType.LAZY, cascade = arrayOf(CascadeType.ALL), optional = false)
@JoinColumn(referencedColumnName = "name", nullable = false)
var role: UserRole
) : UserDetails {
// ...
}
On application startup, I want to ensure that an admin user exists in this 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)
}
}
}
The application throws an exception on startup and shuts down:
org.hibernate.PersistentObjectException: detached entity passed to persist: my.package.name.user.UserRole
The way I understand it here is, that adminRole
is in a detached state straight after it was retrieved from the repository.
- Why is it detached? I had assumed the @Transactional annotation on the method would make sure everything happens within the same persistence context, and this should not happen.
- How can I prevent this? Is there a way without having to remove the cascaed option
- Is there any good information source on how spring/jpa and hibernate play to gether - so far anything i found didn't really help me understand the concepts in detail, and how the respositoryies appear to hide the entity management and session concepts that you find, when trying to read up on hibernate.