Spring Boot 2 с Hibernate Search, индексы не создаются при сохранении - PullRequest
0 голосов
/ 05 марта 2020

Я определил сущность, как показано ниже. Если я использую 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 для получения результатов по идентификатору, но в моем случае мне нужно искать по встроенному идентификатору, чтобы ограничить результаты поиска. (зависит от роли пользователя), поэтому для меня это не вариант.

И я не понимаю, почему работает ручное индексирование ...

Ответы [ 2 ]

0 голосов
/ 06 марта 2020

Кстати: как выполнить запрос / поиск по вложенному индексируемому идентификатору документа? В моем случае это customer.id, который является DocumentId. Я пытался изменить запрос, как показано ниже, но не получил никакого результата. Должен ли я создать новое поле для запроса?

Обычно не требуется для создания отдельного поля, если все, что вам нужно, это выполнить точное совпадение.

Можем ли мы искать и Сортировка по id простым способом

Поиск, да, по крайней мере, в Hibernate Search 5.

Сортировка, нет: вам нужно выделенное поле.

или это лучшая практика?

Лучше всего объявлять поле рядом с @DocumentId, если вам нужно что-то более сложное, чем точное совпадение по идентификатору.

Я знаю, что мы должны использовать нативные функции JPA для получения результатов по id

Я не уверен, что понимаю, что вы подразумеваете под "нативными функциями JPA".

но в моем случае мне нужно искать по встроенному идентификатору, чтобы ограничить результаты поиска. (зависит от роли пользователя)

Да, это должно работать. То есть он должен работать, если идентификатор заполнен правильно.

И я не понимаю, почему работает ручное индексирование ...

Я тоже, но я Предположим, что объяснение кроется в «ошибке в определении поля« pid ». Может быть, в некоторых случаях идентификатор не заполнялся должным образом, что приводило к тому, что Hibernate Search считал сущность удаленной?

Если я хочу, чтобы я дал вам точный ответ, лучший способ получить его - создать репродуктор. Вы можете использовать это как шаблон: https://github.com/hibernate/hibernate-test-case-templates/tree/master/search

0 голосов
/ 05 марта 2020

Это выглядит странно:

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

Я бы ожидал длинный, обнуляемый, инициализированный до null (или что-то эквивалентное Kotlin).

Я не конечно, это проблема, но я предполагаю, что это может быть, поскольку ненулевой идентификатор обычно ожидается только от уже существующего объекта.

Кроме этого, я думаю, что вы на правильном пути: если Массовая индексация работает, но не автоматическая c индексация, это может быть связано с тем, что ваши изменения не выполняются в транзакциях базы данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...