【发布时间】:2020-03-04 23:28:43
【问题描述】:
我有一个如下定义的实体。如果我使用 save() Hibernate 不会为新创建的实体创建新索引。更新/修改现有实体效果很好,符合预期。
我正在使用带有 spring boot 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 未存储,因此新插入的值不可见。这可能是原因吗?
顺便说一句:如何按嵌套索引文档 ID 查询/搜索?在我的例子中,customer.id 是 DocumentId。我尝试更改如下查询但没有得到任何结果,我应该创建一个新字段来查询吗?
query.must(queryBuilder.keyword().onField("customer.id").matching(user.customer.id.toString()).createQuery())
更新 2
我找到了一个解决方案,现在也得到了新插入的数据。 “pid”字段的定义出错,我已将我的字段定义如下,它按预期工作。
@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