Question

I have JUnit4 test class, annotated with @Transactional with this method in it, along with other methods:

@Test
public void testDiscoverArtworksByTitle()
{
    FullTextEntityManager ftem = Search.getFullTextEntityManager(this.entityManager);

    this.prepareArtworksForListing();
    ftem.flushToIndexes();

    List<ArtworkListItem> listItems = this.artworkService.discoverArtworksByTitle("Die Hard");
    Assert.assertNotEquals("There are some items in the list", 0, listItems.size());

    // housekeeping
    ftem.purgeAll(ArtworkEntity.class);
}

Basically, I'm building some discovery functionality and I would like to test it properly while developing and mainly later. The point is, this test always fails, as if the index was not built at all. The method prepareArtworksForListing() creates (using persist(..)) some records in HSqlDb in-memory database. Hibernate is wired with H.Search/Lucene properly, because when I annotate this method with @Transactional(propagation = Propagation.NOT_SUPPORTED) and explicitly call em.getTransaction().begin() and em.getTransaction().commit()/.rollback(), the test is passed, BUT THEN subsequent test methods fail with READ_ONLY TX Error, as if the original @Transactional attribute was absent for the class.

Was it helpful?

Solution

I've found a solution and I've realized, how does Lucene/Hibernate Search works in connection with auto-updating indexes. The indexes are updated (internally) on transaction commit, but not directly, but on flush(). Therefore, calling flush() on EntityManager does the trick while keeping @Transactional intact for the class.

So the code should look something like this (I've added some exception handling as well):

@Test
public void testDiscoverArtworksByTitle()
{
    FullTextEntityManager ftem = Search.getFullTextEntityManager(this.entityManager);

    this.prepareArtworksForListing();
    this.entityManager.flush(); // <-- ADDED FLUSH() CALL
    ftem.flushToIndexes();

    try
    {
        List<ArtworkListItem> listItems = this.artworkService.discoverArtworksByTitle("Die Hard");
        Assert.assertNotEquals("There are some items in the list", 0, listItems.size());
    }
    finally
    {
        // housekeeping
        ftem.purgeAll(ArtworkEntity.class);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top