0

I'm using custom crudrespository to persist data in redis. However, I'm unable to autowire custom repository.

All the configuration seems correct and redis is running on my local.

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface CustomRepository extends CrudRepository<String, 
Long> {

String get(String key);

void put(String key, String value);
}

//////////

public class StorageServiceImpl implements IStorageService {


    @Autowired
    private CustomRepository respository;

    @Override
    public void saveParameter() {
    this.respository.put("key1","value1");
    }

    @Override
    public String getParameter() {
    return this.respository.get("key1");
    }

/////

@Service
public interface IStorageService {

    void saveParameter();

    String getParameter();
}
///////

@SpringBootApplication(scanBasePackages = {"com.example.cache"})
@EnableRedisRepositories(basePackages = {"com.example.cache.repository"})
public class ApplicationConfiguration {

public static void main(String[] args){
    SpringApplication.run(ApplicationConfiguration.class, args);
    new StorageServiceImpl().saveParameter();
        System.out.println(new StorageServiceImpl().getParameter());
    }
}

When I try running this application using gradle bootRun, I get

Exception in thread "main" java.lang.NullPointerException at com.example.cache.impl.StorageServiceImpl.saveParameter(StorageServiceImpl.java:16) at com.example.cache.ApplicationConfiguration.main(ApplicationConfiguration.java:17)

Not sure what's wrong?

heart_coder
  • 189
  • 13

1 Answers1

3

You can't use new on any bean, you need to @Autowire it. The annotations only work with spring managed beans at every level.

Add a new bean with a a storage service and a method that makes your call after it is created.

Also, I can't remember if the spring-boot creates the bean if there is only one implementation but I believe your StorageServiceImpl needs the @Service annotation, not the interface.

Delete this from your ApplicationConfiguration class.

new StorageServiceImpl().saveParameter();
System.out.println(new StorageServiceImpl().getParameter());

Then add this new class.

@Service
public class Startup {

    @Autowired
    IStorageService storageService;

    @PostConstruct
    public void init(){

         storageService.saveParameter();
         System.out.println(storageService().getParameter());
    }
}

And you need a config

@Configuration
@EnableRedisRepositories
public class ApplicationConfig {

  @Bean
  public RedisConnectionFactory connectionFactory() {
    return new JedisConnectionFactory();
  }

  @Bean
  public RedisTemplate<?, ?> redisTemplate() {

    RedisTemplate<byte[], byte[]> template = new RedisTemplate<byte[], byte[]>();
    return template;
  }
}
DCTID
  • 1,277
  • 9
  • 13
  • I did the above change. Now I'm getting "Field respository in com.example.cache.impl.StorageServiceImpl required a bean of type 'com.example.cache.repository.CustomRepository' that could not be found." – heart_coder Jul 21 '19 at 01:12
  • Did you move the `@Service` annotation to the impl class? If so do you have a Redis configuration? https://docs.spring.io/spring-data/data-redis/docs/current/reference/html/ has many different examples depending on the environment. I added a simple one to the answer – DCTID Jul 21 '19 at 03:39
  • Your suggestions helped. Thanks for your time. – heart_coder Jul 21 '19 at 21:38