Spring boot can't inject beans on kotlin

Viewed 33

I'm getting the most annoying error on spring boot while using kotlin (hate companies that are enforcing this !@#&!@)

The scenario is very very very simple:

@RestController
open class NotificationController(
    private val notificationService: NotificationService
) {
    @PostMapping("/send")
    fun createNotification(@RequestBody @Valid notification: Notification): ResponseEntity<Notification> {
 
        return ResponseEntity.ok(notificationService.createNotification(notification))
    }
}


@Service
open class NotificationService(
    val notificationRepository: NotificationRepository,
   
) {
    val logger = LoggerFactory.getLogger(NotificationService::class.java)


    fun createNotification(notification: Notification): Notification {
         
        return notificationRepository.save(notification);
    }
}

Controller and Service couldn't be simplier. this scenario works FINE

but if I want my controller to be validated and add

@RestController
@Validated
open class NotificationController(

if I simple add this, spring can't inject the notificationService anymore... the program runs, but the service becomes null and the application crashes.

IF I ADD @Async or @Transactional to my service THEN THE REPOSITORY BECOMES NULL

Seems that spring is unable to extend any of the components class in kotlin to add the annotation behavior

is it a kotlin or spring bug? How to solve this? is kotlin a total garbage?

1 Answers

Kotlin has changed the Spring Boot code to become more simple. Your problem is not a bug, but the code is different from the Java code.

Because you have used the @Service annotation, you can just autowired those components inside the class.

@RestController
class NotificationController {
    @Autowired private lateinit var notificationService: NotificationService

    @PostMapping("/send")
    fun createNotification(@RequestBody @Valid notification: Notification): ResponseEntity<Notification> {
        return ResponseEntity.ok(notificationService.createNotification(notification))
    }
}


@Service
class NotificationService {
    @Autowired private lateinit var notificationRepository: NotificationRepository

    companion object {
        private val logger: Logger = LoggerFactory.getLogger(NotificationService::class.java)
    }

    fun createNotification(notification: Notification): Notification {
        return notificationRepository.save(notification);
    }
}
Related