2017-03-04 15 views
2

我遇到了在調用@Transactional方法期間bean的屬性變爲null的問題。初始化期間Bean屬性爲null在@Transactional方法調用期間變爲null

  • UserService處於@Configuration類中聲明
  • userRepositorypasswordService是registerUser(這是@Transactional)的調用期間初始化(afterPropertiesSet)
  • 在非空的Bean,這些性質成爲空
  • 這些屬性有不可爲空的類型
  • 已根據打印件使用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 { ... } 
} 

Bean聲明:

@Configuration 
@EnableTransactionManagement 
open class ApplicationServicesConfiguration { 

    @Bean 
    open fun userService(userRepository: UserRepository, 
         passwordService: PasswordService): UserService = UserService(userRepository, passwordService) 

    @Bean 
    open fun passwordService(passwordRepository: PasswordRepository): PasswordService = PasswordService(passwordRepository) 

} 

打印:

### this.afterPropertiesSet 
### this: [email protected] 
### userRepository: org.[email protected]1961d75a 
### passwordService: [email protected] 

### controller.afterPropertiesSet: [email protected] 
### user service: [email protected] 

### controller.registerUser: [email protected] 
### user service: [email protected] 

### this.registerUser 
### this: [email protected] 
### 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 

這是一個Spring的錯誤?還是Kotlin-Spring整合的怪癖?

+0

你通過註釋嘗試'UserService'與'@ Service'? –

+0

我沒有。但是我在'@ Configuration'類中將UserService聲明爲'@ Bean'。爲了清楚,添加了bean聲明。 – Chad

+0

@BranislavLazic按要求添加了包結構 – Chad

回答

0

嘗試將事務性函數標記爲open。

沒有爲標誌認證的所有類作爲一個開放的Gradle插件:

buildscript{ 
    dependencies { 
     classpath("org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion") 
    } 
} 
apply plugin: 'kotlin-spring'