diff --git a/bindings/java/src/org/sleuthkit/datamodel/CaseDatabaseFactory.java b/bindings/java/src/org/sleuthkit/datamodel/CaseDatabaseFactory.java
index 123551396e0a21cabfd25e12c5b8277a6a151086..e6c08af852c8b49b830ef902e4d9cc853f9a4868 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/CaseDatabaseFactory.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/CaseDatabaseFactory.java
@@ -223,7 +223,7 @@ private void createFileTables(Statement stmt) throws SQLException {
 				+ "FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
 				+ "FOREIGN KEY(fs_obj_id) REFERENCES tsk_fs_info(obj_id) ON DELETE CASCADE, "
 				+ "FOREIGN KEY(data_source_obj_id) REFERENCES data_source_info(obj_id) ON DELETE CASCADE, "
-				+ "FOREIGN KEY(os_account_obj_id) REFERENCES tsk_os_accounts(os_account_obj_id)) " ); 
+				+ "FOREIGN KEY(os_account_obj_id) REFERENCES tsk_os_accounts(os_account_obj_id) ON DELETE SET NULL) " ); 
 
 		stmt.execute("CREATE TABLE file_encoding_types (encoding_type INTEGER PRIMARY KEY, name TEXT NOT NULL)");
 
@@ -418,7 +418,7 @@ private void createHostTables(Statement stmt) throws SQLException {
 				+ "person_id INTEGER, "
 				+ "merged_into " + dbQueryHelper.getBigIntType() + ", "
 				+ "FOREIGN KEY(person_id) REFERENCES tsk_persons(id) ON DELETE SET NULL, "
-				+ "FOREIGN KEY(merged_into) REFERENCES tsk_hosts(id), "
+				+ "FOREIGN KEY(merged_into) REFERENCES tsk_hosts(id) ON DELETE CASCADE, "
 				+ "UNIQUE(name)) ");
 
 		stmt.execute("CREATE TABLE  tsk_host_addresses (id " + dbQueryHelper.getPrimaryKey() + " PRIMARY KEY, "
@@ -491,8 +491,8 @@ private void createAccountTables(Statement stmt) throws SQLException {
 				+ "db_status INTEGER DEFAULT 0, " // active/merged/deleted
 				+ "merged_into " + dbQueryHelper.getBigIntType() + " DEFAULT NULL, "	
 				+ "UNIQUE(realm_signature), "
-				+ "FOREIGN KEY(scope_host_id) REFERENCES tsk_hosts(id),"
-				+ "FOREIGN KEY(merged_into) REFERENCES tsk_os_account_realms(id) )");
+				+ "FOREIGN KEY(scope_host_id) REFERENCES tsk_hosts(id) ON DELETE CASCADE,"
+				+ "FOREIGN KEY(merged_into) REFERENCES tsk_os_account_realms(id) ON DELETE CASCADE )");
 		
 		// References tsk_objects, tsk_os_account_realms, tsk_persons
 		stmt.execute("CREATE TABLE tsk_os_accounts (os_account_obj_id " + dbQueryHelper.getBigIntType() + " PRIMARY KEY, "
@@ -508,8 +508,8 @@ private void createAccountTables(Statement stmt) throws SQLException {
 			    + "merged_into " + dbQueryHelper.getBigIntType() + " DEFAULT NULL, "
 				+ "UNIQUE(signature, realm_id), "
 				+ "FOREIGN KEY(os_account_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
-				+ "FOREIGN KEY(realm_id) REFERENCES tsk_os_account_realms(id),"
-				+ "FOREIGN KEY(merged_into) REFERENCES tsk_os_accounts(os_account_obj_id) )");
+				+ "FOREIGN KEY(realm_id) REFERENCES tsk_os_account_realms(id) ON DELETE CASCADE,"
+				+ "FOREIGN KEY(merged_into) REFERENCES tsk_os_accounts(os_account_obj_id) ON DELETE CASCADE )");
 		
 	}
 	// Must be called after createAccountTables() and blackboard_attribute_types, blackboard_artifacts creation.
@@ -526,8 +526,8 @@ private void createAccountInstancesAndArtifacts(Statement stmt) throws SQLExcept
 				+ "value_text TEXT, "
 				+ "value_int32 INTEGER, value_int64 " + dbQueryHelper.getBigIntType() + ", "
 				+ "value_double NUMERIC(20, 10), "
-				+ "FOREIGN KEY(os_account_obj_id) REFERENCES tsk_os_accounts(os_account_obj_id), " 
-				+ "FOREIGN KEY(host_id) REFERENCES tsk_hosts(id), "
+				+ "FOREIGN KEY(os_account_obj_id) REFERENCES tsk_os_accounts(os_account_obj_id) ON DELETE CASCADE, " 
+				+ "FOREIGN KEY(host_id) REFERENCES tsk_hosts(id) ON DELETE CASCADE, "
 				+ "FOREIGN KEY(source_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE SET NULL, "		
 				+ "FOREIGN KEY(attribute_type_id) REFERENCES blackboard_attribute_types(attribute_type_id))");	
 		
@@ -537,7 +537,7 @@ private void createAccountInstancesAndArtifacts(Statement stmt) throws SQLExcept
 				+ "data_source_obj_id " + dbQueryHelper.getBigIntType() + " NOT NULL, " 
 				+ "instance_type INTEGER NOT NULL, "	// PerformedActionOn/ReferencedOn
 				+ "UNIQUE(os_account_obj_id, data_source_obj_id), "
-				+ "FOREIGN KEY(os_account_obj_id) REFERENCES tsk_os_accounts(os_account_obj_id), " 
+				+ "FOREIGN KEY(os_account_obj_id) REFERENCES tsk_os_accounts(os_account_obj_id) ON DELETE CASCADE, " 
 				+ "FOREIGN KEY(data_source_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE ) ");
 		
 		// References blackboard_artifacts, tsk_os_accounts
@@ -545,7 +545,7 @@ private void createAccountInstancesAndArtifacts(Statement stmt) throws SQLExcept
 				+ "artifact_obj_id " + dbQueryHelper.getBigIntType() + " PRIMARY KEY, "
 				+ "os_account_obj_id " + dbQueryHelper.getBigIntType() + ", "
 				+ "FOREIGN KEY(artifact_obj_id) REFERENCES blackboard_artifacts(artifact_obj_id) ON DELETE CASCADE, "
-				+ "FOREIGN KEY(os_account_obj_id) REFERENCES tsk_os_accounts(os_account_obj_id)) ");	
+				+ "FOREIGN KEY(os_account_obj_id) REFERENCES tsk_os_accounts(os_account_obj_id) ON DELETE SET NULL) ");	
 	}
 	
 	private void createEventTables(Statement stmt) throws SQLException {
diff --git a/bindings/java/src/org/sleuthkit/datamodel/HostManager.java b/bindings/java/src/org/sleuthkit/datamodel/HostManager.java
index 2e620df94b2182b959f97bdf9cd20de71d07fc85..d8255b2e7823a93e715bb3264b3f2794ac95f6ab 100755
--- a/bindings/java/src/org/sleuthkit/datamodel/HostManager.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/HostManager.java
@@ -435,11 +435,23 @@ public List<Host> getAllHosts() throws TskCoreException {
 	 * @throws TskCoreException if no host is found or an error occurs.
 	 */
 	public Host getHostByDataSource(DataSource dataSource) throws TskCoreException {
-
+		return getHostByDataSource(dataSource.getId());
+	}	
+	
+	/**
+	 * Get host for the given data source ID.
+	 *
+	 * @param dataSourceId The data source ID to look up the host for.
+	 *
+	 * @return The host for this data source (will not be null).
+	 *
+	 * @throws TskCoreException if no host is found or an error occurs.
+	 */	
+	Host getHostByDataSource(long dataSourceId) throws TskCoreException {
 		String queryString = "SELECT tsk_hosts.id AS hostId, tsk_hosts.name AS name, tsk_hosts.db_status AS db_status FROM \n"
 				+ "tsk_hosts INNER JOIN data_source_info \n"
 				+ "ON tsk_hosts.id = data_source_info.host_id \n"
-				+ "WHERE data_source_info.obj_id = " + dataSource.getId();
+				+ "WHERE data_source_info.obj_id = " + dataSourceId;
 
 		db.acquireSingleUserCaseReadLock();
 		try (CaseDbConnection connection = this.db.getConnection();
@@ -447,12 +459,12 @@ public Host getHostByDataSource(DataSource dataSource) throws TskCoreException {
 				ResultSet rs = connection.executeQuery(s, queryString)) {
 
 			if (!rs.next()) {
-				throw new TskCoreException(String.format("Host not found for data source with ID = %d", dataSource.getId()));
+				throw new TskCoreException(String.format("Host not found for data source with ID = %d", dataSourceId));
 			} else {
 				return new Host(rs.getLong("hostId"), rs.getString("name"), Host.HostDbStatus.fromID(rs.getInt("db_status")));
 			}
 		} catch (SQLException ex) {
-			throw new TskCoreException(String.format("Error getting host for data source with ID = %d", dataSource.getId()), ex);
+			throw new TskCoreException(String.format("Error getting host for data source with ID = %d", dataSourceId), ex);
 		} finally {
 			db.releaseSingleUserCaseReadLock();
 		}
diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
index 6b5d7d7b11133c10c63d619be553adf57192388e..32326ed21baf4cf23831a6bf61519d889e7375bd 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
@@ -9782,6 +9782,22 @@ public void setImagePaths(long obj_id, List<String> paths) throws TskCoreExcepti
 	 *                          within tsk core and the update fails
 	 */
 	void deleteDataSource(long dataSourceObjectId) throws TskCoreException {
+		
+		// Check if this data source is the only one associated with its host. If so,
+		// we will delete the host and other associated data.
+		// Note that the cascading deletes were only added in schema 9.1, so we
+		// would get an error trying to delete a host from older cases.
+		Host hostToDelete = null;
+		VersionNumber version = getDBSchemaCreationVersion();
+		int major = version.getMajor();
+		int minor = version.getMinor();
+		if(major > 9 || (major == 9 && minor >= 1)) {
+			hostToDelete = getHostManager().getHostByDataSource(dataSourceObjectId);
+			if (getHostManager().getDataSourcesForHost(hostToDelete).size() != 1) {
+				hostToDelete = null;
+			}
+		}
+		
 		CaseDbConnection connection = null;
 		Statement statement;
 		acquireSingleUserCaseWriteLock();
@@ -9798,6 +9814,19 @@ void deleteDataSource(long dataSourceObjectId) throws TskCoreException {
 					+ "WHERE account_id NOT IN (SELECT account1_id FROM account_relationships) "
 					+ "AND account_id NOT IN (SELECT account2_id FROM account_relationships))";
 			statement.execute(accountSql);
+			
+			// Now delete any host that was only associated with this data source. This will cascade to delete
+			// realms, os accounts, and os account attributes that were associated with the host.
+			if (hostToDelete != null) {
+				statement.execute("DELETE FROM tsk_hosts WHERE id = " + hostToDelete.getHostId());
+				
+				// Clean up any stray OS Account objects
+				String deleteOsAcctObjectsQuery = "DELETE FROM tsk_objects " +
+					"WHERE type=" + TskData.ObjectType.OS_ACCOUNT.getObjectType() + " " + 
+					"AND obj_id NOT IN (SELECT os_account_obj_id FROM tsk_os_accounts WHERE  os_account_obj_id IS NOT NULL)";
+				statement.execute(deleteOsAcctObjectsQuery);
+			}
+			
 			connection.commitTransaction();
 		} catch (SQLException ex) {
 			rollbackTransaction(connection);