Search code examples
hibernatespring-boothibernate-search

Hibernate Search and Criteria Builder Update


i have a problem in hibernate search since when i update a field using criteria builder 1 by 1 without using its class it doesn't update its index in hibernate search can you please enlighten me about why this happens ? thank you.

val builder: CriteriaBuilder = entityManager.criteriaBuilder
val criteria: CriteriaUpdate<Profile> = builder.createCriteriaUpdate(Profile::class.java)
val root: Root<Profile> = criteria.from(Profile::class.java)

fname?.let { criteria.set(root.get("firstName"), it) }
lname?.let { criteria.set(root.get("lastName"), it) }
birthdate?.let { criteria.set(root.get("birthDate"), it) }
mname?.let { criteria.set(root.get("middleName"), it) }

criteria.set(root.get("updatedBy"), uid)
   .where(builder.equal(root.get<String>("user").get<String>("id"), uid))
entityManager.createQuery(criteria).executeUpdate()

Solution

  • Hibernate Search's automatic reindexing feature is based on Hibernate ORM events. These events are triggered internally by Hibernate ORM when you create/update/delete an entity directly, using its POJO representation and the Session methods (session.persist, session.delete, ...).

    When you use a criteria update/delete query, your query will be translated to SQL and sent directly to the database. This means Hibernate ORM will not know which entities have been changed exactly, and thus it will not send internal events relative to these changes. So Hibernate Search will not be aware of the changes at all, and will not be able to reindex the entities.

    There is an explanation of this limitation in the documentation of Hibernate Search 6 (currently in Beta): https://docs.jboss.org/hibernate/search/6.0/reference/en-US/html_single/#mapper-orm-indexing-automatic-concepts

    There are two workarounds:

    1. Load the entities into the session to change them. Only makes sense if there are very few entities to change.
    2. As you mentioned in your own answer, trigger reindexing of the entities after the fact using FullTextSession.index.