Spring Boot + Hazelcast + Hibernate 5 L2 Cache

2019-06-09 17:29发布

I have a hibernate (5.0.11.Final) Spring Boot (1.4.1-RELEASE) application that uses Hazelcast (3.7.1) as the L2 cache implementation.

I wanted to clarify that with the hibernate l2 configuration, I do NOT need to include my own hazelcast.xml file.

I am asking because when I do have both (hibernate l2 configuration AND a src/main/resource/hibernate.xml file) when I start an instance of this application, I see 2 members created. When I start another instance, I see 4. I was under the impression that I should only see 1 member per application instance.

I was following a related thread where the user was experiencing something similar. I first tried naming my hazelcast instance in the hibernate configuration (programmatically) per this thread, but that made no difference.

When I remove my hazelcast.xml from the classpath & start an instance, I only see 1 member; what I want. Starting a 2nd, starts a 2nd member; what I want.

Is this the correct way of implementing the hibernate l2 cache using hazelcast (ONLY via the hibernate configuration)?

If so, what happens when I want to use fine-grained hazelcast configuration provided via a hazelcast.xml file?

2条回答
等我变得足够好
2楼-- · 2019-06-09 17:50

If Spring Boot 1.4.1 finds a hazelcast.xml file and no Config bean, it will create a Hazelcast instance from it.

The Hazelcast Hibernate module uses the hibernate.cache.hazelcast.instance_name property to determine whether you want a new Hazelcast instance or an existing one.

If you omit hibernate.cache.hazelcast.instance_name you get a new Hazelcast instance (also based on hazelcast.xml) and this is why you have two instances in the one JVM.

There are a number of ways to address. You can stop Spring Boot from autocreating an instance, and you can stop Hazelcast Hibernate from autocreating an instance.

If you are using Spring Boot, my recommendation would be to use a Hazelcast instance that is also a Spring bean. That way the bean will be managed by the Spring lifecycle, and you get elegant shutdown control.

The instance created by Spring Boot for you is the easiest and most obvious way to do so. To get the Hazelcast Hibernate module to use this also, just pass in the instance name when creating your JPA properties with something like: properties.setProperty("hibernate.cache.hazelcast.instance_name", hazelcastInstance.getName());

查看更多
相关推荐>>
3楼-- · 2019-06-09 18:03

Thank you @NeilStevenson. In hopes an example is helpful to others, am including what I did (that works) per Neil's recommendation:

Create src/main/resources/hazelcast.xml containing:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:spring="http://www.hazelcast.com/schema/spring"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.hazelcast.com/schema/spring https://hazelcast.com/schema/spring/hazelcast-spring-3.7.xsd">
    <spring:hazelcast id="hibernateHazelcastInstance">
        <spring:config>
            <spring:instance-name>springHibernate</spring:instance-name>
            <spring:group password="foo" name="bar"/>
            <spring:network port="5701" port-auto-increment="false">
                    <spring:tcp-ip enabled="false">
                        <spring:members>127.0.0.1</spring:members>
                    </spring:tcp-ip>
                </spring:join>
            </spring:network>
        </spring:config>
    </spring:hazelcast>

    <spring:hibernate-region-factory id="regionFactory" instance-ref="hibernateHazelcastInstance"/>
</beans>

In the 'config' inject the hazelcast instance:

import com.hazelcast.core.HazelcastInstance;
...

@Inject
public HazelcastInstance hazelcastInstance;

Then reference it in the hibernate configuration:

...
hibernateJpaProperties.setProperty("hibernate.cache.hazelcast.instance_name", hazelcastInstance.getName());
...
查看更多
登录 后发表回答