diff --git a/bindings/java/src/org/sleuthkit/datamodel/JniDbHelper.java b/bindings/java/src/org/sleuthkit/datamodel/JniDbHelper.java
index dc41ea72b33c4aaf1fe22008368ea450973d217b..0422de29a3774ebc864b896ea03dd692a6696941 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/JniDbHelper.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/JniDbHelper.java
@@ -22,8 +22,10 @@
 import java.util.List;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Queue;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import org.sleuthkit.datamodel.SleuthkitCase.CaseDbTransaction;
@@ -33,6 +35,9 @@
  * case database. All callbacks from the native code should come through this class.
  * Any changes to the method signatures in this class will require changes to the 
  * native code.
+ * 
+ * Note that this code should only be used for the add image process, and not
+ * to add additional files afterward.
  */
 class JniDbHelper {
     
@@ -47,8 +52,9 @@ class JniDbHelper {
     private final Map<ParentCacheKey, Long> parentDirCache = new HashMap<>();
     
     private static final long BATCH_FILE_THRESHOLD = 500;
-    private final List<FileInfo> batchedFiles = new ArrayList<>();
-    private final List<LayoutRangeInfo> batchedLayoutRanges = new ArrayList<>();
+    private final Queue<FileInfo> batchedFiles = new LinkedList<>();
+    private final Queue<LayoutRangeInfo> batchedLayoutRanges = new LinkedList<>();
+    private final List<Long> layoutFileIds = new ArrayList<>();
     
     JniDbHelper(SleuthkitCase caseDb, AddDataSourceCallbacks addDataSourceCallbacks) {
         this.caseDb = caseDb;
@@ -95,6 +101,7 @@ private void revertTransaction() {
     void finish() {
         addBatchedFilesToDb();
         addBatchedLayoutRangesToDb();
+        processLayoutFiles();
     }
     
     /**
@@ -330,7 +337,8 @@ private long addBatchedFilesToDb() {
         List<Long> newObjIds = new ArrayList<>();
         try {
             beginTransaction();
-            for (FileInfo fileInfo : batchedFiles) {
+            FileInfo fileInfo;
+            while ((fileInfo = batchedFiles.poll()) != null) {
                 long computedParentObjId = fileInfo.parentObjId;
                 try {
                     // If we weren't given the parent object ID, look it up
@@ -370,9 +378,6 @@ private long addBatchedFilesToDb() {
                 } catch (TskCoreException ex) {
                     logger.log(Level.SEVERE, "Error adding file to the database - parent object ID: " + computedParentObjId
                             + ", file system object ID: " + fileInfo.fsObjId + ", name: " + fileInfo.name, ex);
-                    revertTransaction();
-                    batchedFiles.clear();
-                    return -1;
                 }
             }
             commitTransaction();
@@ -385,10 +390,8 @@ private long addBatchedFilesToDb() {
         } catch (TskCoreException ex) {
             logger.log(Level.SEVERE, "Error adding batched files to database", ex);
             revertTransaction();
-            batchedFiles.clear();
             return -1;
         }
-        batchedFiles.clear();
         return 0;
     }
     
@@ -413,10 +416,11 @@ private long getParentObjId(FileInfo fileInfo) throws TskCoreException {
         if (parentDirCache.containsKey(key)) {
             return parentDirCache.get(key);
         } else {
-            // The parent wasn't found in the cache so do a database query
-            java.io.File parentAsFile = new java.io.File(parentPath);
-            return caseDb.findParentObjIdJNI(fileInfo.parMetaAddr, fileInfo.fsObjId, parentAsFile.getPath(), parentAsFile.getName(), trans);
-        }
+            // There's no reason to do a database query since every folder added is being
+            // stored in the cache.
+            throw new TskCoreException("Parent not found in cache (fsObjId: " +fileInfo.fsObjId + ", parMetaAddr: " + fileInfo.parMetaAddr
+                + ", parSeq: " + fileInfo.parSeq + ", parentPath: " + parentPath + ")");
+		}
     }
     
     /**
@@ -461,6 +465,10 @@ long addLayoutFile(long parentObjId,
                 null, null, 
                 true, trans);
             commitTransaction();
+
+            // Store the layout file ID for later processing
+            layoutFileIds.add(objId);
+
             return objId;
         } catch (TskCoreException ex) {
             logger.log(Level.SEVERE, "Error adding layout file to the database - parent object ID: " + parentObjId
@@ -498,19 +506,16 @@ long addLayoutFileRange(long objId, long byteStart, long byteLen, long seq) {
     private long addBatchedLayoutRangesToDb() {
         try {
             beginTransaction();
-    
-            for (LayoutRangeInfo range : batchedLayoutRanges) {
+    		LayoutRangeInfo range;
+            while ((range = batchedLayoutRanges.poll()) != null) {
                 try {
                     caseDb.addLayoutFileRangeJNI(range.objId, range.byteStart, range.byteLen, range.seq, trans);
                 } catch (TskCoreException ex) {
                     logger.log(Level.SEVERE, "Error adding layout file range to the database - layout file ID: " + range.objId 
                         + ", byte start: " + range.byteStart, ex);
-                    revertTransaction();
-                    return -1;
                 }
             }
             commitTransaction();
-            batchedLayoutRanges.clear();
             return 0;
         } catch (TskCoreException ex) {
             logger.log(Level.SEVERE, "Error adding batched files to database", ex);
@@ -518,6 +523,16 @@ private long addBatchedLayoutRangesToDb() {
             return -1;
         }
     }
+	
+    /**
+     * Send completed layout files on for further processing.
+     * Note that this must wait until we know all the ranges for each
+     * file have been added to the database. 
+     */
+    void processLayoutFiles() {
+        addDataSourceCallbacks.onFilesAdded(layoutFileIds);
+        layoutFileIds.clear();
+    }
     
     /**
      * Add a virtual directory to hold unallocated file system blocks.
diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
index 3f7ad417bcd6bc9908b30d81c26768222ce78565..3a26e343d1d92a00be16412b0adf2da130d98ef8 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
@@ -11065,44 +11065,6 @@ void addImageNameJNI(long objId, String name, long sequence,
 		}
 	}
 
-	/**
-	 * Looks up a parent file object ID. The calling thread is expected to have
-	 * a case read lock. For use with the JNI callbacks associated with the add
-	 * image process.
-	 *
-	 * @param metaAddr    The metadata address.
-	 * @param fsObjId     The file system object ID.
-	 * @param path        The file path.
-	 * @param name        The file name.
-	 * @param transaction The open transaction.
-	 *
-	 * @return The object ID if found, -1 otherwise.
-	 *
-	 * @throws TskCoreException
-	 */
-	long findParentObjIdJNI(long metaAddr, long fsObjId, String path, String name, CaseDbTransaction transaction) throws TskCoreException {
-		ResultSet resultSet = null;
-		try {
-			CaseDbConnection connection = transaction.getConnection();
-			PreparedStatement preparedStatement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_OBJ_ID_BY_META_ADDR_AND_PATH);
-			preparedStatement.clearParameters();
-			preparedStatement.setLong(1, metaAddr);
-			preparedStatement.setLong(2, fsObjId);
-			preparedStatement.setString(3, path);
-			preparedStatement.setString(4, name);
-			resultSet = connection.executeQuery(preparedStatement);
-			if (resultSet.next()) {
-				return resultSet.getLong("obj_id");
-			} else {
-				throw new TskCoreException(String.format("Error looking up parent - meta addr: %d, path: %s, name: %s", metaAddr, path, name));
-			}
-		} catch (SQLException ex) {
-			throw new TskCoreException(String.format("Error looking up parent - meta addr: %d, path: %s, name: %s", metaAddr, path, name), ex);
-		} finally {
-			closeResultSet(resultSet);
-		}
-	}
-
 	/**
 	 * Add a file system file to the database. For use with the JNI callbacks
 	 * associated with the add image process.
@@ -11526,7 +11488,6 @@ private enum PREPARED_STATEMENT {
 		INSERT_POOL_INFO("INSERT INTO tsk_pool_info (obj_id, pool_type) VALUES (?, ?)"),
 		INSERT_FS_INFO("INSERT INTO tsk_fs_info (obj_id, data_source_obj_id, img_offset, fs_type, block_size, block_count, root_inum, first_inum, last_inum, display_name)"
 				+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"),
-		SELECT_OBJ_ID_BY_META_ADDR_AND_PATH("SELECT obj_id FROM tsk_files WHERE meta_addr = ? AND fs_obj_id = ? AND parent_path = ? AND name = ?"),
 		SELECT_TAG_NAME_BY_ID("SELECT * FROM tag_names where tag_name_id = ?");
 
 		private final String sql;