带有Hibernate Search的Spring Boot 2,不会在保存时创建索引

问题描述 投票:0回答:2

我有一个如下定义的实体。如果我使用save(),Hibernate不会为新创建的实体创建新索引。更新/修改现有实体效果很好,并且符合预期。

我正在使用带有弹簧靴2的kotling。

@Entity(name = "shipment")
@Indexed
data class Shipment(
        @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long = -1,
        @JoinColumn(name = "user") @ManyToOne() var user: User?,
        @IndexedEmbedded
        @JoinColumn(name = "sender") @ManyToOne(cascade = [CascadeType.ALL]) val sender: Contact,
        @IndexedEmbedded
        @JoinColumn(name = "sender_information") @ManyToOne(cascade = [CascadeType.ALL]) val senderInformation: ShipmentInformation,
) {}

保存功能,我正在使用相同的功能来更新我的实体,如果索引存在,索引也会更新。

    @Transactional
    fun save(user: User, shipment: Shipment): Shipment {
        shipment.user = user;
        return this.shipmentRepository.save(shipment)
    }

application.properties

spring.jpa.properties.hibernate.search.default.directory_provider=filesystem
spring.jpa.properties.hibernate.search.default.indexBase=./lucene/
spring.jpa.open-in-view=false

如果我重新启动服务器,则手动建立索引也可以。

    @Transactional
    override fun onApplicationEvent(event: ApplicationReadyEvent) {
        val fullTextEntityManager: FullTextEntityManager = Search.getFullTextEntityManager(entityManager)
        fullTextEntityManager.createIndexer().purgeAllOnStart(true)
        fullTextEntityManager.createIndexer().optimizeAfterPurge(true)
        fullTextEntityManager.createIndexer().batchSizeToLoadObjects(15)
        fullTextEntityManager.createIndexer().cacheMode(CacheMode.IGNORE)
        fullTextEntityManager.createIndexer().threadsToLoadObjects(2)
        fullTextEntityManager.createIndexer().typesToIndexInParallel(2)
        fullTextEntityManager.createIndexer().startAndWait()
        return
    }

我试图强迫使用JPA事务管理器,但是它没有帮助我。

    @Bean(name = arrayOf("transactionManager"))
    @Primary
    fun transactionManager(@Autowired entityManagerFactory: EntityManagerFactory): org.springframework.orm.jpa.JpaTransactionManager {
        return JpaTransactionManager(entityManagerFactory)
    }

更新

我想我找到了为什么没有得到新插入的实体的结果。

我的搜索查询在声明的“ pid”字段中有一个条件:

        @Field(index = Index.YES, analyze = Analyze.NO, store = Store.NO)
        @SortableField
        @Column(name = "id", updatable = false, insertable = false)
        @JsonIgnore
        @NumericField val pid: Long,

和查询:

query.must(queryBuilder.keyword().onField("customer.pid").matching(user.customer.id.toString()).createQuery())

pid不存储,因此新插入的值不可见。这可能是原因吗?

BTW:如何通过嵌套的索引文档ID进行查询/搜索?在我的情况下是customer.id,即DocumentId。我试图像下面那样更改查询,但是没有任何结果,我应该创建一个新字段进行查询吗?

query.must(queryBuilder.keyword().onField("customer.id").matching(user.customer.id.toString()).createQuery())

更新2

我找到了解决方案,现在也获得了新插入的数据。 “ pid”字段的定义存在错误,我已经按照以下方式定义了Fields,并且可以按预期工作。

        @Fields(
                Field(name = "pid", index = Index.YES, analyze = Analyze.YES, store = Store.NO)
        )
        @SortableField(forField = "pid")
        @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long?,

我们可以通过简单的方法对ID进行搜索和排序吗?还是最佳做法?我知道我们应该使用本机JPA函数来按ID获取结果,但就我而言,我需要按嵌入式ID进行搜索以限制搜索结果。 (取决于用户的角色),因此这不是我的选择。

而且我不明白为什么手动索引有效...

spring-boot jpa kotlin hibernate-search
2个回答
0
投票

这看起来很奇怪:

        @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long = -1,

我希望可以为null的long,可以初始化为null(或Kotlin的等价物。)>

我不确定这是问题所在,但我想可能是这样,因为通常只能从已经存在的实体中获得非空ID。

除此之外,我认为您走在正确的轨道上:如果批量索引有效但不能自动索引,则可能与数据库事务中未执行的更改有关。


0
投票

BTW:如何通过嵌套的索引文档ID进行查询/搜索?在我的情况下是customer.id,即DocumentId。我试图像下面那样更改查询,但是没有任何结果,我应该创建一个新字段进行查询吗?

© www.soinside.com 2019 - 2024. All rights reserved.