How to instantiate object(Jdbc template) inside Hazelcast Map store

雨燕双飞 提交于 2021-02-17 06:06:34

问题


I'm trying to Autowire jdbc template inside mapStore.. but I'm getting null pointer exception.

I worked on so many examples but sill not able to resolve this issue..

Here is my main class


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class TestCacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestCacheApplication.class, args);
        System.err.println("......running successfully......");
    }

}

Here is my cache configured code

@Component
public class CacheConfig {

    @Bean
    public static Config config() {

        System.err.println("config class");
        Config config = new Config();
        config.setInstanceName("hazelcast");
        
        
        MapConfig mapCfg = new MapConfig();
        mapCfg.setName("first-map");
        mapCfg.setBackupCount(2);
        mapCfg.setTimeToLiveSeconds(300);

        MapStoreConfig mapStoreCfg = new MapStoreConfig();
        mapStoreCfg.setClassName(DataMapStore .class.getName()).setEnabled(true);
        mapCfg.setMapStoreConfig(mapStoreCfg);
        config.addMapConfig(mapCfg);

        return config;

    }

}

and TblRepo implementation

@Service
public class DataTblRepoImpl implements DataTblRepo {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void save(String id, String name) {

        Object[] params = new Object[] { id, name };
        int[] types = new int[] { Types.VARCHAR, Types.VARCHAR };
        String insertSql = "INSERT INTO public.person(id, name)  VALUES(?, ?)";
        jdbcTemplate.update(insertSql, params, types);
    }

and TblRepo interface I have annotated with @Repository annotation..

And My map store class

@SpringAware
public class DataMapStore implements MapStore<String, ModelClass>{

    @Autowired
    DataTblRepo dataTblRepo;

    @Override
    public void store(String key, ModelClass value) {
        dataTblRepo.save(value.getId(), value.getName());

    }
//remaining methods will come here
}

and Controller

@RestController
@CrossOrigin(origins = "*")
@RequestMapping("/api/v1")
public class DataController {

    @Autowired
    DataService dataService;

    HazelcastInstance hazelCast = Hazelcast.getHazelcastInstanceByName("hazelcast");

    @PostMapping("/{test}")
    public String saveDatafrom(@RequestBody ModelClass model) {

        hazelCast.getMap("first-map").put(model.getId(), model);
        return "stored";
    }

}

Here is the program flow.. When I start the application, first Cacheconfig class will run.

  • In the controller when I perform the map.put() operation, data will go to the DataMapStore class and call the store method to save the data in database..since DataTblRepo is null so operation is failing at the store method itself..* I tried adding @component on the DataMapStore class also

but in my case I'm getting this error

  • "message": "Cannot invoke "com.example.demo.repo.DataTblRepository.save(String, String)" because "this.dataTableRepo" is null",

I saw this same issue in many platforms also but still not able to resolve this issue.

Any suggestions would be very helpful


回答1:


SpringAware is for Hazelcast distributed objects (cf. documentation).

The MapStore in your example is not a distributed object but a simple plain object. It should be managed by Spring itself. You should replace the @SpringAware annotation by a Spring @Component annotation.

The next issue is that your map store configuration makes Hazelcast responsible to instantiate the MapStore. If this happens, you won't benefit from Spring's Dependency Injection mechanism. You should directly set the instance created by Spring.

  1. Replace SpringAware by Component

    @Component
    public class DataMapStore implements MapStore<String, ModelClass> {
        // ...
    }
    
  2. Use the Spring-configured MapStore instance

    @Bean
    public Config config(DataMapStore mapStore) { // Ask Spring to inject the instance
    
        // ...
    
        MapStoreConfig mapStoreCfg = new MapStoreConfig();
        mapStoreCfg.setImplementation(mapStore);  // Use it
        mapCfg.setMapStoreConfig(mapStoreCfg);
        config.addMapConfig(mapCfg);
    
        return config;
    }
    

I also removed the static keyword on the config() method.

Note that this way of using MapStore couples it with the "client" code. This means you need to use Hazelcast embedded. For more information about embedded mode vs. client/server, please check the documentation related to topology.



来源:https://stackoverflow.com/questions/64792712/how-to-instantiate-objectjdbc-template-inside-hazelcast-map-store

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!