diff --git a/dspace-api/src/main/java/org/dspace/core/Context.java b/dspace-api/src/main/java/org/dspace/core/Context.java index 8dca747a2e..ba467035a4 100644 --- a/dspace-api/src/main/java/org/dspace/core/Context.java +++ b/dspace-api/src/main/java/org/dspace/core/Context.java @@ -643,27 +643,6 @@ public class Context dbConnection.shutdown(); } - /** - * Clear the cache of all object that have been read from the database so far. This will also free up - * (heap space) memory. You should use this method when processing a large number of records. - * - * WARNING: After calling this method all previously fetched entities are "detached" (pending - * changes are not tracked anymore). You have to reload all entities you still want to work with - * manually after this method call (see {@link Context#reloadEntity(ReloadableEntity)}). - * - * This method will take care of reloading the current user. - * - * @throws SQLException When clearing the entity cache fails - */ - public void clearCache() throws SQLException { - if(log.isDebugEnabled()) { - log.debug("Cache size before clear cache is " + getCacheSize()); - } - - this.getDBConnection().clearCache(); - - reloadContextBoundEntities(); - } /** * Returns the size of the cache of all object that have been read from the database so far. A larger number diff --git a/dspace-api/src/main/java/org/dspace/core/DBConnection.java b/dspace-api/src/main/java/org/dspace/core/DBConnection.java index 953eee7372..a9a22e96ac 100644 --- a/dspace-api/src/main/java/org/dspace/core/DBConnection.java +++ b/dspace-api/src/main/java/org/dspace/core/DBConnection.java @@ -40,8 +40,6 @@ public interface DBConnection { public DatabaseConfigVO getDatabaseConfig() throws SQLException; - public void clearCache() throws SQLException; - public void setOptimizedForBatchProcessing(boolean batchOptimized) throws SQLException; public boolean isOptimizedForBatchProcessing(); diff --git a/dspace-api/src/main/java/org/dspace/core/HibernateDBConnection.java b/dspace-api/src/main/java/org/dspace/core/HibernateDBConnection.java index 9288e3e7f2..650015056d 100644 --- a/dspace-api/src/main/java/org/dspace/core/HibernateDBConnection.java +++ b/dspace-api/src/main/java/org/dspace/core/HibernateDBConnection.java @@ -116,11 +116,6 @@ public class HibernateDBConnection implements DBConnection { return databaseConfigVO; } - @Override - public void clearCache() throws SQLException { - getSession().flush(); - getSession().clear(); - } @Override public long getCacheSize() throws SQLException { diff --git a/dspace-api/src/main/java/org/dspace/discovery/IndexClient.java b/dspace-api/src/main/java/org/dspace/discovery/IndexClient.java index 9d72900a0d..873c663c55 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/IndexClient.java +++ b/dspace-api/src/main/java/org/dspace/discovery/IndexClient.java @@ -9,11 +9,20 @@ package org.dspace.discovery; import org.apache.log4j.Logger; import org.apache.commons.cli.*; +import org.dspace.content.Collection; +import org.dspace.content.Community; +import org.dspace.content.DSpaceObject; +import org.dspace.content.Item; +import org.dspace.content.factory.ContentServiceFactory; +import org.dspace.content.service.ItemService; +import org.dspace.core.Constants; import org.dspace.core.Context; +import org.dspace.handle.factory.HandleServiceFactory; import org.dspace.services.factory.DSpaceServicesFactory; import java.io.IOException; import java.sql.SQLException; +import java.util.Iterator; /** * Class used to reindex dspace communities/collections/items into discovery @@ -41,19 +50,26 @@ public class IndexClient { Context context = new Context(); context.setIgnoreAuthorization(true); - String usage = "org.dspace.discovery.IndexClient [-cbhf[r ]] or nothing to update/clean an existing index."; + String usage = "org.dspace.discovery.IndexClient [-cbhf] | [-r ] | [-i ] or nothing to update/clean an existing index."; Options options = new Options(); HelpFormatter formatter = new HelpFormatter(); CommandLine line = null; options .addOption(OptionBuilder - .withArgName("item handle") + .withArgName("handle to remove") .hasArg(true) .withDescription( "remove an Item, Collection or Community from index based on its handle") .create("r")); + options + .addOption(OptionBuilder + .withArgName("handle to add or update") + .hasArg(true) + .withDescription( + "add or update an Item, Collection or Community based on its handle") + .create("i")); options .addOption(OptionBuilder @@ -119,6 +135,19 @@ public class IndexClient { indexer.optimize(); } else if(line.hasOption('s')) { checkRebuildSpellCheck(line, indexer); + } else if(line.hasOption('i')) { + final String handle = line.getOptionValue('i'); + final DSpaceObject dso = HandleServiceFactory.getInstance().getHandleService().resolveToObject(context, handle); + if (dso == null) { + throw new IllegalArgumentException("Cannot resolve " + handle + " to a DSpace object"); + } + log.info("Forcibly Indexing " + handle); + // Enable batch mode; we may be indexing a large number of items + context.enableBatchMode(true); + final long startTimeMillis = System.currentTimeMillis(); + final long count = indexAll(indexer, ContentServiceFactory.getInstance().getItemService(), context, dso); + final long seconds = (System.currentTimeMillis() - startTimeMillis ) / 1000; + log.info("Indexed " + count + " DSpace object" + (count > 1 ? "s" : "") + " in " + seconds + " seconds"); } else { log.info("Updating and Cleaning Index"); indexer.cleanIndex(line.hasOption("f")); @@ -129,6 +158,57 @@ public class IndexClient { log.info("Done with indexing"); } + /** + * Indexes the given object and all children, if applicable. + */ + private static long indexAll(final IndexingService indexingService, + final ItemService itemService, + final Context context, + final DSpaceObject dso) throws IOException, SearchServiceException, SQLException { + long count = 0; + + indexingService.indexContent(context, dso, true, true); + count++; + if (dso.getType() == Constants.COMMUNITY) { + final Community community = (Community) dso; + final String communityHandle = community.getHandle(); + for (final Community subcommunity : community.getSubcommunities()) { + count += indexAll(indexingService, itemService, context, subcommunity); + } + final Community reloadedCommunity = (Community) HandleServiceFactory.getInstance().getHandleService().resolveToObject(context, communityHandle); + for (final Collection collection : reloadedCommunity.getCollections()) { + count++; + indexingService.indexContent(context, collection, true, true); + count += indexItems(indexingService, itemService, context, collection); + } + } else if (dso.getType() == Constants.COLLECTION) { + count += indexItems(indexingService, itemService, context, (Collection) dso); + } + + return count; + } + + /** + * Indexes all items in the given collection. + */ + private static long indexItems(final IndexingService indexingService, + final ItemService itemService, + final Context context, + final Collection collection) throws IOException, SearchServiceException, SQLException { + long count = 0; + + final Iterator itemIterator = itemService.findByCollection(context, collection); + while (itemIterator.hasNext()) { + Item item = itemIterator.next(); + indexingService.indexContent(context, itemIterator.next(), true, false); + count++; + context.uncacheEntity(item); + } + indexingService.commit(); + + return count; + } + /** * Check the command line options and rebuild the spell check if active. * @param line the command line options @@ -141,4 +221,4 @@ public class IndexClient { indexer.buildSpellCheck(); } } -} +} \ No newline at end of file diff --git a/dspace-api/src/main/java/org/dspace/discovery/SolrServiceImpl.java b/dspace-api/src/main/java/org/dspace/discovery/SolrServiceImpl.java index ff7b4b1fc7..8f3257007f 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/SolrServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/SolrServiceImpl.java @@ -397,10 +397,7 @@ public class SolrServiceImpl implements SearchService, IndexingService { { Item item = items.next(); indexContent(context, item, force); - if (itemCount++ >= 1000) { - context.clearCache(); - itemCount = 0; - } + context.uncacheEntity(item); } List collections = collectionService.findAll(context);