Old version of the entity retrieved although index was updated

Hello,

I am testing (using HS 6.0.2.Final) a simple simple entity update and I ran into this problem.

  • after updating the entity, elastic search index is updated : OK
  • and the actual query to elastic search returns the updated information : OK
  • but the searchResult.hits() returns the old version of the entity
Book book = new Book();
		book.setId(UUID.randomUUID());
		book.setTitle("space");
		book.setGenre("Sci-Fi");
		bookRepository.save(book);
		List<Book> books = bookSearch.getByTitle("space");
		print(books);
		// actual: result books size = 1
		// OK

		book.setTitle("2001: Space Odyssey");
		book.setGenre("Sci-Fi");
		bookRepository.save(book);
		books = bookSearch.getByTitle("space");
		print(books);
		// actual: result books size = 1 with title = "space"
		// KO: should have been size size = 1 with title = "2001: Space Odyssey"

		book.setTitle("2010: Odyssey Two");
		book.setGenre("Sci-Fi");
		bookRepository.save(book);
		books = bookSearch.getByTitle("space");
		print(books);
		// actual: size = 0
		// OK: size = 0
		books = bookSearch.getByTitle("2001: Space Odyssey");
		print(books);
		// actual: books size = 1 with title = "2001: Space Odyssey"
		// KO: should have been "2010: Odyssey Two"

		bookRepository.delete(book);

		assertEquals(books.get(0).getTitle(), "2010: Odyssey Two");

Actual log response from elastic search

2021-04-16 10:30:30.747 DEBUG 2354 --- [port thread - 1] org.apache.http.wire                     : http-outgoing-0 >> "{"genre":"Sci-Fi","id":"397e18b3-96c7-4439-bccd-9f36e3e8da03","title":"space","_entity_type":"Book"}[\n]"
2021-04-16 10:30:31.023 DEBUG 2354 --- [port thread - 1] org.apache.http.wire                     : http-outgoing-0 >> "{"genre":"Sci-Fi","id":"397e18b3-96c7-4439-bccd-9f36e3e8da03","title":"2001: Space Odyssey","_entity_type":"Book"}[\n]"
2021-04-16 10:30:31.116 DEBUG 2354 --- [port thread - 1] org.apache.http.wire                     : http-outgoing-0 >> "{"genre":"Sci-Fi","id":"397e18b3-96c7-4439-bccd-9f36e3e8da03","title":"2010: Odyssey Two","_entity_type":"Book"}[\n]"

I put the example in github GitHub - jcantonio/hibernate-search-tests: Testing Hibernate-Search

Thanks.

This whole behavior is caused by a wrong use of EntityManager in BookSearch:

    public BookSearch(final EntityManagerFactory entityManagerFactory) {
        this.entityManager = entityManagerFactory.createEntityManager();

    }

You’re creating a single entity manager, and reusing it forever.
The first time you search, a book will be retrieved from the database, and put into the session.
The next time you search, the book will still be in the session, and will get reused. Without being updated, since it’s the same session.

So you will always get the same content in your entities.

Try this instead:

@PersistenceContext
EntityManager entityManager;

    public BookSearch() {
    }

And encapsulate the various phases of your tests in transactions. This will save you a lot of headaches…

@SpringBootTest
class HibernateSearchApplicationTests {

    @Autowired
    BookRepository bookRepository;

    @Autowired
    BookSearch bookSearch;

    @Autowired
    TransactionTemplate transactionTemplate;

    @Test
    void crudTest() {
        UUID bookId = UUID.randomUUID();

        transactionTemplate.execute(ignored -> {
            Book book = new Book();
            book.setId(bookId);
            book.setTitle("space");
            book.setGenre("Sci-Fi");
            bookRepository.save(book);
            return null;
        });
        transactionTemplate.execute(ignored -> {
            List<Book> books = bookSearch.getByTitle("space");
            print(books);
            // actual: result books size = 0
            // should have been size = 1
            return null;
        });

        transactionTemplate.execute(ignored -> {
            Book book = bookRepository.findById(bookId).get();
            book.setTitle("2001: Space Odyssey");
            book.setGenre("Sci-Fi");
            bookRepository.save(book);
            return null;
        });
        transactionTemplate.execute(ignored -> {
            List<Book> books = bookSearch.getByTitle("space");
            print(books);
            // actual: result books size = 1 with title = "space"
            // KO: should have been size size = 1 with title = "2001: Space Odyssey"
            return null;
        });

        transactionTemplate.execute(ignored -> {
            Book book = bookRepository.findById(bookId).get();
            book.setTitle("2010: Odyssey Two");
            book.setGenre("Sci-Fi");
            bookRepository.save(book);
            return null;
        });

        transactionTemplate.execute(ignored -> {
            List<Book> books = bookSearch.getByTitle("space");
            print(books);
            // actual: size = 0
            // OK: size = 0
            return null;
        });
        transactionTemplate.execute(ignored -> {
            List<Book> books = bookSearch.getByTitle("2001: Space Odyssey");
            print(books);
            // actual: books size = 1 with title = "2001: Space Odyssey"
            // KO: should have been "2010: Odyssey Two"
            assertEquals(books.get(0).getTitle(), "2010: Odyssey Two");
            return null;
        });

        transactionTemplate.execute(ignored -> {
            Book book = bookRepository.findById(bookId).get();
            bookRepository.delete(book);
            return null;
        });
    }

    private void print(List<Book> books) {
        System.out.println("----- Size: " + books.size());
        if (books.size() > 0) {
            System.out.println("------- Title: " + books.get(0).toString());
        }
    }
}

Thank you Yoann for your help and your fast response.