Search code examples
nullannotationsmybatisautowiredinject

MyBatis annotation configuration autowired field null


I try to make console myBatis application and get rid of using the same code many times to initialize session, doing commits and transactional. This code gives me "Null Pointer Value" in field "sm" in Annotations_Example class. What i do wrong? With in class initialization all is working fine. But now, it have NPE.

DataSource class

public class DataSourceStudent_Mapper {

        @Bean
     public Student_mapper getDataSource() {
            String user = "postgres";
             String password = "postgres";
             String databasenameURL = "jdbc:postgresql://localhost:5432/postgres";
             String dbDriver = "org.postgresql.Driver";
             DataSource dataSource = new org.apache.ibatis.datasource.pooled.PooledDataSource(
                     dbDriver, databasenameURL, user, password);
             TransactionFactory transactionFactory = new JdbcTransactionFactory();
             Environment environment = new Environment("development",
                     transactionFactory, dataSource);
             Configuration configuration = new Configuration(environment);
             SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
                     .build(configuration);

             SqlSession session = sqlSessionFactory.openSession();
             session.getConfiguration().addMapper(Student_mapper.class);

            return session.getMapper(Student_mapper.class);
            }

        }

Main class

public class Annotations_Example {

    @Autowired
    public Student_mapper sm;

    public static void main(String args[]) throws IOException {

        Student student = new Student();

        student.setName("zara");
        student.setBranch("EEE");
        student.setEmail("[email protected]");
        student.setPercentage(90);
        student.setPhone(123412341);

        sm.insert(student);

        sm.getMaxId();

        session.commit();
        session.close();



    }

}

Solution

  • You need to initialize Spring properly.
    If you want a quick solution, try Spring Boot and MyBatis-Spring-Boot-Starter.

    Assuming you are familiar with Maven, there needs to be a few modifications to your pom.xml.

    <dependencyManagement>
      <dependencies>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-dependencies</artifactId>
          <version>2.2.5.RELEASE</version>
          <type>pom</type>
          <scope>import</scope>
        </dependency>
      </dependencies>
    </dependencyManagement>
    
    <dependencies>
      <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.1</version>
      </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
      </dependency>
      <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
      </dependency>
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <scope>test</scope>
      </dependency>
    </dependencies>
    
    <build>
      <plugins>
        <plugin>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-maven-plugin</artifactId>
          <version>2.2.5.RELEASE</version>
          <executions>
            <execution>
              <goals>
                <goal>repackage</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </build>
    

    The main class would look something as follows:

    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    import mapper.Student_mapper;
    
    @SpringBootApplication
    @MapperScan("mapper")
    public class Application implements CommandLineRunner {
    
      @Autowired
      private Student_mapper sm;
    
      public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
      }
    
      @Override
      public void run(String... args) throws Exception {
        ...
        sm.insert(student);
        ...
      }
    }
    

    In the @MapperScan annotation, you need to specify the package that contains your mappers.
    Then you should be able to inject mappers using @Autowired.

    Although this might not be necessary, it seems to be recommended to add the following line to the application.properties.

    spring.main.web-application-type=NONE
    

    With the above pom.xml, mvn package will generate an executable JAR file (with java -jar).

    Here is an executable demo project.