Kotlin JdbcTemplate 为空

Kotlin JdbcTemplate Null

我正在尝试将我的应用程序从 java 转换为 kotlin,目前正在混合使用 Java 和 Kotlin。我正在尝试先将我的存储库 类 转换为 Kotlin。这是使用 Spring JDBC。我做错了什么吗?

package com.meteor.coral.resources.useradministration.domain

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.jdbc.core.JdbcTemplate
import org.springframework.jdbc.core.RowMapper
import org.springframework.stereotype.Repository
import java.sql.ResultSet
import java.sql.SQLException

@Repository
open class AppUserJdbcRepository {

    @Autowired
    private var jdbcTemplate: JdbcTemplate? = null

    fun findByFirstName(firstName: String): AppUser {
        print("hello")
        return jdbcTemplate!!.queryForObject("select firstname, lastname from m_appuser where firstname = ?", arrayOf<Any>(firstName), AppUserRowMapper())
    }



    internal inner class AppUserRowMapper : RowMapper<AppUser> {
        @Throws(SQLException::class)
        override fun mapRow(resultSet: ResultSet, i: Int): AppUser {
            val appUser = AppUser(resultSet.getString("firstname"),resultSet.getString("lastName") )
            return appUser
        }
    }
}

我的考试还在Java

package com.meteor.coral.resources.useradministration;

import com.meteor.coral.UserAdministrationServiceApplication;
import com.meteor.coral.resources.useradministration.domain.AppUser;
import com.meteor.coral.resources.useradministration.domain.AppUserJdbcRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@SpringBootTest(classes = {UserAdministrationServiceApplication.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class AppUserJdbcRepositoryTest {

    @Autowired
    private AppUserJdbcRepository appUserJdbcRepository;

    private static final Logger LOGGER = LoggerFactory.getLogger(AppUserJdbcRepositoryTest.class);

    @Test
    public void testAppFetch() {
        AppUser appUser = appUserJdbcRepository.findByFirstName("CARLO");
        LOGGER.info(appUser.getId() + "");
        LOGGER.info(appUser.getFirstname());
        LOGGER.info(appUser.getLastname());
    }
}

jdbctemplate 始终为空。

hello
java.lang.NullPointerException
    at com.meteor.coral.resources.useradministration.domain.AppUserJdbcRepository.findByFirstName(AppUserJdbcRepository.kt:18)
    at com.meteor.coral.resources.useradministration.AppUserJdbcRepositoryTest.testAppFetch(AppUserJdbcRepositoryTest.java:25)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:59)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:331)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:79)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
    at org.junit.runners.ParentRunner.access0(ParentRunner.java:66)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:293)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:306)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)


谢谢,

属性 在 kotlin 中使用 spring 注入需要 lateinit 关键字:

@Autowired
private lateinit var jdbcTemplate: JdbcTemplate

通常你想要进行构造函数注入,因为这允许你删除 Autowired 注释并使其成为 val:

class AppUserJdbcRepository(private val jdbcTemplate: JdbcTemplate){

为了完整起见:您不应该(忽略罕见的极端情况)使用“!!” kotlin 中的运算符,因为这基本上只是退回到 java 的可空性方法。至少根据我的经验,用 '?: throw MyCustomException("jdbcTemplate was null during initialization")' 替换它更容易调试,我经常发现考虑它也会暴露不必要的可空性。