[hibernate-commits] Hibernate SVN: r11531 - in trunk/HibernateExt/search/src: java/org/hibernate/search/engine and 3 other directories.
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Wed May 16 18:25:22 EDT 2007
Author: epbernard
Date: 2007-05-16 18:25:22 -0400 (Wed, 16 May 2007)
New Revision: 11531
Added:
trunk/HibernateExt/search/src/java/org/hibernate/search/FullTextQuery.java
trunk/HibernateExt/search/src/java/org/hibernate/search/engine/DocumentExtractor.java
trunk/HibernateExt/search/src/java/org/hibernate/search/engine/EntityInfo.java
trunk/HibernateExt/search/src/java/org/hibernate/search/engine/Loader.java
trunk/HibernateExt/search/src/java/org/hibernate/search/engine/ObjectLoader.java
trunk/HibernateExt/search/src/java/org/hibernate/search/engine/ProjectionLoader.java
trunk/HibernateExt/search/src/java/org/hibernate/search/engine/QueryLoader.java
Removed:
trunk/HibernateExt/search/src/java/org/hibernate/search/query/EntityInfo.java
trunk/HibernateExt/search/src/java/org/hibernate/search/query/FullTextQuery.java
Modified:
trunk/HibernateExt/search/src/java/org/hibernate/search/FullTextSession.java
trunk/HibernateExt/search/src/java/org/hibernate/search/engine/DocumentBuilder.java
trunk/HibernateExt/search/src/java/org/hibernate/search/impl/FullTextSessionImpl.java
trunk/HibernateExt/search/src/java/org/hibernate/search/query/FullTextQueryImpl.java
trunk/HibernateExt/search/src/java/org/hibernate/search/query/IteratorImpl.java
trunk/HibernateExt/search/src/java/org/hibernate/search/query/ScrollableResultsImpl.java
trunk/HibernateExt/search/src/test/org/hibernate/search/test/query/LuceneQuerySortTest.java
trunk/HibernateExt/search/src/test/org/hibernate/search/test/query/LuceneQueryTest.java
Log:
HSEARCH-51 Use where id in (...) rather than the load() then initialize approach
Copied: trunk/HibernateExt/search/src/java/org/hibernate/search/FullTextQuery.java (from rev 11519, trunk/HibernateExt/search/src/java/org/hibernate/search/query/FullTextQuery.java)
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/FullTextQuery.java (rev 0)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/FullTextQuery.java 2007-05-16 22:25:22 UTC (rev 11531)
@@ -0,0 +1,38 @@
+//$Id: $
+package org.hibernate.search;
+
+import org.apache.lucene.search.Sort;
+import org.hibernate.Query;
+
+/**
+ * The base interface for lucene powered searches.
+ *
+ * @author Hardy Ferentschik
+ */
+//TODO return FullTextQuery rather than Query in useful chain methods
+public interface FullTextQuery extends Query {
+ //todo Determine what other lucene specific features to expose via this
+ // interface. Maybe we should give access to the underlying lucene hit
+ // objects?
+
+ /**
+ * Allows to let lucene sort the results. This is useful when you have
+ * additional sort requirements on top of the default lucene ranking.
+ * Without lucene sorting you would have to retrieve the full result set and
+ * order the hibernate objects.
+ *
+ * @param sort The lucene sort object.
+ * @return this for method chaining
+ */
+ FullTextQuery setSort(Sort sort);
+
+ /**
+ * Returns the number of hits for this search
+ *
+ * Caution:
+ * The number of results might be slightly different from
+ * <code>list().size()</code> because list() if the index is
+ * not in sync with the database at the time of query.
+ */
+ int resultSize();
+}
Modified: trunk/HibernateExt/search/src/java/org/hibernate/search/FullTextSession.java
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/FullTextSession.java 2007-05-16 15:32:33 UTC (rev 11530)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/FullTextSession.java 2007-05-16 22:25:22 UTC (rev 11531)
@@ -2,8 +2,7 @@
package org.hibernate.search;
import org.hibernate.classic.Session;
-import org.hibernate.Query;
-import org.hibernate.search.query.FullTextQuery;
+import org.hibernate.search.FullTextQuery;
/**
* Extends the Hibernate {@link Session} with Full text search and indexing capabilities
Modified: trunk/HibernateExt/search/src/java/org/hibernate/search/engine/DocumentBuilder.java
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/engine/DocumentBuilder.java 2007-05-16 15:32:33 UTC (rev 11530)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/engine/DocumentBuilder.java 2007-05-16 22:25:22 UTC (rev 11531)
@@ -19,12 +19,12 @@
import org.apache.lucene.index.Term;
import org.hibernate.Hibernate;
import org.hibernate.annotations.common.AssertionFailure;
-import org.hibernate.annotations.common.util.ReflectHelper;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.annotations.common.reflection.XAnnotatedElement;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XMember;
import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.annotations.common.util.ReflectHelper;
import org.hibernate.search.SearchException;
import org.hibernate.search.SearchFactory;
import org.hibernate.search.annotations.Boost;
@@ -109,6 +109,10 @@
}
}
+ public String getIdentifierName() {
+ return idGetter.getName();
+ }
+
private void initializeMember(XProperty member, PropertiesMetadata propertiesMetadata, boolean isRoot,
String prefix, Set<XClass> processedClasses) {
Keyword keywordAnn = member.getAnnotation( Keyword.class );
Added: trunk/HibernateExt/search/src/java/org/hibernate/search/engine/DocumentExtractor.java
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/engine/DocumentExtractor.java (rev 0)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/engine/DocumentExtractor.java 2007-05-16 22:25:22 UTC (rev 11531)
@@ -0,0 +1,24 @@
+//$Id: $
+package org.hibernate.search.engine;
+
+import org.apache.lucene.document.Document;
+import org.hibernate.search.SearchFactory;
+import org.hibernate.search.engine.EntityInfo;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class DocumentExtractor {
+ private SearchFactory searchFactory;
+ public DocumentExtractor(SearchFactory searchFactory) {
+ this.searchFactory = searchFactory;
+ }
+
+ public EntityInfo extract(Document document, String... fields) {
+ EntityInfo entityInfo = new EntityInfo();
+ entityInfo.clazz = DocumentBuilder.getDocumentClass( document );
+ entityInfo.id = DocumentBuilder.getDocumentId( searchFactory, entityInfo.clazz, document );
+ //TODO read fields
+ return entityInfo;
+ }
+}
Copied: trunk/HibernateExt/search/src/java/org/hibernate/search/engine/EntityInfo.java (from rev 11296, trunk/HibernateExt/search/src/java/org/hibernate/search/query/EntityInfo.java)
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/engine/EntityInfo.java (rev 0)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/engine/EntityInfo.java 2007-05-16 22:25:22 UTC (rev 11531)
@@ -0,0 +1,15 @@
+//$Id: $
+package org.hibernate.search.engine;
+
+import java.io.Serializable;
+
+/**
+ *
+ * @author Emmanuel Bernard
+ */
+//Move to egine?
+public class EntityInfo {
+ public Class clazz;
+ public Serializable id;
+ public Object[] projection;
+}
Added: trunk/HibernateExt/search/src/java/org/hibernate/search/engine/Loader.java
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/engine/Loader.java (rev 0)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/engine/Loader.java 2007-05-16 22:25:22 UTC (rev 11531)
@@ -0,0 +1,17 @@
+//$Id: $
+package org.hibernate.search.engine;
+
+import java.util.List;
+
+import org.hibernate.Session;
+import org.hibernate.search.SearchFactory;
+import org.hibernate.search.engine.EntityInfo;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public interface Loader {
+ void init(Session session, SearchFactory searchFactory);
+ Object load(EntityInfo entityInfo);
+ List load(EntityInfo... entityInfos);
+}
Added: trunk/HibernateExt/search/src/java/org/hibernate/search/engine/ObjectLoader.java
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/engine/ObjectLoader.java (rev 0)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/engine/ObjectLoader.java 2007-05-16 22:25:22 UTC (rev 11531)
@@ -0,0 +1,50 @@
+//$Id: $
+package org.hibernate.search.engine;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Hibernate;
+import org.hibernate.ObjectNotFoundException;
+import org.hibernate.Session;
+import org.hibernate.search.SearchFactory;
+import org.hibernate.search.engine.EntityInfo;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class ObjectLoader implements Loader {
+ private static final Log log = LogFactory.getLog( ObjectLoader.class );
+ private Session session;
+
+ public void init(Session session, SearchFactory searchFactory) {
+ this.session = session;
+ }
+
+ public Object load(EntityInfo entityInfo) {
+ return session.get( entityInfo.clazz, entityInfo.id );
+ }
+
+ public List load(EntityInfo... entityInfos) {
+ //use load to benefit from the batch-size
+ //we don't face proxy casting issues since the exact class is extracted from the index
+ for (EntityInfo entityInfo : entityInfos) {
+ session.load( entityInfo.clazz, entityInfo.id );
+ }
+ List result = new ArrayList(entityInfos.length);
+ for (EntityInfo entityInfo : entityInfos) {
+ try {
+ Object entity = session.load( entityInfo.clazz, entityInfo.id );
+ Hibernate.initialize( entity );
+ result.add( entity );
+ }
+ catch (ObjectNotFoundException e) {
+ log.debug( "Object found in Search index but not in database: "
+ + e.getEntityName() + " wih id " + e.getIdentifier() );
+ }
+ }
+ return result;
+ }
+}
Added: trunk/HibernateExt/search/src/java/org/hibernate/search/engine/ProjectionLoader.java
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/engine/ProjectionLoader.java (rev 0)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/engine/ProjectionLoader.java 2007-05-16 22:25:22 UTC (rev 11531)
@@ -0,0 +1,29 @@
+//$Id: $
+package org.hibernate.search.engine;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hibernate.Session;
+import org.hibernate.search.SearchFactory;
+import org.hibernate.search.engine.EntityInfo;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class ProjectionLoader implements Loader {
+ public void init(Session session, SearchFactory searchFactory) {
+ }
+
+ public Object load(EntityInfo entityInfo) {
+ return entityInfo.projection;
+ }
+
+ public List load(EntityInfo... entityInfos) {
+ List results = new ArrayList(entityInfos.length);
+ for (EntityInfo entityInfo : entityInfos) {
+ results.add( entityInfo.projection );
+ }
+ return results;
+ }
+}
Added: trunk/HibernateExt/search/src/java/org/hibernate/search/engine/QueryLoader.java
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/engine/QueryLoader.java (rev 0)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/engine/QueryLoader.java 2007-05-16 22:25:22 UTC (rev 11531)
@@ -0,0 +1,83 @@
+//$Id: $
+package org.hibernate.search.engine;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.Hibernate;
+import org.hibernate.annotations.common.AssertionFailure;
+import org.hibernate.criterion.Disjunction;
+import org.hibernate.criterion.Restrictions;
+import org.hibernate.search.SearchFactory;
+import org.hibernate.search.engine.EntityInfo;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class QueryLoader implements Loader {
+ private static final Log log = LogFactory.getLog( QueryLoader.class );
+ private static final int MAX_IN_CLAUSE = 500;
+ private static final List EMPTY_LIST = new ArrayList(0);
+
+ private Session session;
+ private Class entityType;
+ private SearchFactory searchFactory;
+
+ public void init(Session session, SearchFactory searchFactory) {
+ this.session = session;
+ this.searchFactory = searchFactory;
+ }
+
+ public void setEntityType(Class entityType) {
+ this.entityType = entityType;
+ }
+
+
+
+ public Object load(EntityInfo entityInfo) {
+ return session.get( entityInfo.clazz, entityInfo.id );
+ }
+
+ public List load(EntityInfo... entityInfos) {
+ final int maxResults = entityInfos.length;
+ if ( maxResults == 0) return EMPTY_LIST;
+ if (entityType == null) throw new AssertionFailure("EntityType not defined");
+ Criteria criteria = session.createCriteria( entityType );
+
+ DocumentBuilder builder = searchFactory.getDocumentBuilders().get( entityType );
+ String idName = builder.getIdentifierName();
+ int loop = maxResults / MAX_IN_CLAUSE;
+ boolean exact = maxResults % MAX_IN_CLAUSE == 0;
+ if (!exact) loop++;
+ Disjunction disjunction = Restrictions.disjunction();
+ for (int index = 0 ; index < loop ; index++) {
+ int max = index*MAX_IN_CLAUSE + MAX_IN_CLAUSE <= maxResults ?
+ index*MAX_IN_CLAUSE + MAX_IN_CLAUSE :
+ maxResults;
+ List ids = new ArrayList(max - index*MAX_IN_CLAUSE);
+ for (int entityInfoIndex = index * MAX_IN_CLAUSE ; entityInfoIndex < max ; entityInfoIndex++) {
+ ids.add(entityInfos[entityInfoIndex].id);
+ }
+ disjunction.add( Restrictions.in( idName, ids ) );
+ }
+ criteria.add( disjunction );
+ criteria.setMaxResults( maxResults ); //is it faster
+ criteria.list(); //load all objects
+
+ //mandatory to keep the same ordering
+ List result = new ArrayList(entityInfos.length);
+ for (EntityInfo entityInfo : entityInfos) {
+ Object element = session.load( entityInfo.clazz, entityInfo.id );
+ if ( Hibernate.isInitialized( element ) ) {
+ //all existing elements should have been loaded by the query,
+ //the other ones are missing ones
+ result.add( element );
+ }
+ }
+ return result;
+ }
+}
Modified: trunk/HibernateExt/search/src/java/org/hibernate/search/impl/FullTextSessionImpl.java
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/impl/FullTextSessionImpl.java 2007-05-16 15:32:33 UTC (rev 11530)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/impl/FullTextSessionImpl.java 2007-05-16 22:25:22 UTC (rev 11531)
@@ -42,10 +42,10 @@
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.SearchFactory;
+import org.hibernate.search.FullTextQuery;
import org.hibernate.search.backend.WorkType;
import org.hibernate.search.engine.DocumentBuilder;
import org.hibernate.search.query.FullTextQueryImpl;
-import org.hibernate.search.query.FullTextQuery;
import org.hibernate.search.util.ContextHelper;
import org.hibernate.stat.SessionStatistics;
import org.hibernate.type.Type;
Deleted: trunk/HibernateExt/search/src/java/org/hibernate/search/query/EntityInfo.java
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/query/EntityInfo.java 2007-05-16 15:32:33 UTC (rev 11530)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/query/EntityInfo.java 2007-05-16 22:25:22 UTC (rev 11531)
@@ -1,12 +0,0 @@
-//$Id: $
-package org.hibernate.search.query;
-
-import java.io.Serializable;
-
-/**
- * @author Emmanuel Bernard
- */
-class EntityInfo {
- public Class clazz;
- public Serializable id;
-}
Deleted: trunk/HibernateExt/search/src/java/org/hibernate/search/query/FullTextQuery.java
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/query/FullTextQuery.java 2007-05-16 15:32:33 UTC (rev 11530)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/query/FullTextQuery.java 2007-05-16 22:25:22 UTC (rev 11531)
@@ -1,36 +0,0 @@
-//$Id: $
-package org.hibernate.search.query;
-
-import org.apache.lucene.search.Sort;
-import org.hibernate.Query;
-
-/**
- * The base interface for lucene powered searches.
- *
- * @author Hardy Ferentschik
- */
-public interface FullTextQuery extends Query {
- //todo Determine what other lucene specific features to expose via this
- // interface. Maybe we should give access to the underlying lucene hit
- // objects?
-
- /**
- * Allows to let lucene sort the results. This is useful when you have
- * additional sort requirements on top of the default lucene ranking.
- * Without lucene sorting you would have to retrieve the full result set and
- * order the hibernate objects.
- *
- * @param sort The lucene sort object.
- */
- void setSort(Sort sort);
-
- /**
- * Returns the number of hits for this search
- *
- * Caution:
- * The number of results might be slightly different from
- * <code>list().size()</code> because list() if the index is
- * not in sync with the database at the time of query.
- */
- int resultSize();
-}
Modified: trunk/HibernateExt/search/src/java/org/hibernate/search/query/FullTextQueryImpl.java
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/query/FullTextQueryImpl.java 2007-05-16 15:32:33 UTC (rev 11530)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/query/FullTextQueryImpl.java 2007-05-16 22:25:22 UTC (rev 11531)
@@ -2,7 +2,6 @@
package org.hibernate.search.query;
import java.io.IOException;
-import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@@ -21,26 +20,30 @@
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MultiSearcher;
import org.apache.lucene.search.Searcher;
+import org.apache.lucene.search.Sort;
import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.search.Sort;
import org.apache.lucene.store.Directory;
-import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
-import org.hibernate.ObjectNotFoundException;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.query.ParameterMetadata;
import org.hibernate.impl.AbstractQueryImpl;
+import org.hibernate.search.SearchFactory;
+import org.hibernate.search.FullTextQuery;
import org.hibernate.search.engine.DocumentBuilder;
-import org.hibernate.search.SearchFactory;
+import org.hibernate.search.engine.DocumentExtractor;
+import org.hibernate.search.engine.Loader;
+import org.hibernate.search.engine.ObjectLoader;
+import org.hibernate.search.engine.QueryLoader;
+import org.hibernate.search.engine.EntityInfo;
import org.hibernate.search.util.ContextHelper;
/**
- * Implementation of {@link org.hibernate.search.query.FullTextQuery}
+ * Implementation of {@link org.hibernate.search.FullTextQuery}
*
* @author Emmanuel Bernard
* @author Hardy Ferentschik
@@ -55,7 +58,19 @@
private Integer maxResults;
private Integer resultSize;
private Sort sort;
+ private static Loader noLoader = new Loader() {
+ public void init(Session session, SearchFactory searchFactory) {
+ }
+ public Object load(EntityInfo entityInfo) {
+ throw new UnsupportedOperationException( "noLoader should not be used" );
+ }
+
+ public List load(EntityInfo... entityInfos) {
+ throw new UnsupportedOperationException( "noLoader should not be used" );
+ }
+ };
+
/**
* classes must be immutable
*/
@@ -68,8 +83,9 @@
}
- public void setSort(Sort sort) {
+ public FullTextQuery setSort(Sort sort) {
this.sort = sort;
+ return this;
}
/**
@@ -86,51 +102,68 @@
//find the directories
Searcher searcher = buildSearcher( searchFactory );
if ( searcher == null ) {
- return new IteratorImpl( new ArrayList<EntityInfo>(0), (Session) this.session);
+ return new IteratorImpl( new ArrayList<EntityInfo>(0), noLoader );
}
try {
Hits hits = getHits( searcher );
- setResultSize( hits );
int first = first();
int max = max( first, hits );
+ Session sess = (Session) this.session;
+
List<EntityInfo> entityInfos = new ArrayList<EntityInfo>( max - first + 1 );
+ DocumentExtractor extractor = new DocumentExtractor( searchFactory );
for ( int index = first; index <= max; index++ ) {
Document document = hits.doc( index );
- EntityInfo entityInfo = new EntityInfo();
- entityInfo.clazz = DocumentBuilder.getDocumentClass( document );
- entityInfo.id = DocumentBuilder.getDocumentId( searchFactory, entityInfo.clazz, document );
- entityInfos.add( entityInfo );
+ entityInfos.add( extractor.extract( document ) );
}
- return new IteratorImpl( entityInfos, (Session) this.session );
+ Loader loader = getLoader(sess, searchFactory);
+ return new IteratorImpl( entityInfos, loader );
}
catch (IOException e) {
throw new HibernateException( "Unable to query Lucene index", e );
}
finally {
- try {
- searcher.close();
- } catch (IOException e) {
- log.warn("Unable to properly close searcher during lucene query: " + getQueryString(), e);
- }
- }
+ try {
+ searcher.close();
+ }
+ catch (IOException e) {
+ log.warn( "Unable to properly close searcher during lucene query: " + getQueryString(), e );
+ }
+ }
}
+ private Loader getLoader(Session session, SearchFactory searchFactory) {
+ if (classes.length == 1) {
+ QueryLoader loader = new QueryLoader();
+ loader.init( session, searchFactory );
+ loader.setEntityType( classes[0] );
+ return loader;
+ }
+ else {
+ final ObjectLoader objectLoader = new ObjectLoader();
+ objectLoader.init( session, searchFactory );
+ return objectLoader;
+ }
+ }
+
public ScrollableResults scroll() throws HibernateException {
//keep the searcher open until the resultset is closed
SearchFactory searchFactory = ContextHelper.getSearchFactoryBySFI( session );
-
+
//find the directories
Searcher searcher = buildSearcher( searchFactory );
//FIXME: handle null searcher
Hits hits;
try {
hits = getHits( searcher );
- setResultSize( hits );
int first = first();
int max = max( first, hits );
- return new ScrollableResultsImpl( searcher, hits, first, max, (Session) this.session, searchFactory );
+ DocumentExtractor extractor = new DocumentExtractor( searchFactory );
+ Loader loader = getLoader( (Session) this.session, searchFactory );
+ return new ScrollableResultsImpl( searcher, hits, first, max, extractor, loader);
}
catch (IOException e) {
+ //close only in case of exception
try {
if ( searcher != null ) searcher.close();
}
@@ -154,41 +187,23 @@
Hits hits;
try {
hits = getHits( searcher );
- setResultSize( hits );
int first = first();
int max = max( first, hits );
- List result = new ArrayList( max - first + 1 );
Session sess = (Session) this.session;
+ List<EntityInfo> infos = new ArrayList<EntityInfo>( max - first + 1 );
+ DocumentExtractor extractor = new DocumentExtractor( searchFactory );
for ( int index = first; index <= max; index++ ) {
Document document = hits.doc( index );
- Class clazz = DocumentBuilder.getDocumentClass( document );
- Serializable id = DocumentBuilder.getDocumentId( searchFactory, clazz, document );
- result.add( sess.load( clazz, id ) );
- //use load to benefit from the batch-size
- //we don't face proxy casting issues since the exact class is extracted from the index
+ infos.add( extractor.extract( document ) );
}
- //then initialize the objects
- List excludedObects = new ArrayList();
- for ( Object element : result ) {
- try {
- Hibernate.initialize( element );
- }
- catch (ObjectNotFoundException e) {
- log.debug( "Object found in Search index but not in database: "
- + e.getEntityName() + " wih id " + e.getIdentifier() );
- excludedObects.add( element );
- }
- }
- if ( excludedObects.size() > 0 ) {
- result.removeAll( excludedObects );
- }
- return result;
+ Loader loader = getLoader( sess, searchFactory );
+ return loader.load( infos.toArray( new EntityInfo[infos.size()]) );
}
catch (IOException e) {
throw new HibernateException( "Unable to query Lucene index", e );
}
finally {
- if ( searcher != null ) try {
+ try {
searcher.close();
}
catch (IOException e) {
@@ -213,6 +228,7 @@
else {
hits = searcher.search( query, sort );
}
+ setResultSize( hits );
return hits;
}
@@ -327,7 +343,6 @@
Hits hits;
try {
hits = getHits( searcher );
- setResultSize( hits );
}
catch (IOException e) {
throw new HibernateException( "Unable to query Lucene index", e );
@@ -346,12 +361,12 @@
return this.resultSize;
}
- public Query setFirstResult(int firstResult) {
+ public FullTextQuery setFirstResult(int firstResult) {
this.firstResult = firstResult;
return this;
}
- public Query setMaxResults(int maxResults) {
+ public FullTextQuery setMaxResults(int maxResults) {
this.maxResults = maxResults;
return this;
}
Modified: trunk/HibernateExt/search/src/java/org/hibernate/search/query/IteratorImpl.java
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/query/IteratorImpl.java 2007-05-16 15:32:33 UTC (rev 11530)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/query/IteratorImpl.java 2007-05-16 22:25:22 UTC (rev 11531)
@@ -5,7 +5,8 @@
import java.util.List;
import java.util.NoSuchElementException;
-import org.hibernate.Session;
+import org.hibernate.search.engine.Loader;
+import org.hibernate.search.engine.EntityInfo;
/**
* @author Emmanuel Bernard
@@ -14,16 +15,16 @@
public class IteratorImpl implements Iterator {
private final List<EntityInfo> entityInfos;
- private final Session session;
private int index = 0;
private final int size;
private Object next;
private int nextObjectIndex = -1;
+ private Loader loader;
- public IteratorImpl(List<EntityInfo> entityInfos, Session session) {
+ public IteratorImpl(List<EntityInfo> entityInfos, Loader loader) {
this.entityInfos = entityInfos;
- this.session = session;
this.size = entityInfos.size();
+ this.loader = loader;
}
//side effect is to set up next
@@ -37,7 +38,7 @@
next = null;
return false;
}
- next = session.get( entityInfos.get( index ).clazz, entityInfos.get( index ).id );
+ next = loader.load( entityInfos.get( index ) );
if ( next == null ) {
index++;
}
Modified: trunk/HibernateExt/search/src/java/org/hibernate/search/query/ScrollableResultsImpl.java
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/query/ScrollableResultsImpl.java 2007-05-16 15:32:33 UTC (rev 11530)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/query/ScrollableResultsImpl.java 2007-05-16 22:25:22 UTC (rev 11531)
@@ -9,16 +9,18 @@
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
+import java.util.Map;
import java.util.TimeZone;
+import java.util.HashMap;
import org.apache.lucene.document.Document;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.Searcher;
import org.hibernate.HibernateException;
import org.hibernate.ScrollableResults;
-import org.hibernate.Session;
-import org.hibernate.search.engine.DocumentBuilder;
-import org.hibernate.search.SearchFactory;
+import org.hibernate.search.engine.DocumentExtractor;
+import org.hibernate.search.engine.Loader;
+import org.hibernate.search.engine.EntityInfo;
import org.hibernate.type.Type;
/**
@@ -34,21 +36,23 @@
private final int first;
private final int max;
private int current;
- private final Session session;
private EntityInfo[] entityInfos;
- private final SearchFactory searchFactory;
+ private Loader loader;
+ private DocumentExtractor documentExtractor;
+ private Map<EntityInfo, Object[]> resultContext;
public ScrollableResultsImpl(
- Searcher searcher, Hits hits, int first, int max, Session session, SearchFactory searchFactory
+ Searcher searcher, Hits hits, int first, int max, DocumentExtractor extractor, Loader loader
) {
this.searcher = searcher;
this.hits = hits;
this.first = first;
this.max = max;
this.current = first;
- this.session = session;
- this.searchFactory = searchFactory;
- entityInfos = new EntityInfo[max - first + 1];
+ this.loader = loader;
+ this.documentExtractor = extractor;
+ this.entityInfos = new EntityInfo[max - first + 1];
+ this.resultContext = new HashMap<EntityInfo, Object[]>(max - first + 1);
}
public boolean next() throws HibernateException {
@@ -103,7 +107,6 @@
if ( current < first || current > max ) return null; //or exception?
EntityInfo info = entityInfos[current - first];
if ( info == null ) {
- info = new EntityInfo();
Document document = null;
try {
document = hits.doc( current );
@@ -111,14 +114,16 @@
catch (IOException e) {
throw new HibernateException( "Unable to read Lucene hits[" + current + "]", e );
}
- info.clazz = DocumentBuilder.getDocumentClass( document );
//FIXME should check that clazz match classes but this complexify a lot the firstResult/maxResult
- info.id = DocumentBuilder.getDocumentId( searchFactory, info.clazz, document );
+ info = documentExtractor.extract( document );
entityInfos[current - first] = info;
}
- return new Object[]{
- session.get( info.clazz, info.id )
- };
+ if ( !resultContext.containsKey( info ) ) {
+ Object loaded = loader.load( info );
+ if ( !loaded.getClass().isArray() ) loaded = new Object[] { loaded };
+ resultContext.put( info, (Object[]) loaded );
+ }
+ return resultContext.get( info );
}
public Object get(int i) throws HibernateException {
Modified: trunk/HibernateExt/search/src/test/org/hibernate/search/test/query/LuceneQuerySortTest.java
===================================================================
--- trunk/HibernateExt/search/src/test/org/hibernate/search/test/query/LuceneQuerySortTest.java 2007-05-16 15:32:33 UTC (rev 11530)
+++ trunk/HibernateExt/search/src/test/org/hibernate/search/test/query/LuceneQuerySortTest.java 2007-05-16 22:25:22 UTC (rev 11531)
@@ -14,7 +14,7 @@
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.hibernate.search.Version;
-import org.hibernate.search.query.FullTextQuery;
+import org.hibernate.search.FullTextQuery;
import org.hibernate.search.test.SearchTestCase;
Modified: trunk/HibernateExt/search/src/test/org/hibernate/search/test/query/LuceneQueryTest.java
===================================================================
--- trunk/HibernateExt/search/src/test/org/hibernate/search/test/query/LuceneQueryTest.java 2007-05-16 15:32:33 UTC (rev 11530)
+++ trunk/HibernateExt/search/src/test/org/hibernate/search/test/query/LuceneQueryTest.java 2007-05-16 22:25:22 UTC (rev 11531)
@@ -7,7 +7,7 @@
import org.hibernate.search.test.SearchTestCase;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
-import org.hibernate.search.query.FullTextQuery;
+import org.hibernate.search.FullTextQuery;
import org.hibernate.Transaction;
import org.hibernate.Hibernate;
import org.hibernate.ScrollableResults;
@@ -51,6 +51,12 @@
assertEquals( "Query with explicit class filter", 2, result.size() );
query = parser.parse( "summary:Festina Or brand:Seiko" );
+ hibQuery = s.createFullTextQuery( query, Clock.class );
+ result = hibQuery.list();
+ assertNotNull( result );
+ assertEquals( "Query with one class filter", 1, result.size() );
+
+ query = parser.parse( "summary:Festina Or brand:Seiko" );
hibQuery = s.createFullTextQuery( query );
result = hibQuery.list();
assertNotNull( result );
More information about the hibernate-commits
mailing list