Java 初始化期间不为null的Bean属性在@Transactional方法调用期间变为null
我遇到了一个问题,在调用Java 初始化期间不为null的Bean属性在@Transactional方法调用期间变为null,java,spring,spring-boot,kotlin,Java,Spring,Spring Boot,Kotlin,我遇到了一个问题,在调用@Transactional方法期间,bean的属性变为null UserService是在@Configuration类中声明的bean userRepository和passwordService在初始化期间不为空(afterPropertiesSet) 在调用registerUser(即@Transactional)期间,这些属性将变为null 这些属性具有不可为空的类型 基于打印使用了UserService的相同实例/bean 删除@Transactional似
@Transactional
方法期间,bean的属性变为null
是在UserService
类中声明的bean@Configuration
和userRepository
在初始化期间不为空passwordService
(afterPropertiesSet)
- 在调用registerUser(即
)期间,这些属性将变为null@Transactional
- 这些属性具有不可为空的类型
- 基于打印使用了UserService的相同实例/bean
- 删除
似乎可以解决这个问题@Transactional
- 添加或删除
似乎没有任何作用@EnableTransactionManagement
open class UserService (val userRepository: UserRepository,
val passwordService: PasswordService) : InitializingBean {
override fun afterPropertiesSet() {
println("### this.afterPropertiesSet")
println("### this: " + this)
println("### userRepository: " + userRepository)
println("### passwordService: " + passwordService)
}
@Transactional
fun registerUser(request: UserRegistrationRequest): User {
println("### this.registerUser")
println("### this: " + this)
println("### userRepository: " + userRepository)
println("### passwordService: " + passwordService)
val savedUser = this.userRepository.save(request.toUser())
this.passwordService.savePassword(savedUser, request.password)
return savedUser
}
private fun UserRegistrationRequest.toUser(): User { ... }
}
控制器:
@Controller
class UserController (val userService: UserService) : InitializingBean {
override fun afterPropertiesSet() {
println("### controller.afterPropertiesSet: " + userService)
println("### user service: " + userService)
}
@PostMapping("/users")
fun registerUser(@RequestBody userDetails: UserDetailsDto): ResponseEntity<UserDto> {
println("### controller.registerUser: " + userService)
println("### user service: " + userService)
val registeredUser = userService.registerUser(userDetails.toUserRegistrationRequest())
return ResponseEntity.ok(registeredUser.toDto())
}
private fun UserDetailsDto.toUserRegistrationRequest(): UserRegistrationRequest { ... }
private fun User.toDto(): UserDto { ... }
}
印刷品:
### this.afterPropertiesSet
### this: com.sample.mojo.user.UserService@1ab14636
### userRepository: org.springframework.data.jpa.repository.support.SimpleJpaRepository@1961d75a
### passwordService: com.sample.mojo.user.PasswordService@36359723
### controller.afterPropertiesSet: com.sample.mojo.user.UserService@1ab14636
### user service: com.sample.mojo.user.UserService@1ab14636
### controller.registerUser: com.sample.mojo.user.UserService@1ab14636
### user service: com.sample.mojo.user.UserService@1ab14636
### this.registerUser
### this: com.sample.mojo.user.UserService@1ab14636
### userRepository: null
### passwordService: null
包结构
com.sample.app.Application
com.sample.app.ApplicationServicesConfiguration
com.sample.app.user.UserController
com.sample.app.user.UserService
com.sample.app.user.UserRepository
com.sample.app.user.PasswordService
这是弹簧虫吗?还是Kotlin Spring集成怪癖?尝试将事务功能标记为打开 有一个gradle插件,用于将所有类标记为打开:
buildscript{
dependencies {
classpath("org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion")
}
}
apply plugin: 'kotlin-spring'
你试过用
@Service
注释UserService
吗?我没有。但是我在@配置
类中将UserService声明为@Bean
。为清晰起见,添加了bean声明。@BranislavLazic根据请求添加了包结构对Kotlin不太熟悉,但@Transactional fun
似乎是最终的。这使得它不可代理,因此它将使用代理的实例(即null
)而不是调用实际包装的实例。尝试打开功能
。
buildscript{
dependencies {
classpath("org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion")
}
}
apply plugin: 'kotlin-spring'