org.hibernate.search.test.reader.nrtreaders.BasicNRTFunctionalityTest.java Source code

Java tutorial

Introduction

Here is the source code for org.hibernate.search.test.reader.nrtreaders.BasicNRTFunctionalityTest.java

Source

/* 
 * Hibernate, Relational Persistence for Idiomatic Java
 * 
 * JBoss, Home of Professional Open Source
 * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors
 * as indicated by the @authors tag. All rights reserved.
 * See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU Lesser General Public License, v. 2.1.
 * This program is distributed in the hope that it will be useful, but WITHOUT A
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public License,
 * v.2.1 along with this distribution; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA  02110-1301, USA.
 */
package org.hibernate.search.test.reader.nrtreaders;

import java.util.List;

import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.search.Environment;
import org.hibernate.search.FullTextQuery;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.hibernate.search.engine.spi.SearchFactoryImplementor;
import org.hibernate.search.exception.ErrorHandler;
import org.hibernate.search.indexes.impl.NRTIndexManager;
import org.hibernate.search.indexes.spi.IndexManager;
import org.hibernate.search.query.dsl.QueryBuilder;
import org.hibernate.search.test.AlternateDocument;
import org.hibernate.search.test.Document;
import org.hibernate.search.test.SearchTestCase;
import org.hibernate.search.test.errorhandling.MockErrorHandler;
import org.hibernate.search.util.impl.ContextHelper;
import org.junit.Assert;

/**
 * Strongly inspired to RamDirectoryTest, verifies the searchability of unflushed
 * modifications on an NRT IndexManager.
 * Implicitly verifies that the NRTIndexManager is setup as configured.
 * 
 * @author Sanne Grinovero <sanne@hibernate.org> (C) 2011 Red Hat Inc.
 */
public class BasicNRTFunctionalityTest extends SearchTestCase {

    /**
     * Verify it's safe to not skip deletes even when a new entity
     * is stored reusing a stale documentId.
     */
    public void testEntityResurrection() {
        final Long id = 5l;
        Session session = getSessions().openSession();
        session.getTransaction().begin();

        AlternateDocument docOnInfinispan = new AlternateDocument(id, "On Infinispan", "a book about Infinispan",
                "content");
        session.persist(docOnInfinispan);
        session.getTransaction().commit();
        session.clear();

        session.getTransaction().begin();
        FullTextSession fullTextSession = Search.getFullTextSession(session);
        QueryBuilder queryBuilder = fullTextSession.getSearchFactory().buildQueryBuilder()
                .forEntity(AlternateDocument.class).get();
        Query luceneQuery = queryBuilder.keyword().onField("Abstract").matching("Infinispan").createQuery();
        List list = fullTextSession.createFullTextQuery(luceneQuery).list();
        Assert.assertEquals(1, list.size());
        session.getTransaction().commit();
        session.clear();

        session.getTransaction().begin();
        Object loadedDocument = session.load(AlternateDocument.class, id);
        session.delete(loadedDocument);
        session.getTransaction().commit();
        session.clear();

        session.getTransaction().begin();
        list = fullTextSession.createFullTextQuery(luceneQuery).list();
        Assert.assertEquals(0, list.size());

        AlternateDocument docOnHibernate = new AlternateDocument(id, "On Hibernate", "a book about Hibernate",
                "content");
        session.persist(docOnHibernate);
        session.getTransaction().commit();

        session.getTransaction().begin();
        list = fullTextSession.createFullTextQuery(luceneQuery).list();
        Assert.assertEquals(0, list.size());

        session.close();
    }

    public void testMultipleEntitiesPerIndex() throws Exception {
        SearchFactoryImplementor searchFactoryBySFI = ContextHelper
                .getSearchFactoryBySFI((SessionFactoryImplementor) getSessions());
        IndexManager documentsIndexManager = searchFactoryBySFI.getAllIndexesManager().getIndexManager("Documents");
        Assert.assertNotNull(documentsIndexManager);
        Assert.assertTrue(
                documentsIndexManager.getClass().equals(org.hibernate.search.indexes.impl.NRTIndexManager.class));
        NRTIndexManager indexManager = (NRTIndexManager) documentsIndexManager;

        Session s = getSessions().openSession();
        s.getTransaction().begin();
        Document document = new Document("Hibernate in Action", "Object/relational mapping with Hibernate",
                "blah blah blah");
        s.persist(document);
        s.flush();
        s.persist(new AlternateDocument(document.getId(), "Hibernate in Action",
                "Object/relational mapping with Hibernate", "blah blah blah"));
        s.getTransaction().commit();
        s.close();

        assertEquals(0, getDocumentNbrFromFilesystem(indexManager));
        assertEquals(2, getDocumentNbrFromReaderProvider(indexManager));

        s = getSessions().openSession();
        s.getTransaction().begin();
        TermQuery q = new TermQuery(new Term("alt_title", "hibernate"));
        assertEquals("does not properly filter", 0,
                Search.getFullTextSession(s).createFullTextQuery(q, Document.class).list().size());
        assertEquals("does not properly filter", 1, Search.getFullTextSession(s)
                .createFullTextQuery(q, Document.class, AlternateDocument.class).list().size());
        s.delete(s.get(AlternateDocument.class, document.getId()));
        s.getTransaction().commit();
        s.close();

        s = getSessions().openSession();
        s.getTransaction().begin();

        assertEquals(0, getDocumentNbrFromFilesystem(indexManager)); //filesystem only sees changes from a fully closed IW
        assertEquals(1, getDocumentNbrFromQuery(s)); //Hibernate Search has to return the right answer
        assertEquals(1, getDocumentNbrFromReaderProvider(indexManager)); //In-memory buffers might fail to see deletes

        s.delete(s.createCriteria(Document.class).uniqueResult());
        s.getTransaction().commit();
        s.close();

        s = getSessions().openSession();
        s.getTransaction().begin();

        assertEquals(0, getDocumentNbrFromFilesystem(indexManager));
        assertEquals(0, getDocumentNbrFromQuery(s));
        assertEquals(0, getDocumentNbrFromReaderProvider(indexManager));

        s.getTransaction().commit();
        s.close();

        ErrorHandler errorHandler = searchFactoryBySFI.getErrorHandler();
        Assert.assertTrue(errorHandler instanceof MockErrorHandler);
        MockErrorHandler mockErrorHandler = (MockErrorHandler) errorHandler;
        Assert.assertNull("Errors detected in the backend!", mockErrorHandler.getLastException());
    }

    private int getDocumentNbrFromQuery(Session currentSession) {
        MatchAllDocsQuery luceneQuery = new MatchAllDocsQuery();
        FullTextQuery fullTextQuery = Search.getFullTextSession(currentSession).createFullTextQuery(luceneQuery,
                Document.class);
        return fullTextQuery.list().size();
    }

    private int getDocumentNbrFromReaderProvider(NRTIndexManager indexManager) {
        IndexReader reader = indexManager.getReaderProvider().openIndexReader();
        try {
            return reader.numDocs();
        } finally {
            indexManager.getReaderProvider().closeIndexReader(reader);
        }
    }

    private int getDocumentNbrFromFilesystem(NRTIndexManager documentsIndexManager) throws Exception {
        IndexReader reader = IndexReader.open(documentsIndexManager.getDirectoryProvider().getDirectory(), true);
        try {
            return reader.numDocs();
        } finally {
            reader.close();
        }
    }

    protected Class<?>[] getAnnotatedClasses() {
        return new Class[] { Document.class, AlternateDocument.class };
    }

    protected void configure(Configuration cfg) {
        super.configure(cfg);
        cfg.setProperty("hibernate.search.default.indexmanager", "near-real-time");
        cfg.setProperty(Environment.ERROR_HANDLER, MockErrorHandler.class.getName());
    }

}