如何修复 Hibernate Search createClient 错误?

How to fix Hibernate Search createClient error?

我正在使用 Spring 开网店,我决定在那里添加文本搜索。我使用本指南尝试了 Hibernate Search https://reflectoring.io/hibernate-search/,但在启动应用程序时出现错误。

这是我的(错误)+ 我的代码如下:

描述:

试图调用不存在的方法。尝试是从以下位置进行的:

org.hibernate.search.elasticsearch.client.impl.DefaultElasticsearchClientFactory.createClient(DefaultElasticsearchClientFactory.java:92)

不存在以下方法:

org.elasticsearch.client.RestClientBuilder.setMaxRetryTimeoutMillis(I)Lorg/elasticsearch/client/RestClientBuilder;

方法的 class、org.elasticsearch.client.RestClientBuilder 可从以下位置获得:

jar:file:/C:/Users/myuser/.m2/repository/org/elasticsearch/client/elasticsearch-rest-client/7.9.3/elasticsearch-rest-client-7.9.3.jar!/org/elasticsearch/client/RestClientBuilder.class

class 层次结构是从以下位置加载的:

org.elasticsearch.client.RestClientBuilder: file:/C:/Users/myuser/.m2/repository/org/elasticsearch/client/elasticsearch-rest-client/7.9.3/elasticsearch-rest-client-7.9.3.jar

操作:

更正应用程序的 class 路径,使其包含 org.elasticsearch.client.RestClientBuilder

的单一兼容版本

我创建了 classes(由于指南): Item.class

@Data
@Entity
@Component
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "items")
@Indexed(index = "items")
@NormalizerDef(name = "lowercase", filters = @TokenFilterDef(factory = LowerCaseFilterFactory.class))
public class Item {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long itemId;

    @Field(name = "name", analyzer = @Analyzer(definition = "stop"))
    private String itemName;

    @Field(name = "description", analyzer = @Analyzer(definition = "stop"))
    @Field(name = "name", analyzer = @Analyzer(definition = "stop"))
    private String itemDesc;

    @Field(normalizer = @Normalizer(definition = "lowercase"))
    @Enumerated(EnumType.STRING)
    private ItemCategory itemCategory;

IndexingService.class

@Service
@RequiredArgsConstructor
@Slf4j
public class IndexingService {

    private final EntityManager em;

    @Transactional  // check
    public void initiateIndexing() throws InterruptedException {
        log.info("Initiating indexing...");
        FullTextEntityManager fullTextEntityManager =
                Search.getFullTextEntityManager(em);
        fullTextEntityManager.createIndexer().startAndWait();
        log.info("All entities indexed");
    }
}

SearchService.class

@Component
@Slf4j
@RequiredArgsConstructor
public class SearchService {

    private final EntityManager entityManager;

    public List<Item> getItemBasedOnWord(String word){
        FullTextEntityManager fullTextEntityManager =
                Search.getFullTextEntityManager(entityManager);

        QueryBuilder qb = fullTextEntityManager
                .getSearchFactory()
                .buildQueryBuilder()
                .forEntity(Item.class)
                .get();

        Query itemQuery = qb.keyword()
                .onFields("name","description")
                .matching(word)
                .createQuery();

        FullTextQuery fullTextQuery = fullTextEntityManager
                .createFullTextQuery(itemQuery, Item.class);
        return (List<Item>) fullTextQuery.getResultList();
    }
}

StartupEvent.class

@Component
@Slf4j
@RequiredArgsConstructor
public class StartupEvent implements ApplicationListener<ApplicationReadyEvent> {

    private final IndexingService indexingService;

    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        try {
            indexingService.initiateIndexing();
        } catch (InterruptedException ex){
            log.error("Failed to reindex entities ", ex);
        }
    }
}

最后是 Elasticsearch 配置 class:

@Configuration
public class EsConfig {

    @Bean
    public Client client() throws UnknownHostException {
        Settings settings = Settings.builder().put("cluster.name", "elasticsearch").put("client.transport.sniff", true).build();
        TransportClient transportClient = new PreBuiltTransportClient(settings);
        transportClient.addTransportAddress(new TransportAddress(InetAddress.getByName("localhost"), 9200)); // 9300
        return transportClient;
    }
}

我应该在这里添加什么来防止这个错误? 如果您需要,我可以添加其他代码。 希望你们能帮助我,伙计们!

您使用的是旧版 Hibernate Search 5,最新版本 Spring。

Hibernate Search 5 较旧,依赖于旧版本的 Elasticsearch 客户端 JAR。

您的 Spring 版本取决于更新的、不兼容的 Elasticsearch 客户端 JAR 版本。

两种解决方案:

  1. 升级到更新的 Hibernate Search 6,这很可能取决于与 Spring 捆绑的版本兼容的 Elasticsearch 版本。 请注意,仅更改版本是不够的:组 ID、工件 ID 和 API 是不同的。参见 the migration guide

  2. 或尝试降级到旧版本的 Elasticsearch 客户端。例如,使用 Spring Boot:

    <properties>
        <elasticsearch.version>5.6.16</elasticsearch.version>
        <!-- ... plus any other properties of yours ... -->
    </properties>