我有一个如下定义的实体。如果我使用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())
我找到了解决方案,现在也获得了新插入的数据。 “ 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进行搜索以限制搜索结果。 (取决于用户的角色),因此这不是我的选择。
而且我不明白为什么手动索引有效...
这看起来很奇怪:
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long = -1,
我希望可以为null的long,可以初始化为null
(或Kotlin的等价物。)>
我不确定这是问题所在,但我想可能是这样,因为通常只能从已经存在的实体中获得非空ID。
除此之外,我认为您走在正确的轨道上:如果批量索引有效但不能自动索引,则可能与数据库事务中未执行的更改有关。
BTW:如何通过嵌套的索引文档ID进行查询/搜索?在我的情况下是customer.id,即DocumentId。我试图像下面那样更改查询,但是没有任何结果,我应该创建一个新字段进行查询吗?