SpringBoot 2.x 集成 Hibernate Search(历史项目迁移) 时间: 2019-12-24 18:13 分类: JAVA Web,Spring ####前言 大学期间个人写了个网站,采用的是`Spring` + `SpringMVC` + `Spring Data JPA`开发,如今之际想把网站重构:干掉`Spring Data JPA`,换成`Mybatis`操作数据库,重写前端页面。由于最开始使用的是`Hibernate Search`作为网站的全文检索,并且目前暂时不想重写后台管理系统(保留后台的增删改查),于是有了今天问题: 1. SpringBoot 集成 Hibernate Search 2. Mybatis 与 Hibernate Search 混合开发是否冲突(因为 Hibernate Search 依赖 Spring Data JPA) 3. 如何继续使用原有的索引(即老后台可继续插入数据建立索引,新系统能够直接查询老系统建的索引) ####扯卵谈 上面问题看似简单,但是兜兜转转也报了不少错误,浪费了不少时间,所以博客记之。 首先,最开始的问题,不用多想就是版本问题,`Spring Boot`版本: ``` org.springframework.boot spring-boot-starter-parent 2.2.2.RELEASE ``` 因为`Hibernate Search`依赖于`Spring Data JPA`,于是引入`Spring Data JPA`: ``` org.springframework.boot spring-boot-starter-data-jpa ``` 自动引入的`hibernate-core`版本为: ``` org.hibernate hibernate-core 5.4.9.Final ``` 集成`Hibernate Search`我们只需要再引入`Hibernate-search-orm`依赖即可: ``` org.hibernate hibernate-search-orm 5.11.4.Final ``` 注意上面的版本是`5.11.4.Final`,这个版本是没问题的,那么我是如何找到这个可用的版本的呢? 前面说了自动引入的`hibernate-core`版本为`5.4.9.Final`,那么我们到`https://mvnrepository.com`仓库去搜索`hibernate-search-orm`,可用看到有很多的版本,随便选一个版本点击进去,可用看到有这么一栏`Compile Dependencies`。 下面列举了一些编译依赖及其版本,可用看到目前最新版本`5.11.4.Final`正好依赖的是`5.4.9.Final`版本的`hibernate-core`,所以版本问题解决! #####第二个问题:与 Mybatis 是否冲突? 这个问题基本上不是什么问题,因为早前在公司的时候做过相关的测试,可用混合开发,不会冲突。 需要注意的是,与`Spring Boot`继承的`Spring Data JPA`在使用`@Column`时会发现设置的`name`参数不起作用,举例: > 数据库字段`createDate`,java 属性`createDate` 以前没有继承`Spring Boot`的时候,`@Column`的默认策略是`name`同`JAVA`属性。 但是集成`Spring Boot`后, `Column`的策略变为:`驼峰转下划线`,即: > createDate => create_date 解决办法: 1. 将列名全部改为小写 @column(name="testname") 2. 修改命名策略:spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl #####最后一个问题:共用老系统的索引 我之所以会有这个问题,是因为,重写后的项目,我更换了项目的包名,即:`Entity`实体类的包名发生了改变,即使我们把索引的存储路径配置为老系统保存的路径,比如: ``` spring: profiles: active: dev thymeleaf: cache: false mode: LEGACYHTML5 jpa: properties: hibernate: search: default: directory_provide: filesystem indexBase: E:\usr\local\indexes ``` 说明:`E:\usr\local\indexes`:老系统索引生成的目录。 打开目录其实不难发现,都是以`Entity`的全路径名作为索引文件的目录,所以一旦重写的项目包名发生了变化,那么就无法继续使用以前的索引了。 解决办法: 改包名?不太现实。 由于我的整个项目是采用`Kotlin`重写的,所以为了避免出现不必要的问题,决定直接将老系统的`Entity`拷贝过来,`Kotlin`可以与`JAVA`混合开发,正合我意。 注意:拷贝过来不是仅仅将`.java`文件拷贝过来,而是建立完全一样的包路径,将`.java`拷贝进去。 这样就行了吗?不行~! 假如我的新项目`Application`的包名为`com.aaa`,老项目的包名为`com.bbb`,这个时候启动项目进行查询会发现报错: ``` org.hibernate.search.exception.SearchException: HSEARCH000331: Can't build query for type 'com.bbb.entity.Article' which is neither configured nor has any configured sub-types. ``` 这个问题无非就是说`com.aaa.entity.Article`不是索引的类,没加`@Indexed`?没加`@Indexed`确实会报这个错误,但是我的`Entity`是直接拷贝过来的,所以不存在是加没加注解的问题。 除此之外,就是加了注解,但是没有扫描到。 由于`Spring Boot`项目默认是只会扫描与`Application`类同级以及其子级包中的注解,所以再看看之前两个不同的包名: 1. com.aaa 2. com.bbb 新项目的`Application`类就是在`com.aaa`下,所以新建的`com.bbb.entity`包下面的类肯定是扫描不到的,所以解决版本就是让`Spring Boot`去扫描它即可: ``` @EnableJpaRepositories @EntityScan("com.bbb.entity") ``` 至此,问题解决。 最后还有个问题需要注意的就是,如果要是用`IKAnalyzer`分词器的话,需要`exclude`掉`Lucene`相关的包,让项目使用`hibernate-search-orm`里面依赖的版本。我的依赖如下: ``` 4.0.0 org.springframework.boot spring-boot-starter-parent 2.2.2.RELEASE com.bde4 v2 0.0.1-SNAPSHOT war v2 Demo project for Spring Boot 1.8 1.3.61 org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-web com.fasterxml.jackson.module jackson-module-kotlin org.jetbrains.kotlin kotlin-reflect org.jetbrains.kotlin kotlin-stdlib-jdk8 org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.1 mysql mysql-connector-java runtime org.springframework.boot spring-boot-starter-tomcat provided org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine org.springframework.boot spring-boot-devtools true com.github.pagehelper pagehelper-spring-boot-starter 1.2.13 com.alibaba druid-spring-boot-starter 1.1.21 com.rometools rome 1.12.2 org.apache.commons commons-lang3 3.9 commons-codec commons-codec 1.13 org.springframework.boot spring-boot-starter-data-jpa org.hibernate hibernate-search-orm 5.11.4.Final com.jianggujin IKAnalyzer-lucene 5.3.0 lucene-core org.apache.lucene lucene-analyzers-common org.apache.lucene lucene-queries org.apache.lucene lucene-queryparser org.apache.lucene central Maven Repository Switchboard default http://repo1.maven.org/maven2 false ${project.basedir}/src/main/kotlin ${project.basedir}/src/test/kotlin org.springframework.boot spring-boot-maven-plugin org.jetbrains.kotlin kotlin-maven-plugin -Xjsr305=strict spring org.jetbrains.kotlin kotlin-maven-allopen ${kotlin.version} kotlin-maven-plugin org.jetbrains.kotlin ${kotlin.version} no-arg no-arg:annotation=com.bde4.v2.annotation.NoArg org.jetbrains.kotlin kotlin-maven-noarg ${kotlin.version} ``` 标签: hibernate search