<p>I have a Spring boot application with Hibernate L2 cache enabled.
I integrated Hazelcast as cache provider for Hibernate.
My application runs on Kubernetes and deployed on 2 pods.I verified, that hibernate l2 cache successfully distributed between 2 pods, within 1 cluster.So if 1 entity was put in cache in one pod, I see that cache size increases equally in all pods.</p>
<p>Also ,I want to use Hazelcast with spring <code>@Cacheable</code>
But this cache is not distributed between 2 pods, and just works separately in each instance.
So ,If I trigger method with <code>@Cacheable</code> in first pod, and it's result is cached, then if I try to execute the same method(it result must be already in cache, after execution on fist pod) on second pod, It will not take it's result from cache.</p>
<p>What I need to add to configuration to make this work as expected?
Would be very grateful for any advice.Thanks.</p>
<p>deployment.yaml for Kubernetes</p>
<pre><code>apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: hazelcast-cluster-role
rules:
  - apiGroups:
      - &quot;&quot;
    resources:
      - endpoints
      - pods
      - nodes
      - services
    verbs:
      - get
      - list

---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: hazelcast-cluster-role-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: hazelcast-cluster-role
subjects:
  - kind: ServiceAccount
    name: default
    namespace: default
</code></pre>
<p>Configuration for Hazelcast - hazelcast.yaml</p>
<pre><code>hazelcast:
  instance-name: my-instance
  network:
    join:
      multicast:
        enabled: false
      kubernetes:
        enabled: true
        namespace: dev
</code></pre>
<p>Application properties</p>
<pre><code>spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.url=jdbc:postgresql://host.docker.internal/postgres
spring.datasource.username=postgres
spring.datasource.password=pass
spring.datasource.driver-class-name=org.postgresql.Driver

spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=com.hazelcast.hibernate.HazelcastCacheRegionFactory

spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.show_sql=true

hibernate.cache.hazelcast.instance_name=my-instance
</code></pre>
<p>Service with @Cacheable</p>
<pre><code>@Service
public class BookService {

    @Autowired
    private BookRepo bookRepo;

    @Cacheable(&quot;books&quot;)
    public Iterable&lt;Book&gt; getBooks() {
        try {
            Thread.sleep(15000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException(e);
        }
        System.out.println(&quot;Book service triggered&quot;);
        return bookRepo.findAll();
    }

}
</code></pre>

Oleksandr Onopriienko
<p>If I understand correctly, the data that is to be shared does not use <code>@Cacheable</code>, which makes it simpler, solution 1 below.</p>
<p>Solution 1 - Each pod/JVM contains 2 Hazelcast instances, one is a cache manager.</p>
<ul>
<li>The first is used for data to share with other pods, and uses Kubernetes discovery, as you already have.</li>
<li>The second is wired as the cache manager implementation. If this second instance is configured with discovery de-activated, it won't find other instances to share <code>@Cacheable</code> data with.</li>
<li>Be sure the second instance has a different cluster name and port range from the first.</li>
</ul>
<p>Solution 1 - Each pod/JVM contains 2 Hazelcast instances, both are cache managers.</p>
<ul>
<li>Configure both as for solution 1, the first clustered and the second standalone.</li>
<li>Use <code>@Cacheable(cacheManager = &quot;first&quot; ...)</code> or <code>@Cacheable(cacheManager = &quot;second&quot; ...)</code> to select what is cached locally and what is cached across all pods.</li>
</ul>
<p>Example Hazelcast code for 2nd standalone instance in same JVM.</p>
<pre><code>    @Bean(name = &quot;B&quot;)
    public HazelcastInstance hazelcastInstanceB() {
        Config config = new Config();
        config.setClusterName(UUID.randomUUID().toString());
        config.getNetworkConfig().setPort(6701);
        config.getNetworkConfig().getJoin().getAutoDetectionConfig().setEnabled(false);
        config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
        return Hazelcast.newHazelcastInstance(config);
    }
    @Autowired
    @Qualifier(value = &quot;B&quot;)
    private HazelcastInstance hazelcastInstanceB;
</code></pre>
