Added first instances of using a cache for access index schema values
Project: http://git-wip-us.apache.org/repos/asf/usergrid/repo Commit: http://git-wip-us.apache.org/repos/asf/usergrid/commit/7e180af9 Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/7e180af9 Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/7e180af9 Branch: refs/heads/release-2.1.1 Commit: 7e180af9469f2ef2dc31cba8aa67867acd514b42 Parents: bc1fdef Author: George Reyes <g...@apache.org> Authored: Wed Mar 30 16:26:46 2016 -0700 Committer: George Reyes <g...@apache.org> Committed: Wed Mar 30 16:26:46 2016 -0700 ---------------------------------------------------------------------- .../usergrid/corepersistence/CoreModule.java | 6 ++ .../corepersistence/CpEntityManager.java | 22 ++-- .../corepersistence/CpEntityManagerFactory.java | 4 + .../corepersistence/CpManagerCache.java | 17 ++++ .../usergrid/corepersistence/ManagerCache.java | 4 + .../corepersistence/index/IndexSchemaCache.java | 45 ++++++++ .../index/IndexSchemaCacheFactory.java | 44 ++++++++ .../index/IndexSchemaCacheFig.java | 39 +++++++ .../index/IndexSchemaCacheImpl.java | 102 +++++++++++++++++++ .../usergrid/persistence/EntityManager.java | 1 + .../persistence/map/impl/MapManagerImpl.java | 6 ++ .../index/impl/EntityToMapConverter.java | 2 +- 12 files changed, 285 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/usergrid/blob/7e180af9/stack/core/src/main/java/org/apache/usergrid/corepersistence/CoreModule.java ---------------------------------------------------------------------- diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CoreModule.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CoreModule.java index 5ac7faf..2d57131 100644 --- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CoreModule.java +++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CoreModule.java @@ -16,6 +16,9 @@ package org.apache.usergrid.corepersistence; +import org.apache.usergrid.corepersistence.index.IndexSchemaCache; +import org.apache.usergrid.corepersistence.index.IndexSchemaCacheFactory; +import org.apache.usergrid.corepersistence.index.IndexSchemaCacheFig; import org.apache.usergrid.locking.guice.LockModule; import org.apache.usergrid.persistence.cache.guice.CacheModule; import java.util.concurrent.ThreadPoolExecutor; @@ -128,6 +131,7 @@ public class CoreModule extends AbstractModule { bind( ManagerCache.class ).to( CpManagerCache.class ); bind( ApplicationIdCacheFactory.class ); + bind( IndexSchemaCacheFactory.class ); /** @@ -177,6 +181,8 @@ public class CoreModule extends AbstractModule { install( new GuicyFigModule( ApplicationIdCacheFig.class ) ); + install( new GuicyFigModule( IndexSchemaCacheFig.class ) ); + install( new GuicyFigModule( EntityManagerFig.class ) ); install( new GuicyFigModule( AsyncEventsSchedulerFig.class ) ); http://git-wip-us.apache.org/repos/asf/usergrid/blob/7e180af9/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java ---------------------------------------------------------------------- diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java index 78e52ef..d1f28be 100644 --- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java +++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java @@ -38,8 +38,8 @@ import java.util.TreeMap; import java.util.TreeSet; import java.util.UUID; -import com.google.common.base.Optional; +import org.apache.usergrid.corepersistence.index.IndexSchemaCache; import org.apache.usergrid.corepersistence.service.CollectionService; import org.apache.usergrid.corepersistence.service.ConnectionService; import org.apache.usergrid.persistence.index.EntityIndex; @@ -106,6 +106,7 @@ import org.apache.usergrid.persistence.model.util.UUIDGenerator; import com.codahale.metrics.Meter; import com.codahale.metrics.Timer; +import com.google.common.base.Optional; import com.google.common.base.Preconditions; import me.prettyprint.hector.api.Keyspace; @@ -236,7 +237,10 @@ public class CpEntityManager implements EntityManager { * @param metricsFactory * @param applicationId */ - public CpEntityManager( final CassandraService cass, final CounterUtils counterUtils, final AsyncEventService indexService, final ManagerCache managerCache, + public CpEntityManager( final CassandraService cass, + final CounterUtils counterUtils, + final AsyncEventService indexService, + final ManagerCache managerCache, final MetricsFactory metricsFactory, final EntityManagerFig entityManagerFig, final GraphManagerFactory graphManagerFactory, @@ -1754,9 +1758,9 @@ public class CpEntityManager implements EntityManager { schemaMap.put("lastUpdateBy",owner); - //TODO: please add a check to get the previous reindex time. MapManager mm = getMapManagerForTypes(); + //TODO: add a cache around String jsonSchemaMap = mm.getString( collectionName ); //If we do have a schema then parse it and add it to a list of properties we want to keep.Otherwise return. @@ -1778,10 +1782,16 @@ public class CpEntityManager implements EntityManager { @Override public Object getCollectionSchema( String collectionName ){ MapManager mm = getMapManagerForTypes(); - String jsonMap = mm.getString( collectionName ); - Object obj = JsonUtils.parse( jsonMap ); - return obj; + + java.util.Optional<String> collectionIndexingSchema = managerCache.getIndexSchema( mm,collectionName ); + + if(collectionIndexingSchema.isPresent()){ + return JsonUtils.parse( collectionIndexingSchema.get() ); + } + else{ + return null; + } } @Override http://git-wip-us.apache.org/repos/asf/usergrid/blob/7e180af9/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManagerFactory.java ---------------------------------------------------------------------- diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManagerFactory.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManagerFactory.java index 0462ac6..4e7f90f 100644 --- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManagerFactory.java +++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManagerFactory.java @@ -31,6 +31,8 @@ import org.springframework.context.ApplicationContextAware; import org.apache.commons.lang.StringUtils; import org.apache.usergrid.corepersistence.asyncevents.AsyncEventService; +import org.apache.usergrid.corepersistence.index.IndexSchemaCache; +import org.apache.usergrid.corepersistence.index.IndexSchemaCacheFactory; import org.apache.usergrid.corepersistence.index.ReIndexRequestBuilder; import org.apache.usergrid.corepersistence.index.ReIndexService; import org.apache.usergrid.corepersistence.service.CollectionService; @@ -110,6 +112,7 @@ public class CpEntityManagerFactory implements EntityManagerFactory, Application }); private final ApplicationIdCache applicationIdCache; + //private final IndexSchemaCache indexSchemaCache; private ManagerCache managerCache; @@ -139,6 +142,7 @@ public class CpEntityManagerFactory implements EntityManagerFactory, Application this.connectionService = injector.getInstance( ConnectionService.class ); //this line always needs to be last due to the temporary cicular dependency until spring is removed + this.applicationIdCache = injector.getInstance(ApplicationIdCacheFactory.class).getInstance( getManagementEntityManager() ); http://git-wip-us.apache.org/repos/asf/usergrid/blob/7e180af9/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpManagerCache.java ---------------------------------------------------------------------- diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpManagerCache.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpManagerCache.java index 0b7bb43..dfbab00 100644 --- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpManagerCache.java +++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpManagerCache.java @@ -16,7 +16,13 @@ package org.apache.usergrid.corepersistence; +import java.util.Optional; + +import org.safehaus.guicyfig.Overrides; + import org.apache.usergrid.corepersistence.index.IndexLocationStrategyFactory; +import org.apache.usergrid.corepersistence.index.IndexSchemaCache; +import org.apache.usergrid.corepersistence.index.IndexSchemaCacheFactory; import org.apache.usergrid.persistence.collection.EntityCollectionManager; import org.apache.usergrid.persistence.collection.EntityCollectionManagerFactory; import org.apache.usergrid.persistence.core.scope.ApplicationScope; @@ -44,6 +50,7 @@ public class CpManagerCache implements ManagerCache { private final EntityIndexFactory eif; private final GraphManagerFactory gmf; private final MapManagerFactory mmf; + private final IndexSchemaCacheFactory indexSchemaCacheFactory; private final IndexLocationStrategyFactory indexLocationStrategyFactory; private final IndexProducer indexProducer; @@ -55,6 +62,7 @@ public class CpManagerCache implements ManagerCache { final EntityIndexFactory eif, final GraphManagerFactory gmf, final MapManagerFactory mmf, + final IndexSchemaCacheFactory indexSchemaCacheFactory, final IndexLocationStrategyFactory indexLocationStrategyFactory, final IndexProducer indexProducer ) { @@ -63,6 +71,7 @@ public class CpManagerCache implements ManagerCache { this.eif = eif; this.gmf = gmf; this.mmf = mmf; + this.indexSchemaCacheFactory = indexSchemaCacheFactory; this.indexLocationStrategyFactory = indexLocationStrategyFactory; this.indexProducer = indexProducer; } @@ -94,6 +103,14 @@ public class CpManagerCache implements ManagerCache { return mmf.createMapManager( mapScope ); } + //could be called an index schema manager. + + @Override + public Optional<String> getIndexSchema( MapManager mapManager, String collectionName ) { + return indexSchemaCacheFactory.getInstance( mapManager ).getCollectionSchema( collectionName ); + } + + @Override public IndexProducer getIndexProducer() { return indexProducer; http://git-wip-us.apache.org/repos/asf/usergrid/blob/7e180af9/stack/core/src/main/java/org/apache/usergrid/corepersistence/ManagerCache.java ---------------------------------------------------------------------- diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/ManagerCache.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/ManagerCache.java index 1dee80a..e0a8257 100644 --- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/ManagerCache.java +++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/ManagerCache.java @@ -20,6 +20,8 @@ package org.apache.usergrid.corepersistence; +import java.util.Optional; + import org.apache.usergrid.persistence.collection.EntityCollectionManager; import org.apache.usergrid.persistence.core.scope.ApplicationScope; import org.apache.usergrid.persistence.graph.GraphManager; @@ -66,6 +68,8 @@ public interface ManagerCache { */ MapManager getMapManager(MapScope mapScope); + Optional<String> getIndexSchema( MapManager mapManager, String collectionName ); + /** * gets index producer * @return http://git-wip-us.apache.org/repos/asf/usergrid/blob/7e180af9/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexSchemaCache.java ---------------------------------------------------------------------- diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexSchemaCache.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexSchemaCache.java new file mode 100644 index 0000000..5a9e95d --- /dev/null +++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexSchemaCache.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.corepersistence.index; + + +import java.util.Map; +import java.util.Optional; + + +public interface IndexSchemaCache { + + /** + * Get the collection schema from the cache. + * @param collectionName + * @return + */ + public Optional<String> getCollectionSchema(String collectionName); + + /** + * Evict the collection schema from the cache. + * @param collectionName + */ + public void evictCollectionSchema(String collectionName); + + /** + * Evict everything from the cache. + */ + public void evictCache(); + + +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/7e180af9/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexSchemaCacheFactory.java ---------------------------------------------------------------------- diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexSchemaCacheFactory.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexSchemaCacheFactory.java new file mode 100644 index 0000000..6f72103 --- /dev/null +++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexSchemaCacheFactory.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.usergrid.corepersistence.index; + + +import org.apache.usergrid.persistence.map.MapManager; + +import com.google.inject.Inject; +import com.google.inject.Singleton; + + +/** + * This can only be implemented after we have the impl for the application cache. + */ +@Singleton +public class IndexSchemaCacheFactory { + private final IndexSchemaCacheFig fig; + + @Inject + public IndexSchemaCacheFactory(IndexSchemaCacheFig fig){ + this.fig = fig; + } + + public IndexSchemaCache getInstance(MapManager mapManager ){ + return new IndexSchemaCacheImpl( mapManager,fig ); + } + + +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/7e180af9/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexSchemaCacheFig.java ---------------------------------------------------------------------- diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexSchemaCacheFig.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexSchemaCacheFig.java new file mode 100644 index 0000000..0953abd --- /dev/null +++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexSchemaCacheFig.java @@ -0,0 +1,39 @@ +package org.apache.usergrid.corepersistence.index;/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import org.safehaus.guicyfig.Default; +import org.safehaus.guicyfig.FigSingleton; +import org.safehaus.guicyfig.GuicyFig; +import org.safehaus.guicyfig.Key; + + +/** + * Index schema configuration. + */ +@FigSingleton +public interface IndexSchemaCacheFig extends GuicyFig { + + @Key( "usergrid.index_schema_cache_size" ) + @Default( "5000" ) + int getCacheSize(); + + @Key( "usergrid.index_schema_cache_timeout_ms" ) + @Default( "60000" ) + int getCacheTimeout(); + +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/7e180af9/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexSchemaCacheImpl.java ---------------------------------------------------------------------- diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexSchemaCacheImpl.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexSchemaCacheImpl.java new file mode 100644 index 0000000..d818ce0 --- /dev/null +++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexSchemaCacheImpl.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.usergrid.corepersistence.index; + + +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.usergrid.corepersistence.ManagerCache; +import org.apache.usergrid.persistence.map.MapManager; +import org.apache.usergrid.utils.JsonUtils; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; + + +/** + * Cache the calls to update and get the map manager so we don't overload cassandra when we update + * after each call? + */ +public class IndexSchemaCacheImpl implements IndexSchemaCache { + private static final Logger logger = LoggerFactory.getLogger(IndexSchemaCacheImpl.class ); + + private final LoadingCache<String,Optional<String>> indexSchemaCache; + private final MapManager mapManager; + + + public IndexSchemaCacheImpl(MapManager mapManager,IndexSchemaCacheFig indexSchemaCacheFig){ + this.mapManager = mapManager; + indexSchemaCache = CacheBuilder.newBuilder() + .maximumSize( indexSchemaCacheFig.getCacheSize() ) + //.expireAfterWrite( indexSchemaCacheFig.getCacheTimeout(), TimeUnit.MILLISECONDS ) <-- I don't think we want this to expire that quickly. + .build( new CacheLoader<String, Optional<String>>() { + @Override + public Optional<String> load( final String collectionName ) throws Exception { + return Optional.ofNullable( retrieveCollectionSchema( collectionName ) ); + } + } ); + } + + private String retrieveCollectionSchema( final String collectionName ){ + return mapManager.getString( collectionName ); + } + + + @Override + public Optional<String> getCollectionSchema( final String collectionName ) { + try { + Optional<String> optionalCollectionSchema = indexSchemaCache.get( collectionName ); + if(!optionalCollectionSchema.isPresent()){ + indexSchemaCache.invalidate( collectionName ); + return Optional.empty(); + } + return optionalCollectionSchema; + }catch(Exception e){ + if(logger.isDebugEnabled()){ + logger.debug( "Returning for collection name: {} " + + "resulted in the following failure: {}",collectionName,e ); + } + } + return null; + } + + + @Override + public void evictCollectionSchema( final String collectionName ) { + indexSchemaCache.invalidate( collectionName ); + if(logger.isDebugEnabled() ){ + logger.debug( "Invalidated key {}",collectionName ); + } + + } + + + @Override + public void evictCache() { + indexSchemaCache.invalidateAll(); + if(logger.isDebugEnabled()){ + logger.debug( "Invalidated all keys" ); + } + } +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/7e180af9/stack/core/src/main/java/org/apache/usergrid/persistence/EntityManager.java ---------------------------------------------------------------------- diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/EntityManager.java b/stack/core/src/main/java/org/apache/usergrid/persistence/EntityManager.java index 13fb098..f5b398a 100644 --- a/stack/core/src/main/java/org/apache/usergrid/persistence/EntityManager.java +++ b/stack/core/src/main/java/org/apache/usergrid/persistence/EntityManager.java @@ -525,6 +525,7 @@ public interface EntityManager { public Set<String> getRolePermissions( String roleName ) throws Exception; public void deleteRole( String roleName ) throws Exception; + public void deleteRole( String roleName, final Optional<EntityRef> roleRef ) throws Exception; http://git-wip-us.apache.org/repos/asf/usergrid/blob/7e180af9/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapManagerImpl.java ---------------------------------------------------------------------- diff --git a/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapManagerImpl.java b/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapManagerImpl.java index 501ade7..965f5f9 100644 --- a/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapManagerImpl.java +++ b/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapManagerImpl.java @@ -25,6 +25,9 @@ import java.util.UUID; import org.apache.usergrid.persistence.map.MapManager; import org.apache.usergrid.persistence.map.MapScope; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; import com.google.inject.Inject; import com.google.inject.assistedinject.Assisted; ; @@ -38,6 +41,9 @@ public class MapManagerImpl implements MapManager { private final MapScope scope; private final MapSerialization mapSerialization; + //Maybe this should go in front of the mapSerialization stuff because thats where we actually make the calls + //to cassandra. Then the parsing could be done through an interface. + @Inject public MapManagerImpl( @Assisted final MapScope scope, final MapSerialization mapSerialization) { http://git-wip-us.apache.org/repos/asf/usergrid/blob/7e180af9/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityToMapConverter.java ---------------------------------------------------------------------- diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityToMapConverter.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityToMapConverter.java index 885f66e..e9a2075 100644 --- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityToMapConverter.java +++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityToMapConverter.java @@ -17,7 +17,6 @@ package org.apache.usergrid.persistence.index.impl; -import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -199,6 +198,7 @@ public class EntityToMapConverter { } if ( toRemoveFlag ) { + //Removes the value if it doesn't match anything collectionIterator.remove(); } }