Reputation: 179
I am working on a spring boot project. In that, i have an entity called ProductMap which i want to keep in cache. I did that using MapLoader and defining the configuration for the map as below.
@Bean
public Config hazelcastConfig() {
return new Config().setInstanceName("hazelcast-instance").addMapConfig(
new MapConfig().setName("ProductMap")
.setMapStoreConfig(
new MapStoreConfig().setEnabled(true).setInitialLoadMode(MapStoreConfig.InitialLoadMode.EAGER)
.setClassName("com.hazelcast.example.HzTest.config.ProductMapLoader")
));
}
ProductMap entity:
@Data
@Entity
@KeySpace("ProductMap")
@Table
public class ProductMap implements Serializable {
@Id
@org.springframework.data.annotation.Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer Id;
private String name;
private Integer category;
private Integer productType;
}
ProductMapLoader:
@Log4j2
@Component
public class ProductMapLoader implements MapLoader<Integer, ProductMap>, ApplicationContextAware {
private static ProductMapRepository productMapRepository;
@Override
public synchronized ProductMap load(Integer integer) {
System.out.println("Load::" + integer);
return productMapRepository.findById(integer).get();
}
@Override
public synchronized Map<Integer, ProductMap> loadAll(Collection<Integer> collection) {
Map<Integer, ProductMap> result = new HashMap<>();
for (Integer key : collection) {
ProductMap productMap = this.load(key);
if (productMap != null) {
result.put(key, productMap);
}
}
return result;
}
@Override
public synchronized Iterable<Integer> loadAllKeys() {
System.out.println("load all keys" + productMapRepository);
return productMapRepository.findAllProdMapKeys();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
productMapRepository = applicationContext.getBean(ProductMapRepository.class);
}
}
I am loading the cache on startup,
@PostConstruct
public void Init() {
IMap map = hazelcastInstance.getMap("ProductMap"); // this will load the cache
}
In also created a HazelcastRepository,
public interface ProductMapKvRepo extends KeyValueRepository<ProductMap, Integer> {
List<ProductMap> findByProductType(Integer productType);
}
In one of my service methods, it calls productMapKvRepo.findAll()
and productMapKvRepo.findByProductType(1).
But the repository still queries the database.
Hibernate: select productmap0_.id as id1_0_, productmap0_.category as category2_0_, productmap0_.name as name3_0_, productmap0_.product_type as product_4_0_ from product_map productmap0_
Hibernate: select productmap0_.id as id1_0_, productmap0_.category as category2_0_, productmap0_.name as name3_0_, productmap0_.product_type as product_4_0_ from product_map productmap0_ where productmap0_.product_type=?
dependencies used:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<version>3.12.7</version>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-client</artifactId>
<version>3.12.7</version>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>spring-data-hazelcast</artifactId>
<version>2.2.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.13</version>
</dependency>
</dependencies>
Can anyone tell me what is wrong here and what can i do?
Upvotes: 1
Views: 1303
Reputation: 1
While I was working with Spring Boot v2.1.3.RELEASE and Spring v5.1.5.RELEASE , spring was injecting SimpleJpaRepository
type for both repositories :
MyStandardRepository
And MyHazelCastRepository
, with the presence only of @EnableHazelcastRepositories
By adding also @EnableJpaRepositories
to my HazelcastConfiguration
class :
spring then injected SimpleKeyValueRepository
bean type into MyHazelCastRepository
:
@Configuration
@EnableHazelcastRepositories(basePackages = {"com.test.repository.hazelcast"})
@EnableJpaRepositories(basePackages = {"com.test.repository.dao"})
public class HazelcastConfiguration {
@Bean
HazelcastInstance hazelcastInstance() {
return Hazelcast.newHazelcastInstance();
}
@Bean
public KeyValueOperations keyValueTemplate() {
return new KeyValueTemplate(new HazelcastKeyValueAdapter(hazelcastInstance()));
}
@Bean
public HazelcastKeyValueAdapter hazelcastKeyValueAdapter(HazelcastInstance hzInstance) {
return new HazelcastKeyValueAdapter(hzInstance);
}
}
Upvotes: 0
Reputation: 13843
Your logs indicate that your Spring Data repository is Hibernate-backed which means your project is misconfigured. Spring Data Hazelcast doesn't use Hibernate to read data from the Hazelcast IMDG cluster.
If the use of Hibernate is intended(most likely), then you should consider using its native second-level cache capabilities with Hazelcast instead of wrapping Spring Data repositories inside a MapLoader. You can find the example here.
However, if you want to apply the read-through caching pattern with a MapLoader, you'd need to use a spring-data-hazelcast
artifact to read data from Hazelcast cluster directly.
Upvotes: 3