Я получаю «отдельный объект передан для сохранения», но я не понимаю, как рассматриваемый объект может быть в отсоединенном состоянии. Вот сначала некоторый контекст.
два JpaRepository
s для каждого пользователя и роли:
@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 и спящий режим взаимодействуют вместе - до сих пор все, что я нашел, действительно не помогло мне подробно понять концепции , и как кажется, что репозитории скрывают концепции управления сущностями и сеанса, которые вы обнаруживаете при попытке чтения в спящем режиме.