Как создать экземпляр объекта (шаблон Jdbc) внутри хранилища карт Hazelcast

#java #hazelcast

#java #hazelcast

Вопрос:

Я пытаюсь автоматически подключить шаблон jdbc внутри хранилища карт .. но я получаю исключение нулевого указателя.

Я работал над таким количеством примеров, но не смог решить эту проблему..

Вот мой основной класс

 
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......");
    }

}

  

Вот мой настроенный кеш-код

 @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;

    }

}
  

и реализация TblRepo

 @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);
    }

  

и интерфейс TblRepo, который я аннотировал аннотацией @Repository..

И мой класс хранилища карт

 @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
}
  

и контроллер

 @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";
    }

}
  

Вот поток программы.. Когда я запускаю приложение, будет запущен первый класс Cacheconfig.

  • В контроллере, когда я выполняю операцию map.put(), данные будут отправляться в класс DataMapStore и вызывать метод store для сохранения данных в базе данных .. поскольку DataTblRepo равно нулю, поэтому операция не выполняется в самом методе store..* Я также попытался добавить @component в класс DataMapStore

но в моем случае я получаю эту ошибку

  • «сообщение»: «Невозможно вызвать «com.example.demo.repo.DataTblRepository.save (строка, строка)», потому что «this.dataTableRepo» равно нулю»,

Я также видел эту проблему на многих платформах, но все еще не смог решить эту проблему.

Любые предложения были бы очень полезны

Ответ №1:

SpringAware предназначен для распределенных объектов Hazelcast (см. документацию).

MapStore В вашем примере это не распределенный объект, а простой обычный объект. Им должен управлять сам Spring. Вы должны заменить @SpringAware @Component аннотацию аннотацией Spring.

Следующая проблема заключается в том, что конфигурация вашего хранилища карт делает Hazelcast ответственным за создание экземпляра MapStore . Если это произойдет, вы не сможете воспользоваться механизмом внедрения зависимостей Spring. Вы должны напрямую установить экземпляр, созданный Spring.

  1. Заменить SpringAware на Component

     @Component
    public class DataMapStore implements MapStore<String, ModelClass> {
        // ...
    }
      
  2. Используйте MapStore экземпляр, настроенный на Spring

     @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;
    }
      

Я также удалил static ключевое слово в config() методе.

Обратите внимание, что этот способ использования MapStore связывает его с «клиентским» кодом. Это означает, что вам нужно использовать встроенный Hazelcast. Для получения дополнительной информации о встроенном режиме и клиенте / сервере, пожалуйста, ознакомьтесь с документацией, связанной с топологией.