Я определил сущность, как показано ниже. Если я использую save (), Hibernate не создает новый индекс для вновь созданной сущности. Обновление / изменение существующего объекта работает хорошо и, как и ожидалось.
Я использую kotling с пружинной загрузкой 2.
@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 не сохраняется и поэтому вновь вставленные значения не видны Может ли это быть причиной?
Кстати: как выполнить запрос / поиск по вложенному индексируемому идентификатору документа? В моем случае это 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?,
Можем ли мы искать и сортировать по идентификатору простым способом или это лучшая практика? Я знаю, что мы должны использовать встроенные функции JPA для получения результатов по идентификатору, но в моем случае мне нужно искать по встроенному идентификатору, чтобы ограничить результаты поиска. (зависит от роли пользователя), поэтому для меня это не вариант.
И я не понимаю, почему работает ручное индексирование ...