[hibernate-commits] Hibernate SVN: r15376 - in search/trunk/src: java/org/hibernate/search/backend/impl and 4 other directories.
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Wed Oct 22 22:15:50 EDT 2008
Author: epbernard
Date: 2008-10-22 22:15:50 -0400 (Wed, 22 Oct 2008)
New Revision: 15376
Added:
search/trunk/src/java/org/hibernate/search/engine/EntityState.java
search/trunk/src/test/org/hibernate/search/test/embedded/NonIndexedEntity.java
Modified:
search/trunk/src/java/org/hibernate/search/backend/WorkType.java
search/trunk/src/java/org/hibernate/search/backend/impl/BatchedQueueingProcessor.java
search/trunk/src/java/org/hibernate/search/engine/DocumentBuilder.java
search/trunk/src/java/org/hibernate/search/engine/SearchFactoryImplementor.java
search/trunk/src/java/org/hibernate/search/event/FullTextIndexEventListener.java
search/trunk/src/java/org/hibernate/search/impl/FullTextSessionImpl.java
search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java
search/trunk/src/test/org/hibernate/search/test/embedded/EmbeddedTest.java
search/trunk/src/test/org/hibernate/search/test/embedded/State.java
Log:
HSEARCH-142 Entity not marked as @Indexed but using @ContainedIn are now properly indexed on update
Modified: search/trunk/src/java/org/hibernate/search/backend/WorkType.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/backend/WorkType.java 2008-10-23 00:04:14 UTC (rev 15375)
+++ search/trunk/src/java/org/hibernate/search/backend/WorkType.java 2008-10-23 02:15:50 UTC (rev 15376)
@@ -10,23 +10,38 @@
* @author John Griffin
*/
public enum WorkType {
- ADD,
- UPDATE,
- DELETE,
- COLLECTION,
+ ADD(true),
+ UPDATE(true),
+ DELETE(false),
+ COLLECTION(true),
/**
* Used to remove a specific instance
* of a class from an index.
*/
- PURGE,
+ PURGE(false),
/**
* Used to remove all instances of a
* class from an index.
*/
- PURGE_ALL,
+ PURGE_ALL(false),
/**
* This type is used for batch indexing.
*/
- INDEX
+ INDEX(true);
+
+ private final boolean searchForContainers;
+
+ private WorkType(boolean searchForContainers) {
+ this.searchForContainers = searchForContainers;
+ }
+
+ /**
+ * When references are changed, either null or another one, we expect dirty checking to be triggered (both sides
+ * have to be updated)
+ * When the internal object is changed, we apply the {Add|Update}Work on containedIns
+ */
+ public boolean searchForContainers() {
+ return this.searchForContainers;
+ }
}
Modified: search/trunk/src/java/org/hibernate/search/backend/impl/BatchedQueueingProcessor.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/backend/impl/BatchedQueueingProcessor.java 2008-10-23 00:04:14 UTC (rev 15375)
+++ search/trunk/src/java/org/hibernate/search/backend/impl/BatchedQueueingProcessor.java 2008-10-23 02:15:50 UTC (rev 15376)
@@ -146,6 +146,10 @@
work.getEntityClass() :
Hibernate.getClass( work.getEntity() );
DocumentBuilder<T> builder = searchFactoryImplementor.getDocumentBuilder( entityClass );
+ if ( builder == null ) {
+ //might be a entity contained in
+ builder = searchFactoryImplementor.getContainedInOnlyBuilder( entityClass );
+ }
if ( builder == null ) return;
//TODO remove casting when Work is Work<T>
builder.addWorkToQueue(entityClass, (T) work.getEntity(), work.getId(), work.getType(), luceneQueue, searchFactoryImplementor );
Modified: search/trunk/src/java/org/hibernate/search/engine/DocumentBuilder.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/engine/DocumentBuilder.java 2008-10-23 00:04:14 UTC (rev 15375)
+++ search/trunk/src/java/org/hibernate/search/engine/DocumentBuilder.java 2008-10-23 02:15:50 UTC (rev 15376)
@@ -67,7 +67,6 @@
* @author Richard Hallier
* @author Hardy Ferentschik
*/
- at SuppressWarnings( "unchecked" )
public class DocumentBuilder<T> {
private static final Logger log = LoggerFactory.make();
@@ -90,14 +89,19 @@
//if composite id, use of (a, b) in ((1,2), (3,4)) fails on most database
private boolean safeFromTupleId;
private boolean idProvided = false;
+ private EntityState entityState;
public boolean isRoot() {
return isRoot;
}
+ /**
+ * used on an @Indexed entity
+ */
public DocumentBuilder(XClass clazz, InitContext context, DirectoryProvider[] directoryProviders,
IndexShardingStrategy shardingStrategy, ReflectionManager reflectionManager) {
+ this.entityState = EntityState.INDEXED;
this.beanClass = clazz;
this.directoryProviders = directoryProviders;
this.shardingStrategy = shardingStrategy;
@@ -105,6 +109,10 @@
this.reflectionManager = reflectionManager;
this.similarity = context.getDefaultSimilarity();
+ init( clazz, context, reflectionManager );
+ }
+
+ private void init(XClass clazz, InitContext context, ReflectionManager reflectionManager) {
if ( clazz == null ) throw new AssertionFailure( "Unable to build a DocumentBuilder with a null class" );
rootPropertiesMetadata.boost = getBoost( clazz );
rootPropertiesMetadata.analyzer = context.getDefaultAnalyzer();
@@ -113,7 +121,7 @@
initializeMembers( clazz, rootPropertiesMetadata, true, "", processedClasses, context );
//processedClasses.remove( clazz ); for the sake of completness
this.analyzer.setGlobalAnalyzer( rootPropertiesMetadata.analyzer );
- if ( idKeywordName == null ) {
+ if ( entityState == EntityState.INDEXED && idKeywordName == null ) {
// if no DocumentId then check if we have a ProvidedId instead
ProvidedId provided = findProvidedId( clazz, reflectionManager );
if ( provided == null ) throw new SearchException( "No document id in: " + clazz.getName() );
@@ -123,9 +131,28 @@
}
//if composite id, use of (a, b) in ((1,2)TwoWayString2FieldBridgeAdaptor, (3,4)) fails on most database
//a TwoWayString2FieldBridgeAdaptor is never a composite id
- safeFromTupleId = TwoWayString2FieldBridgeAdaptor.class.isAssignableFrom( idBridge.getClass() );
+ safeFromTupleId = entityState != EntityState.INDEXED || TwoWayString2FieldBridgeAdaptor.class.isAssignableFrom( idBridge.getClass() );
}
+ /**
+ * used on a non @Indexed entity
+ */
+ public DocumentBuilder(XClass clazz, InitContext context, ReflectionManager reflectionManager) {
+ this.entityState = EntityState.CONTAINED_IN_ONLY;
+ this.beanClass = clazz;
+ this.directoryProviders = null;
+ this.shardingStrategy = null;
+
+ //FIXME get rid of it when boost is stored?
+ this.reflectionManager = reflectionManager;
+ this.similarity = context.getDefaultSimilarity();
+
+ init( clazz, context, reflectionManager );
+ if (rootPropertiesMetadata.containedInGetters.size() == 0) {
+ this.entityState = EntityState.NON_INDEXABLE;
+ }
+ }
+
private ProvidedId findProvidedId(XClass clazz, ReflectionManager reflectionManager) {
ProvidedId id = null;
XClass currentClass = clazz;
@@ -502,83 +529,81 @@
}
//TODO could we use T instead of EntityClass?
- public void addWorkToQueue(Class entityClass, T entity, Serializable id, WorkType workType, List<LuceneWork> queue, SearchFactoryImplementor searchFactoryImplementor) {
+ public void addWorkToQueue(Class<T> entityClass, T entity, Serializable id, WorkType workType, List<LuceneWork> queue, SearchFactoryImplementor searchFactoryImplementor) {
//TODO with the caller loop we are in a n^2: optimize it using a HashMap for work recognition
- List<LuceneWork> toDelete = new ArrayList<LuceneWork>();
- boolean duplicateDelete = false;
- for (LuceneWork luceneWork : queue) {
- //avoid unecessary duplicated work
- if ( luceneWork.getEntityClass() == entityClass
- ) {
- Serializable currentId = luceneWork.getId();
- //currentId != null => either ADD or Delete work
- if ( currentId != null && currentId.equals( id ) ) { //find a way to use Type.equals(x,y)
- if (workType == WorkType.DELETE) { //TODO add PURGE?
- //DELETE should have precedence over any update before (HSEARCH-257)
- //if an Add work is here, remove it
- //if an other delete is here remember but still search for Add
- if (luceneWork instanceof AddLuceneWork) {
- toDelete.add( luceneWork );
+ if ( entityState == EntityState.INDEXED ) {
+ List<LuceneWork> toDelete = new ArrayList<LuceneWork>();
+ boolean duplicateDelete = false;
+ for (LuceneWork luceneWork : queue) {
+ //avoid unecessary duplicated work
+ if ( luceneWork.getEntityClass() == entityClass
+ ) {
+ Serializable currentId = luceneWork.getId();
+ //currentId != null => either ADD or Delete work
+ if ( currentId != null && currentId.equals( id ) ) { //find a way to use Type.equals(x,y)
+ if (workType == WorkType.DELETE) { //TODO add PURGE?
+ //DELETE should have precedence over any update before (HSEARCH-257)
+ //if an Add work is here, remove it
+ //if an other delete is here remember but still search for Add
+ if (luceneWork instanceof AddLuceneWork) {
+ toDelete.add( luceneWork );
+ }
+ else if (luceneWork instanceof DeleteLuceneWork) {
+ duplicateDelete = true;
+ }
}
- else if (luceneWork instanceof DeleteLuceneWork) {
- duplicateDelete = true;
+ else {
+ //we can safely say we are out, the other work is an ADD
+ return;
}
}
- else {
- //we can safely say we are out, the other work is an ADD
- return;
- }
+ //TODO do something to avoid multiple PURGE ALL and OPTIMIZE
}
- //TODO do something to avoid multiple PURGE ALL and OPTIMIZE
}
- }
- for ( LuceneWork luceneWork : toDelete ) {
- toDelete.remove( luceneWork );
- }
- if (duplicateDelete) return;
+ for ( LuceneWork luceneWork : toDelete ) {
+ toDelete.remove( luceneWork );
+ }
+ if (duplicateDelete) return;
- boolean searchForContainers = false;
- String idInString = idBridge.objectToString( id );
- if ( workType == WorkType.ADD ) {
- Document doc = getDocument( entity, id );
- queue.add( new AddLuceneWork( id, idInString, entityClass, doc ) );
- searchForContainers = true;
+ String idInString = idBridge.objectToString( id );
+ if ( workType == WorkType.ADD ) {
+ Document doc = getDocument( entity, id );
+ queue.add( new AddLuceneWork( id, idInString, entityClass, doc ) );
+ }
+ else if ( workType == WorkType.DELETE || workType == WorkType.PURGE ) {
+ queue.add( new DeleteLuceneWork( id, idInString, entityClass ) );
+ }
+ else if ( workType == WorkType.PURGE_ALL ) {
+ queue.add( new PurgeAllLuceneWork( entityClass ) );
+ }
+ else if ( workType == WorkType.UPDATE || workType == WorkType.COLLECTION ) {
+ Document doc = getDocument( entity, id );
+ /**
+ * even with Lucene 2.1, use of indexWriter to update is not an option
+ * We can only delete by term, and the index doesn't have a term that
+ * uniquely identify the entry.
+ * But essentially the optimization we are doing is the same Lucene is doing, the only extra cost is the
+ * double file opening.
+ */
+ queue.add( new DeleteLuceneWork( id, idInString, entityClass ) );
+ queue.add( new AddLuceneWork( id, idInString, entityClass, doc ) );
+ }
+ else if ( workType == WorkType.INDEX ) {
+ Document doc = getDocument( entity, id );
+ queue.add( new DeleteLuceneWork( id, idInString, entityClass ) );
+ queue.add( new AddLuceneWork( id, idInString, entityClass, doc, true ) );
+ }
+ else {
+ throw new AssertionFailure( "Unknown WorkType: " + workType );
+ }
}
- else if ( workType == WorkType.DELETE || workType == WorkType.PURGE ) {
- queue.add( new DeleteLuceneWork( id, idInString, entityClass ) );
- }
- else if ( workType == WorkType.PURGE_ALL ) {
- queue.add( new PurgeAllLuceneWork( entityClass ) );
- }
- else if ( workType == WorkType.UPDATE || workType == WorkType.COLLECTION ) {
- Document doc = getDocument( entity, id );
- /**
- * even with Lucene 2.1, use of indexWriter to update is not an option
- * We can only delete by term, and the index doesn't have a term that
- * uniquely identify the entry.
- * But essentially the optimization we are doing is the same Lucene is doing, the only extra cost is the
- * double file opening.
- */
- queue.add( new DeleteLuceneWork( id, idInString, entityClass ) );
- queue.add( new AddLuceneWork( id, idInString, entityClass, doc ) );
- searchForContainers = true;
- }
- else if ( workType == WorkType.INDEX ) {
- Document doc = getDocument( entity, id );
- queue.add( new DeleteLuceneWork( id, idInString, entityClass ) );
- queue.add( new AddLuceneWork( id, idInString, entityClass, doc, true ) );
- searchForContainers = true;
- }
- else {
- throw new AssertionFailure( "Unknown WorkType: " + workType );
- }
/**
* When references are changed, either null or another one, we expect dirty checking to be triggered (both sides
* have to be updated)
* When the internal object is changed, we apply the {Add|Update}Work on containedIns
*/
- if ( searchForContainers ) {
+ if ( workType.searchForContainers() ) {
processContainedIn( entity, queue, rootPropertiesMetadata, searchFactoryImplementor );
}
}
@@ -626,7 +651,7 @@
//do not walk through them
}
- private void processContainedInValue(Object value, List<LuceneWork> queue, Class valueClass,
+ private void processContainedInValue(Object value, List<LuceneWork> queue, Class<?> valueClass,
DocumentBuilder builder, SearchFactoryImplementor searchFactoryImplementor) {
Serializable id = (Serializable) builder.getMemberValue( value, builder.idGetter );
builder.addWorkToQueue( valueClass, value, id, WorkType.UPDATE, queue, searchFactoryImplementor );
@@ -634,7 +659,8 @@
public Document getDocument(T instance, Serializable id) {
Document doc = new Document();
- XClass instanceClass = reflectionManager.toXClass( Hibernate.getClass( instance ) );
+ final Class<?> entityType = Hibernate.getClass( instance );
+ XClass instanceClass = reflectionManager.toXClass( entityType );
if ( rootPropertiesMetadata.boost != null ) {
doc.setBoost( rootPropertiesMetadata.boost );
}
@@ -718,10 +744,16 @@
}
public DirectoryProvider[] getDirectoryProviders() {
+ if( entityState != EntityState.INDEXED ) {
+ throw new AssertionFailure("Contained in only entity: getDirectoryProvider should not have been called.");
+ }
return directoryProviders;
}
public IndexShardingStrategy getDirectoryProviderSelectionStrategy() {
+ if( entityState != EntityState.INDEXED ) {
+ throw new AssertionFailure("Contained in only entity: getDirectoryProviderSelectionStrategy should not have been called.");
+ }
return shardingStrategy;
}
@@ -825,6 +857,7 @@
}
public void postInitialize(Set<Class<?>> indexedClasses) {
+ if (entityState == EntityState.NON_INDEXABLE) throw new AssertionFailure("A non indexed entity is post processed");
//this method does not requires synchronization
Class plainClass = reflectionManager.toClass( beanClass );
Set<Class<?>> tempMappedSubclasses = new HashSet<Class<?>>();
@@ -844,6 +877,9 @@
}
}
+ public EntityState getEntityState() {
+ return entityState;
+ }
public Set<Class<?>> getMappedSubclasses() {
return mappedSubclasses;
Added: search/trunk/src/java/org/hibernate/search/engine/EntityState.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/engine/EntityState.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/engine/EntityState.java 2008-10-23 02:15:50 UTC (rev 15376)
@@ -0,0 +1,12 @@
+package org.hibernate.search.engine;
+
+/**
+ * Entity state with regard to indexing possibilities
+ *
+ * @author Emmanuel Bernard
+ */
+public enum EntityState {
+ INDEXED,
+ CONTAINED_IN_ONLY,
+ NON_INDEXABLE
+}
Modified: search/trunk/src/java/org/hibernate/search/engine/SearchFactoryImplementor.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/engine/SearchFactoryImplementor.java 2008-10-23 00:04:14 UTC (rev 15375)
+++ search/trunk/src/java/org/hibernate/search/engine/SearchFactoryImplementor.java 2008-10-23 02:15:50 UTC (rev 15376)
@@ -19,7 +19,6 @@
* @author Emmanuel Bernard
* @author Hardy Ferentschik
*/
- at SuppressWarnings("unchecked")
public interface SearchFactoryImplementor extends SearchFactory {
BackendQueueProcessorFactory getBackendQueueProcessorFactory();
@@ -29,6 +28,8 @@
<T> DocumentBuilder<T> getDocumentBuilder(Class<T> entityType);
+ <T> DocumentBuilder<T> getContainedInOnlyBuilder(Class<T> entityType);
+
Worker getWorker();
void addOptimizerStrategy(DirectoryProvider<?> provider, OptimizerStrategy optimizerStrategy);
Modified: search/trunk/src/java/org/hibernate/search/event/FullTextIndexEventListener.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/event/FullTextIndexEventListener.java 2008-10-23 00:04:14 UTC (rev 15375)
+++ search/trunk/src/java/org/hibernate/search/event/FullTextIndexEventListener.java 2008-10-23 02:15:50 UTC (rev 15376)
@@ -72,17 +72,20 @@
}
public void onPostDelete(PostDeleteEvent event) {
- if ( used && searchFactoryImplementor.getDocumentBuilders().containsKey( event.getEntity().getClass() ) ) {
- processWork( event.getEntity(), event.getId(), WorkType.DELETE, event );
+ if ( used ) {
+ final Class<?> entityType = event.getEntity().getClass();
+ if ( searchFactoryImplementor.getDocumentBuilders().containsKey( entityType )
+ || searchFactoryImplementor.getContainedInOnlyBuilder( entityType ) != null ) {
+ processWork( event.getEntity(), event.getId(), WorkType.DELETE, event );
+ }
}
}
public void onPostInsert(PostInsertEvent event) {
if ( used ) {
final Object entity = event.getEntity();
- DocumentBuilder<?> builder = searchFactoryImplementor.getDocumentBuilder( entity.getClass() );
- //not strictly necessary but a small optimization
- if ( builder != null ) {
+ if ( searchFactoryImplementor.getDocumentBuilder( entity.getClass() ) != null
+ || searchFactoryImplementor.getContainedInOnlyBuilder( entity.getClass() ) != null ) {
Serializable id = event.getId();
processWork( entity, id, WorkType.ADD, event );
}
@@ -92,9 +95,8 @@
public void onPostUpdate(PostUpdateEvent event) {
if ( used ) {
final Object entity = event.getEntity();
- //not strictly necessary but a small optimization
- DocumentBuilder<?> builder = searchFactoryImplementor.getDocumentBuilder( entity.getClass() );
- if ( builder != null ) {
+ if ( searchFactoryImplementor.getDocumentBuilder( entity.getClass() ) != null
+ || searchFactoryImplementor.getContainedInOnlyBuilder( entity.getClass() ) != null ) {
Serializable id = event.getId();
processWork( entity, id, WorkType.UPDATE, event );
}
@@ -131,16 +133,19 @@
//Should log really but we don't know if we're interested in this collection for indexing
return;
}
- if ( used && searchFactoryImplementor.getDocumentBuilders().containsKey( entity.getClass() ) ) {
- Serializable id = getId( entity, event );
- if ( id == null ) {
- log.warn(
- "Unable to reindex entity on collection change, id cannot be extracted: {}",
- event.getAffectedOwnerEntityName()
- );
- return;
+ if ( used ) {
+ if ( searchFactoryImplementor.getDocumentBuilder( entity.getClass() ) != null
+ || searchFactoryImplementor.getContainedInOnlyBuilder( entity.getClass() ) != null ) {
+ Serializable id = getId( entity, event );
+ if ( id == null ) {
+ log.warn(
+ "Unable to reindex entity on collection change, id cannot be extracted: {}",
+ event.getAffectedOwnerEntityName()
+ );
+ return;
+ }
+ processWork( entity, id, WorkType.COLLECTION, event );
}
- processWork( entity, id, WorkType.COLLECTION, event );
}
}
Modified: search/trunk/src/java/org/hibernate/search/impl/FullTextSessionImpl.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/impl/FullTextSessionImpl.java 2008-10-23 00:04:14 UTC (rev 15375)
+++ search/trunk/src/java/org/hibernate/search/impl/FullTextSessionImpl.java 2008-10-23 02:15:50 UTC (rev 15376)
@@ -112,9 +112,10 @@
// not strictly necessary but a small optimization plus let's make sure the
// client didn't mess something up.
- DocumentBuilder<?> builder = searchFactoryImplementor.getDocumentBuilder( entityType );
- if ( builder == null ) {
- throw new IllegalArgumentException( entityType.getName() + " is not a mapped entity (don't forget to add @Indexed)" );
+ if ( searchFactoryImplementor.getDocumentBuilder( entityType ) == null
+ && searchFactoryImplementor.getContainedInOnlyBuilder( entityType ) == null ) {
+ throw new IllegalArgumentException( "Entity to index is not an @Indexed entity nor @ContainedIn another entity: "
+ + entityType.getName() );
}
WorkType type;
if ( id == null ) {
@@ -142,9 +143,10 @@
//TODO cache that at the FTSession level
SearchFactoryImplementor searchFactoryImplementor = getSearchFactoryImplementor();
//not strictly necessary but a small optimization
- DocumentBuilder<?> builder = searchFactoryImplementor.getDocumentBuilder( clazz );
- if ( builder == null ) {
- throw new IllegalArgumentException( "Entity to index not an @Indexed entity: " + entity.getClass().getName() );
+ if ( searchFactoryImplementor.getDocumentBuilder( clazz ) == null
+ && searchFactoryImplementor.getContainedInOnlyBuilder( clazz ) == null ) {
+ throw new IllegalArgumentException( "Entity to index is not an @Indexed entity nor @ContainedIn another entity: "
+ + entity.getClass().getName() );
}
Serializable id = session.getIdentifier( entity );
Work work = new Work( entity, id, WorkType.INDEX );
Modified: search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java 2008-10-23 00:04:14 UTC (rev 15375)
+++ search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java 2008-10-23 02:15:50 UTC (rev 15376)
@@ -42,6 +42,7 @@
import org.hibernate.search.engine.DocumentBuilder;
import org.hibernate.search.engine.FilterDef;
import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.hibernate.search.engine.EntityState;
import org.hibernate.search.filter.CachingWrapperFilter;
import org.hibernate.search.filter.FilterCachingStrategy;
import org.hibernate.search.filter.MRUFilterCachingStrategy;
@@ -66,6 +67,7 @@
private static final Logger log = LoggerFactory.make();
private final Map<Class<?>, DocumentBuilder<?>> documentBuilders = new HashMap<Class<?>, DocumentBuilder<?>>();
+ private final Map<Class<?>, DocumentBuilder<?>> containedInOnlyBuilders = new HashMap<Class<?>, DocumentBuilder<?>>();
//keep track of the index modifiers per DirectoryProvider since multiple entity can use the same directory provider
private final Map<DirectoryProvider<?>, DirectoryProviderData> dirProviderData = new HashMap<DirectoryProvider<?>, DirectoryProviderData>();
private final Worker worker;
@@ -117,6 +119,10 @@
for (DocumentBuilder builder : documentBuilders.values()) {
builder.postInitialize( indexedClasses );
}
+ //not really necessary today
+ for (DocumentBuilder builder : containedInOnlyBuilders.values()) {
+ builder.postInitialize( indexedClasses );
+ }
this.worker = WorkerFactory.createWorker( cfg, this );
this.readerProvider = ReaderProviderFactory.createReaderProvider( cfg, this );
this.filterCachingStrategy = buildFilterCachingStrategy( cfg.getProperties() );
@@ -244,9 +250,16 @@
@SuppressWarnings( "unckecked" )
public <T> DocumentBuilder<T> getDocumentBuilder(Class<T> entityType) {
+ if (barrier != 0) { } //read barrier
return ( DocumentBuilder<T> ) documentBuilders.get( entityType );
}
+ @SuppressWarnings( "unckecked" )
+ public <T> DocumentBuilder<T> getContainedInOnlyBuilder(Class<T> entityType) {
+ if (barrier != 0) { } //read barrier
+ return ( DocumentBuilder<T> ) containedInOnlyBuilders.get( entityType );
+ }
+
public Set<DirectoryProvider<?>> getDirectoryProviders() {
if (barrier != 0) { } //read barrier
return this.dirProviderData.keySet();
@@ -343,14 +356,26 @@
if ( mappedXClass != null) {
if ( mappedXClass.isAnnotationPresent( Indexed.class ) ) {
DirectoryProviderFactory.DirectoryProviders providers = factory.createDirectoryProviders( mappedXClass, cfg, this, reflectionManager );
-
- final DocumentBuilder<Object> documentBuilder = new DocumentBuilder<Object>(
+ //FIXME DocumentBuilder needs to be built by a helper method receiving Class<T> to infer T properly
+ //XClass unfortunately is not (yet) genericized: TODO?
+ final DocumentBuilder<?> documentBuilder = new DocumentBuilder(
mappedXClass, context, providers.getProviders(), providers.getSelectionStrategy(),
reflectionManager
);
documentBuilders.put( mappedClass, documentBuilder );
}
+ else {
+ //FIXME DocumentBuilder needs to be built by a helper method receiving Class<T> to infer T properly
+ //XClass unfortunately is not (yet) genericized: TODO?
+ final DocumentBuilder<?> documentBuilder = new DocumentBuilder(
+ mappedXClass, context, reflectionManager
+ );
+ //TODO enhance that, I don't like to expose EntityState
+ if ( documentBuilder.getEntityState() != EntityState.NON_INDEXABLE ) {
+ containedInOnlyBuilders.put( mappedClass, documentBuilder );
+ }
+ }
bindFilterDefs(mappedXClass);
//TODO should analyzer def for classes at tyher sqme level???
}
Modified: search/trunk/src/test/org/hibernate/search/test/embedded/EmbeddedTest.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/embedded/EmbeddedTest.java 2008-10-23 00:04:14 UTC (rev 15375)
+++ search/trunk/src/test/org/hibernate/search/test/embedded/EmbeddedTest.java 2008-10-23 02:15:50 UTC (rev 15376)
@@ -264,7 +264,6 @@
* Tests that updating an indexed embedded object updates the Lucene index as well.
*
* @throws Exception in case the test fails
- * @see HSEARCH-142
*/
public void testEmbeddedObjectUpdate() throws Exception {
@@ -316,6 +315,7 @@
protected Class<?>[] getMappings() {
return new Class[] { Tower.class, Address.class, Product.class, Order.class, Author.class, Country.class,
- State.class, StateCandidate.class };
+ State.class, StateCandidate.class, NonIndexedEntity.class
+ };
}
}
Added: search/trunk/src/test/org/hibernate/search/test/embedded/NonIndexedEntity.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/embedded/NonIndexedEntity.java (rev 0)
+++ search/trunk/src/test/org/hibernate/search/test/embedded/NonIndexedEntity.java 2008-10-23 02:15:50 UTC (rev 15376)
@@ -0,0 +1,23 @@
+package org.hibernate.search.test.embedded;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at Entity
+public class NonIndexedEntity {
+ @Id
+ @GeneratedValue
+ private int id;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+}
Modified: search/trunk/src/test/org/hibernate/search/test/embedded/State.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/embedded/State.java 2008-10-23 00:04:14 UTC (rev 15375)
+++ search/trunk/src/test/org/hibernate/search/test/embedded/State.java 2008-10-23 02:15:50 UTC (rev 15376)
@@ -15,7 +15,6 @@
* @author Hardy Ferentschik
*/
@Entity
- at Indexed // @indexed should not be needed, see HSEARCH-142 and testEmbeddedObjectUpdate()
public class State {
@Id
@DocumentId
More information about the hibernate-commits
mailing list