简体   繁体   中英

Apache Ignite Hibernate L2 Cache with Spring Boot

I'm trying to develop a Spring Boot application with Iginte Hibernate L2 Cache.

Before I start my Spring Boot application, I run my server node. When I'm trying to run the Spring Boot Application I got the following error:

Output

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.3.RELEASE)

2018-11-28 18:14:50.291  INFO 20868 --- [           main] c.o.apache.ignite.learn.Application      : Starting Application on DESKTOP-UNSVMQG with PID 20868 (C:\Users\patri\HibernateL2Cache\target\classes started by patri in C:\Users\patri\HibernateL2Cache)
2018-11-28 18:14:50.293  INFO 20868 --- [           main] c.o.apache.ignite.learn.Application      : No active profile set, falling back to default profiles: default
2018-11-28 18:14:50.324  INFO 20868 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@50a638b5: startup date [Wed Nov 28 18:14:50 CET 2018]; root of context hierarchy
2018-11-28 18:14:51.353  INFO 20868 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2018-11-28 18:14:51.365  INFO 20868 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2018-11-28 18:14:51.366  INFO 20868 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.14
2018-11-28 18:14:51.463  INFO 20868 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2018-11-28 18:14:51.464  INFO 20868 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1142 ms
2018-11-28 18:14:51.565  INFO 20868 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
2018-11-28 18:14:51.568  INFO 20868 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-11-28 18:14:51.569  INFO 20868 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-11-28 18:14:51.569  INFO 20868 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-11-28 18:14:51.570  INFO 20868 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2018-11-28 18:14:52.065  INFO 20868 --- [           main] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
2018-11-28 18:14:52.074  INFO 20868 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [
    name: default
    ...]
2018-11-28 18:14:52.123  INFO 20868 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate Core {5.0.12.Final}
2018-11-28 18:14:52.124  INFO 20868 --- [           main] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found
2018-11-28 18:14:52.125  INFO 20868 --- [           main] org.hibernate.cfg.Environment            : HHH000021: Bytecode provider name : javassist
2018-11-28 18:14:52.159  INFO 20868 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2018-11-28 18:14:52.248  INFO 20868 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
2018-11-28 18:14:52.460  WARN 20868 --- [           main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
2018-11-28 18:14:52.536  INFO 20868 --- [           main] utoConfigurationReportLoggingInitializer : 

Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2018-11-28 18:14:52.543 ERROR 20868 --- [           main] o.s.boot.SpringApplication               : Application startup failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081) ~[spring-context-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:856) ~[spring-context-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) ~[spring-context-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
    at com.ontius.apache.ignite.learn.Application.main(Application.java:13) [classes/:na]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:954) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:882) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) ~[spring-orm-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353) ~[spring-orm-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:370) ~[spring-orm-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:359) ~[spring-orm-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    ... 16 common frames omitted
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.spi.CacheImplementor]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:264) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:228) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:207) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.getService(SessionFactoryServiceRegistryImpl.java:68) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:244) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:879) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    ... 22 common frames omitted
Caused by: org.apache.ignite.IgniteIllegalStateException: Ignite instance with provided name doesn't exist. Did you call Ignition.start(..) to start an Ignite instance? [name=HibernateL2CacheGrid]
    at org.apache.ignite.internal.IgnitionEx.grid(IgnitionEx.java:1383) ~[ignite-core-2.6.0.jar:2.6.0]
    at org.apache.ignite.Ignition.ignite(Ignition.java:535) ~[ignite-core-2.6.0.jar:2.6.0]
    at org.apache.ignite.cache.hibernate.HibernateAccessStrategyFactory.start(HibernateAccessStrategyFactory.java:112) ~[ignite-hibernate-core-2.6.0.jar:2.6.0]
    at org.apache.ignite.cache.hibernate.HibernateRegionFactory.start(HibernateRegionFactory.java:92) ~[ignite-hibernate_5.1-2.6.0.jar:2.6.0]
    at org.hibernate.internal.CacheImpl.<init>(CacheImpl.java:49) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:28) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:20) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.initiateService(SessionFactoryServiceRegistryImpl.java:49) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:254) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    ... 28 common frames omitted


Process finished with exit code 1

In order to get a better understanding of my code, I list the relvant code snippets below.

CacheConfigurationFactory

public class CacheConfigurationFactory {

    public static List<CacheConfiguration> createCacheList() {
        List<CacheConfiguration> cacheList = new ArrayList<CacheConfiguration>();

        cacheList.add(createTransactionalCache("com.ontius.apache.ignite.learn.model.Person"));
        cacheList.add(createAtomicCache("org.hibernate.cache.spi.UpdateTimestampsCache"));
        cacheList.add(createAtomicCache("org.hibernate.cache.internal.StandardQueryCache"));

        return cacheList;
    }

    private static CacheConfiguration createAtomicCache(String cacheName) {
        CacheConfiguration cacheConfiguration = new CacheConfiguration();
        cacheConfiguration.setCacheMode(CacheMode.PARTITIONED);
        cacheConfiguration.setAtomicityMode(CacheAtomicityMode.ATOMIC);
        cacheConfiguration.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
        cacheConfiguration.setName(cacheName);
        return cacheConfiguration;
    }

    private static CacheConfiguration createTransactionalCache(String cacheName) {
        CacheConfiguration cacheConfiguration = new CacheConfiguration();
        cacheConfiguration.setCacheMode(CacheMode.PARTITIONED);
        cacheConfiguration.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
        cacheConfiguration.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
        cacheConfiguration.setName(cacheName);
        return cacheConfiguration;
    }

}

ServerConfigurationFactory

public class ServerConfigurationFactory {

    public static IgniteConfiguration createConfiguration() {
        IgniteConfiguration igniteConfiguration = new IgniteConfiguration();

        igniteConfiguration.setClientMode(false);
        igniteConfiguration.setIgniteInstanceName("HibernateL2CacheGrid");
        igniteConfiguration.setPeerClassLoadingEnabled(true);

        TcpDiscoverySpi discoverySpi = new TcpDiscoverySpi();
        TcpDiscoveryMulticastIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();

        ipFinder.setAddresses(Arrays.asList("127.0.0.1:47500:47509"));
        discoverySpi.setIpFinder(ipFinder);
        igniteConfiguration.setDiscoverySpi(discoverySpi);

        List<CacheConfiguration> cacheList = CacheConfigurationFactory.createCacheList();
        igniteConfiguration.setCacheConfiguration(cacheList.toArray(new CacheConfiguration[cacheList.size()]));

        return igniteConfiguration;
    }

}

ClientConfigurationFactory

public class ClientConfigurationFactory {

    public static IgniteConfiguration createConfiguration() {
        IgniteConfiguration igniteConfiguration = new IgniteConfiguration();

        igniteConfiguration.setClientMode(true);
        igniteConfiguration.setIgniteInstanceName("HibernateL2CacheGrid");
        igniteConfiguration.setPeerClassLoadingEnabled(true);

        TcpDiscoverySpi discoverySpi = new TcpDiscoverySpi();
        TcpDiscoveryMulticastIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();

        ipFinder.setAddresses(Arrays.asList("127.0.0.1:47500:47509"));
        discoverySpi.setIpFinder(ipFinder);
        igniteConfiguration.setDiscoverySpi(discoverySpi);

        List<CacheConfiguration> cacheList = CacheConfigurationFactory.createCacheList();
        igniteConfiguration.setCacheConfiguration(cacheList.toArray(new CacheConfiguration[cacheList.size()]));

        return igniteConfiguration;
    }

}

SessionFactoryConfiguration

@EnableAutoConfiguration
public class SessionFactoryConfiguration {

    @Bean
    public HibernateJpaSessionFactoryBean sessionFactory(EntityManagerFactory entityManagerFactory) {
        HibernateJpaSessionFactoryBean hibernateJpaSessionFactoryBean = new HibernateJpaSessionFactoryBean();
        hibernateJpaSessionFactoryBean.setEntityManagerFactory(entityManagerFactory);
        return hibernateJpaSessionFactoryBean;
    }

}

ServerNodeStartup

public class ServerNodeStartup {

    public static void main(String[] args) {
        Ignition.start(ServerConfigurationFactory.createConfiguration());
    }

}

Application

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public IgniteSpringBean igniteInstance() {
        IgniteSpringBean igniteSpringBean = new IgniteSpringBean();
        igniteSpringBean.setConfiguration(ClientConfigurationFactory.createConfiguration());
        return igniteSpringBean;
    }

}

application.yml

spring:
  application:
    name: HibernateL2Cache
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/demo_app?useSSL=false
    username: root
    password: demo
  jpa:
    properties:
      hibernate:
        show_sql: true
        generate_statistics: true
        cache:
          use_query_cache: true
          use_second_level_cache: true
          region:
            factory_class: org.apache.ignite.cache.hibernate.HibernateRegionFactory
      org:
        apache:
          ignite:
            hibernate:
              ignite_instance_name: HibernateL2CacheGrid
              default_access_type: READ_WRITE

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.ontius.apache.ignite.learn</groupId>
    <artifactId>hibernate-l2-cache</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>HibernateL2Cache</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <ignite.version>2.6.0</ignite.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.3.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- Apache Ignite -->
        <dependency>
            <groupId>org.apache.ignite</groupId>
            <artifactId>ignite-core</artifactId>
            <version>${ignite.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.ignite</groupId>
            <artifactId>ignite-spring</artifactId>
            <version>${ignite.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.ignite</groupId>
            <artifactId>ignite-hibernate_5.1</artifactId>
            <version>${ignite.version}</version>
        </dependency>
        <!-- MySQL -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.13</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

I think I have to start ignite in the Spring Boot Application before the entityManagerFactory is initialized. But I don't know how I can achieve this.

First, you have a typo in your addresses : 127.0.0.1:47500:47509 should be 127.0.0.1:47500..47509 .

Second, you have two options to link Hibernate L2 Cache to Ignite - start the Ignite node manually in the same JVM prior to Hibernate initialization or make Hibernate start it automatically.

Since you're using Spring Boot, and Ignite always starts last in the Spring contexts, it would probably be easier to go with the second approach.

To enable automatic Ignite startup you need to set org.apache.ignite.hibernate.grid_config property to a path of an Ignite XML configuration. Unfortunately, it seems that you can't use Java-based configuration here, only XML. You can convert your client configuration to an XML, put it into a resource under META-INF , say META-INF/ignite-client.xml , and then reference it (now without META-INF ) - org.apache.ignite.hibernate.grid_config: ignite-client.xml . You should also remove the ignite_instance_name property (because it is overridden by grid_config ) and the Ignite bean in the client application (because it is now started by Hibernate).

I know this is an old post. But let me put my view on this issue here.

The reason for this issue is Spring Boot is staring before Ignite. To fix it, we need to make sure Ignite is starting before Spring Boot.

If you change your "Application.java" as below, it should work.

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        IgniteSpringBean igniteSpringBean = new IgniteSpringBean();
        igniteSpringBean.setConfiguration(ClientConfigurationFactory.createConfiguration());
        SpringApplication.run(Application.class, args);
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM