#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.
-
Заменить
SpringAware
наComponent
@Component public class DataMapStore implements MapStore<String, ModelClass> { // ... }
-
Используйте
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. Для получения дополнительной информации о встроенном режиме и клиенте / сервере, пожалуйста, ознакомьтесь с документацией, связанной с топологией.