Search code examples
javaspringspring-bootspring-mybatis

Why is my Spring Boot @Autowired MyBatis static mapper null?


I have the following class, but Spring and MyBatis-Spring-Boot-Starter will not autowire my mapper.

When I run the request, I get the output from the println()

sourceMapper = null

Model

public class Source {       
    @Autowired
    public static SourceMapper sourceMapper;   #### Why isn't this set?

    public static Source findOrCreate(String url) {
        ...
        System.out.println("sourceMapper = " + sourceMapper);
        source = sourceMapper.findByHost(host);
        ...
    }

}

I followed the examples as closely as possible.

http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/

The other @Autowired Mappers in the main @Controller class that handles requests work, even though they are private.

This is the Mapper class

package ...mapper;

@Mapper
public interface SourceMapper {
  ...

I ran into this issue again with a new model and mapper. I tried to follow Why is my Spring @Autowired field null? and the code sample, but it was still null! I tried @Configurable, @Service, @Component.

Model
@Configurable
public class Domain {
    @Autowired
    private static DomainMapper domainMapper;

    public static void incrementCounter(String host) {
        ...
        Domain d = getDomainMapper().find(host, thisMonth);

    public static DomainMapper getDomainMapper() {
        return domainMapper;

    public static void setDomainMapper(DomainMapper domainMapper) {
        Domain.domainMapper = domainMapper;
Mapper
@Mapper
public interface DomainMapper {

MyBatis 3.4.5, MyBatis Spring 1.3.1, MyBatis Spring Boot Autoconfigure 1.3.1, MyBatis Spring Boot Starter 1.3.1


Solution

  • I fixed it with

    private static DomainMapper getDomainMapper() {
        // https://stackoverflow.com/a/52997701/148844
        if (domainMapper == null)
            domainMapper = MyApplication.getApplicationContext().getBean(DomainMapper.class);
        return domainMapper;
    

    And

    MyApplication
    @Autowired // for AWS
    private static ApplicationContext context;
    // I believe this only runs during an embedded Tomcat with `mvn spring-boot:run`. 
    // I don't believe it runs when deploying to Tomcat on AWS.
    public static void main(String[] args) {
        context = SpringApplication.run(MyApplication.class, args);
    

    But I don't like it!