diff --git a/bindings/java/src/org/sleuthkit/datamodel/CaseDatabaseFactory.java b/bindings/java/src/org/sleuthkit/datamodel/CaseDatabaseFactory.java
index d2c8a826cc23d5580d76f904d5926ebf2b7fa61c..d369e2f8f408630ae9ef747878d5ea74f607a845 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/CaseDatabaseFactory.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/CaseDatabaseFactory.java
@@ -212,8 +212,8 @@ private void createFileTables(Statement stmt) throws SQLException {
 				+ "mtime " + dbQueryHelper.getBigIntType() + ", mode INTEGER, uid INTEGER, gid INTEGER, md5 TEXT, sha256 TEXT, "
 				+ "known INTEGER, "
 				+ "parent_path TEXT, mime_type TEXT, extension TEXT, "
-				+ "owner_uid TEXT, "
-				+ "os_account_obj_id " + dbQueryHelper.getBigIntType() + ", "
+				+ "owner_uid TEXT DEFAULT NULL, "
+				+ "os_account_obj_id " + dbQueryHelper.getBigIntType() + " DEFAULT NULL, "
 				+ "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, "
@@ -281,7 +281,7 @@ private void createArtifactTables(Statement stmt) throws SQLException {
 	}
 	
 	private void createAnalysisResultsTables(Statement stmt) throws SQLException  {
-		stmt.execute("CREATE TABLE tsk_analysis_results (artifact_obj_id " + dbQueryHelper.getBigIntType() + " NOT NULL, "
+		stmt.execute("CREATE TABLE tsk_analysis_results (artifact_obj_id " + dbQueryHelper.getBigIntType() + " PRIMARY KEY, "
 				+ "conclusion TEXT, "
 				+ "significance INTEGER NOT NULL, "
 				+ "confidence INTEGER NOT NULL, "
@@ -290,7 +290,7 @@ private void createAnalysisResultsTables(Statement stmt) throws SQLException  {
 				+ "FOREIGN KEY(artifact_obj_id) REFERENCES blackboard_artifacts(artifact_obj_id) ON DELETE CASCADE"
 				+ ")");		
 		
-		stmt.execute("CREATE TABLE tsk_aggregate_score( obj_id " + dbQueryHelper.getBigIntType() + " NOT NULL, "
+		stmt.execute("CREATE TABLE tsk_aggregate_score( obj_id " + dbQueryHelper.getBigIntType() + " PRIMARY KEY, "
 				+ "data_source_obj_id " + dbQueryHelper.getBigIntType() + " NOT NULL, "
 				+ "significance INTEGER NOT NULL, "
 				+ "confidence INTEGER NOT NULL, "
@@ -442,7 +442,7 @@ private void createAccountTables(Statement stmt) throws SQLException {
 				+ "status INTEGER, "    // enabled/disabled/deleted
 				+ "admin INTEGER DEFAULT 0," // is admin account
 				+ "type INTEGER, "	// service/interactive
-				+ "created_date " + dbQueryHelper.getBigIntType() + ", "		
+				+ "created_date " + dbQueryHelper.getBigIntType() + " DEFAULT NULL, "		
 				+ "UNIQUE(signature), "
 				+ "FOREIGN KEY(os_account_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
 				+ "FOREIGN KEY(realm_id) REFERENCES tsk_os_account_realms(id) )");
@@ -474,7 +474,7 @@ private void createAccountTables(Statement stmt) throws SQLException {
 		
 		stmt.execute("CREATE TABLE tsk_data_artifacts ( "
 				+ "artifact_obj_id " + dbQueryHelper.getBigIntType() + " PRIMARY KEY, "
-				+ "os_account_obj_id " + dbQueryHelper.getBigIntType() + " NOT NULL, "
+				+ "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) ON DELETE CASCADE) ");	
 	}
diff --git a/bindings/java/src/org/sleuthkit/datamodel/OsAccount.java b/bindings/java/src/org/sleuthkit/datamodel/OsAccount.java
index 237dd4b4ab21d3bc0d552a04ff0d043011348910..243c32c9083a0f63fb466d8b6cf497113504f138 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/OsAccount.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/OsAccount.java
@@ -53,7 +53,7 @@ public final class OsAccount extends AbstractContent {
 	private boolean isAdmin = false;	// is admin account.
 	private OsAccountType osAccountType = OsAccountType.UNKNOWN;
 	private OsAccountStatus osAccountStatus;
-	private long creationTime = 0;
+	private Long creationTime = null;
 
 	private final List<OsAccountAttribute> osAccountAttributes = new ArrayList<>();
 
@@ -132,7 +132,7 @@ public enum OsAccountType {
 		 *
 		 * @return Account type id.
 		 */
-		int getId() {
+		public int getId() {
 			return id;
 		}
 
@@ -141,7 +141,7 @@ int getId() {
 		 *
 		 * @return Account type name.
 		 */
-		String getName() {
+		public String getName() {
 			return name;
 		}
 
@@ -371,8 +371,8 @@ public boolean isAdmin() {
 	 *
 	 * @return Account creation time, returns 0 if creation time is not known.
 	 */
-	public long getCreationTime() {
-		return creationTime;
+	public Optional<Long> getCreationTime() {
+		return Optional.of(creationTime);
 	}
 
 	/**
diff --git a/bindings/java/src/org/sleuthkit/datamodel/OsAccountAttribute.java b/bindings/java/src/org/sleuthkit/datamodel/OsAccountAttribute.java
index 657c012bc68195c9fe77a3772e4da40743432440..d1be2cd722af4152bc6c5b5fb90e3cede911b901 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/OsAccountAttribute.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/OsAccountAttribute.java
@@ -30,18 +30,18 @@ public final class OsAccountAttribute extends AbstractAttribute {
 
 	private final long osAccountObjId;	// OS account to which this attribute belongs.
 	private final Long hostId; // Host to which this attribute applies, may be null
-	private final long sourceObjId; // Object id of the source where the attribute was discoevered.
+	private final long sourceObjId; // Object id of the source where the attribute was discovered.
 
 	/**
 	 * Creates an os account attribute with int value.
 	 *
 	 * @param attributeType  Attribute type.
 	 * @param valueInt	      Int value.
-	 * @param osAccountObjId Obj id of account which the attribute pertains to.
-	 * @param sourceObjId    Object id of the source where the attribute was
-	 *                       found.
+	 * @param osAccountObjId Obj id of account which the attribute pertains to. 
 	 * @param hostId         Id of host on which the attribute applies to. Pass
 	 *                       Null if it applies across hosts.
+	 * @param sourceObjId    Object id of the source where the attribute was
+	 *                       found.
 	 */
 	public OsAccountAttribute(BlackboardAttribute.Type attributeType, int valueInt, long osAccountObjId, Long hostId, long sourceObjId) {
 		super(attributeType, valueInt);
@@ -57,10 +57,10 @@ public OsAccountAttribute(BlackboardAttribute.Type attributeType, int valueInt,
 	 * @param attributeType  Attribute type.
 	 * @param valueLong	     Long value.
 	 * @param osAccountObjId Obj id of account which the attribute pertains to.
-	 * @param sourceObjId    Object id of the source where the attribute was
-	 *                       found.
 	 * @param hostId         Id of host on which the attribute applies to. Pass
 	 *                       Null if it applies across hosts.
+	 * @param sourceObjId    Object id of the source where the attribute was
+	 *                       found.
 	 */
 	public OsAccountAttribute(BlackboardAttribute.Type attributeType, long valueLong, long osAccountObjId, Long hostId, long sourceObjId) {
 		super(attributeType, valueLong);
@@ -76,10 +76,10 @@ public OsAccountAttribute(BlackboardAttribute.Type attributeType, long valueLong
 	 * @param attributeType  Attribute type.
 	 * @param valueDouble    Double value.
 	 * @param osAccountObjId Obj id of account which the attribute pertains to.
-	 * @param sourceObjId    Object id of the source where the attribute was
-	 *                       found.
 	 * @param hostId         Id of host on which the attribute applies to. Pass
 	 *                       Null if it applies across hosts.
+	 * @param sourceObjId    Object id of the source where the attribute was
+	 *                       found.
 	 */
 	public OsAccountAttribute(BlackboardAttribute.Type attributeType, double valueDouble, long osAccountObjId, Long hostId, long sourceObjId) {
 		super(attributeType, valueDouble);
@@ -95,10 +95,10 @@ public OsAccountAttribute(BlackboardAttribute.Type attributeType, double valueDo
 	 * @param attributeType  Attribute type.
 	 * @param valueString    String value.
 	 * @param osAccountObjId Obj id of account which the attribute pertains to.
-	 * @param sourceObjId    Object id of the source where the attribute was
-	 *                       found.
 	 * @param hostId         Id of host on which the attribute applies to. Pass
 	 *                       Null if it applies across hosts.
+	 * @param sourceObjId    Object id of the source where the attribute was
+	 *                       found.
 	 */
 	public OsAccountAttribute(BlackboardAttribute.Type attributeType, String valueString, long osAccountObjId, Long hostId, long sourceObjId) {
 		super(attributeType, valueString);
@@ -114,10 +114,10 @@ public OsAccountAttribute(BlackboardAttribute.Type attributeType, String valueSt
 	 * @param attributeType  Attribute type.
 	 * @param valueBytes     Bytes value.
 	 * @param osAccountObjId Obj id of account which the attribute pertains to.
-	 * @param sourceObjId    Object id of the source where the attribute was
-	 *                       found.
 	 * @param hostId         Id of host on which the attribute applies to. Pass
 	 *                       Null if it applies across hosts.
+	 * @param sourceObjId    Object id of the source where the attribute was
+	 *                       found.
 	 */
 	public OsAccountAttribute(Type attributeType, byte[] valueBytes, long osAccountObjId, Long hostId, long sourceObjId) {
 		super(attributeType, valueBytes);
@@ -145,7 +145,7 @@ public OsAccountAttribute(Type attributeType, byte[] valueBytes, long osAccountO
 	 *                       Null if it applies across hosts.
 	 */
 	OsAccountAttribute(BlackboardAttribute.Type attributeType, int valueInt, long valueLong, double valueDouble, String valueString, byte[] valueBytes,
-			SleuthkitCase sleuthkitCase, long osAccountObjId, long sourceObjId, Long hostId) {
+			SleuthkitCase sleuthkitCase, long osAccountObjId, Long hostId, long sourceObjId) {
 		
 		super( attributeType,
 				valueInt, valueLong, valueDouble, valueString, valueBytes,
diff --git a/bindings/java/src/org/sleuthkit/datamodel/OsAccountManager.java b/bindings/java/src/org/sleuthkit/datamodel/OsAccountManager.java
index 6ca2b9254b8af0e74f3dd8944746f18767ad249c..50e6929bac4231d93b202fae179456de950ec694 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/OsAccountManager.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/OsAccountManager.java
@@ -55,13 +55,13 @@ public final class OsAccountManager {
 	}
 
 	/**
-	 * Creates an OS account with given unique id or given realm/loginname.
+	 * Creates an OS account with given unique id or given realm and login name.
 	 * If an account already exists with the given id or realm/login, then the
 	 * existing OS account is returned.
 	 *
 	 * @param uniqueAccountId Account sid/uid.
 	 * @param loginName       Login name.
-	 * @param realmName       Realm within which the accountId/loginName is
+	 * @param realmName       Realm within which the accountId or login name is
 	 *                        unique.
 	 * @param host            Host for the realm, may be null.
 	 *
@@ -81,7 +81,8 @@ public OsAccount createOsAccount(String uniqueAccountId, String loginName, Strin
 		}
 
 		Optional<OsAccountRealm> realm = Optional.empty();
-		try (CaseDbConnection connection = this.db.getConnection()) {
+		
+		try (CaseDbConnection connection = this.db.getConnection();) {
 
 			// get the realm with given name
 			realm = db.getOsAccountRealmManager().getRealmByName(realmName, host, connection);
@@ -89,49 +90,54 @@ public OsAccount createOsAccount(String uniqueAccountId, String loginName, Strin
 				// realm was not found, create it.
 				realm = Optional.of(db.getOsAccountRealmManager().createRealmByName(realmName, host));
 			}
-
-			return createOsAccount(uniqueAccountId, loginName, realm.get(), OsAccount.OsAccountStatus.UNKNOWN,  connection);
-		} catch (SQLException ex) {
-
-			// Create may fail if an OsAccount already exists. 
-			try (CaseDbConnection connection = this.db.getConnection()) {
-
-				Optional<OsAccount> osAccount;
-
-				// First search for account by uniqueId
-				if (!Strings.isNullOrEmpty(uniqueAccountId)) {
-					osAccount = getOsAccountByUniqueId(uniqueAccountId, host, connection);
-					if (osAccount.isPresent()) {
-						return osAccount.get();
+		
+			// try to create account
+			try {
+				return createOsAccount(uniqueAccountId, loginName, realm.get(), OsAccount.OsAccountStatus.UNKNOWN, connection);
+			} catch (SQLException ex) {
+
+				// Create may fail if an OsAccount already exists. 
+				try (CaseDbConnection newConnection = this.db.getConnection()) {
+
+					Optional<OsAccount> osAccount;
+
+					// First search for account by uniqueId
+					if (!Strings.isNullOrEmpty(uniqueAccountId)) {
+						osAccount = getOsAccountByUniqueId(uniqueAccountId, host, newConnection);
+						if (osAccount.isPresent()) {
+							return osAccount.get();
+						}
 					}
-				}
 
-				// search by loginName
-				if (!Strings.isNullOrEmpty(loginName)) {
-					osAccount = getOsAccountByLoginName(loginName, realm.get(), connection);
-					if (osAccount.isPresent()) {
-						return osAccount.get();
+					// search by loginName
+					if (!Strings.isNullOrEmpty(loginName)) {
+						osAccount = getOsAccountByLoginName(loginName, realm.get(), newConnection);
+						if (osAccount.isPresent()) {
+							return osAccount.get();
+						}
 					}
-				}
 
-				// create failed for some other reason, throw an exception
-				throw new TskCoreException(String.format("Error creating OsAccount with loginName = %s", loginName), ex);
+					// create failed for some other reason, throw an exception
+					throw new TskCoreException(String.format("Error creating OsAccount with loginName = %s", loginName), ex);
+				}
 			}
-		}
+		} 
 	}
 
 	/**
-	 * Get the OS account with given unique id or given realm name/login name.
+	 * Get the OS account with given unique id or given realm name and login name.
 	 *
 	 * @param uniqueAccountId Account sid/uid.
 	 * @param loginName       Login name.
-	 * @param realmName       Realm within which the accountId/loginName is
+	 * @param realmName       Realm within which the accountId & login name is
 	 *                        unique.
 	 * @param host            Host for the realm, may be null.
 	 * @param transaction     Transaction to use for database operation.
 	 *
 	 * @return Optional with OsAccount matching the given uniqueId, or
 	 *         realm/login name. Optional.empty if no match is found.
+	 * 
+	 * @throws TskCoreException If there is an error getting the account.
 	 */
 	public Optional<OsAccount> getOsAccount(String uniqueAccountId, String loginName, String realmName, Host host, CaseDbTransaction transaction) throws TskCoreException {
 
@@ -144,19 +150,24 @@ public Optional<OsAccount> getOsAccount(String uniqueAccountId, String loginName
 			throw new IllegalArgumentException("Realm name is required to create an OS account.");
 		}
 
-		Optional<OsAccount> osAccount =  this.getOsAccountByUniqueId(uniqueAccountId, host, transaction.getConnection());
-		
-		if (osAccount.isPresent()) {
-			return osAccount;
+		if (!Strings.isNullOrEmpty(uniqueAccountId)) {
+			Optional<OsAccount> osAccount = this.getOsAccountByUniqueId(uniqueAccountId, host, transaction.getConnection());
+			if (osAccount.isPresent()) {
+				return osAccount;
+			}
 		}
 		
-		// first get the realm 
-		Optional<OsAccountRealm> realm = db.getOsAccountRealmManager().getRealmByName(realmName, host, transaction);
-		if (!realm.isPresent()) {
-			throw new TskCoreException(String.format("No realm found with name %s", realmName));
+		if (!Strings.isNullOrEmpty(loginName)) {
+			// first get the realm 
+			Optional<OsAccountRealm> realm = db.getOsAccountRealmManager().getRealmByName(realmName, host, transaction);
+			if (!realm.isPresent()) {
+				throw new TskCoreException(String.format("No realm found with name %s", realmName));
+			}
+
+			return getOsAccountByLoginName(loginName, realm.get(), transaction.getConnection());
 		}
 		
-		return  getOsAccountByLoginName(loginName, realm.get(), transaction.getConnection());
+		return Optional.empty();
 	}
 	
 	/**
@@ -178,16 +189,7 @@ private OsAccount createOsAccount(String uniqueId, String loginName, OsAccountRe
 			throw new IllegalArgumentException("Cannot create an OS Account, realm is NULL.");
 		}
 		
-		// Create a signature.  This signature is simply to prevent duplicate accounts from being created.
-		// Signature is set to realmId/uniqueId or realmId/loginName
-		String signature;
-		if (Strings.isNullOrEmpty(uniqueId) == false) {
-			signature = String.format("%d/%s", realm.getId(), uniqueId);
-		} else if (Strings.isNullOrEmpty(loginName) == false)  {
-			signature = String.format("%d/%s", realm.getId(), loginName);
-		} else {
-			throw new IllegalArgumentException("Cannot create OS Account, either a uniqueID or a login name must be provided.");
-		}
+		String signature = makeAccountSignature(realm, uniqueId, loginName);
 
 		db.acquireSingleUserCaseWriteLock();
 		try {
@@ -251,8 +253,8 @@ public Optional<OsAccount> getOsAccount(String uniqueId, Host host, CaseDbTransa
 	/**
 	 * Gets the OS account for the given unique id. 
 	 *
-	 * @param uniqueId Account SID/uid.
-	 * @param Host Host to match the realm, may be null.
+	 * @param uniqueId   Account SID/uid.
+	 * @param host       Host to match the realm, may be null.
 	 * @param connection Database connection to use.
 	 *
 	 * @return Optional with OsAccount, Optional.empty if no account with matching uniqueId is found.
@@ -292,12 +294,12 @@ private Optional<OsAccount> getOsAccountByUniqueId(String uniqueId, Host host, C
 				return Optional.of(osAccountFromResultSet(rs, realm));
 			}
 		} catch (SQLException ex) {
-			throw new TskCoreException(String.format("Error getting OS account for unique id = %s", uniqueId), ex);
+			throw new TskCoreException(String.format("Error getting OS account for unique id = %s and host = %s", uniqueId, (host != null ? host.getName() : "null")), ex);
 		}
 	}
 
 	/**
-	 * Gets a OS Account by the realm/loginName.
+	 * Gets a OS Account by the realm and login name.
 	 *
 	 * @param loginName  Login name.
 	 * @param realm	     Account Realm.
@@ -311,12 +313,9 @@ private Optional<OsAccount> getOsAccountByUniqueId(String uniqueId, Host host, C
 	private Optional<OsAccount> getOsAccountByLoginName(String loginName, OsAccountRealm realm, CaseDbConnection connection) throws TskCoreException {
 
 		String queryString = "SELECT * FROM tsk_os_accounts"
-				+ " WHERE LOWER(login_name) = LOWER('" + loginName + "')";
+				+ " WHERE LOWER(login_name) = LOWER('" + loginName + "')" 
+				+ " AND realm_id = " + realm.getId();
 		
-		if (realm != null) {
-				queryString += " AND realm_id = " + realm.getId();
-		}
-
 		try (Statement s = connection.createStatement();
 				ResultSet rs = connection.executeQuery(s, queryString)) {
 
@@ -505,8 +504,8 @@ public OsAccount createOsAccountByWindowsSID(String sid, Host host) throws TskCo
 	/**
 	 * Gets an OS account with the given SID.
 	 * 
-	 * @param sid Account SID.
-	 * @param host Host for the realm.
+	 * @param sid         Account SID.
+	 * @param host        Host for the realm.
 	 * @param transaction Transaction to use.
 	 * 
 	 * @return Optional with OsAccount, Optional.empty if no matching OsAccount is found.
@@ -609,8 +608,9 @@ public Optional<OsAccount> getOsAccountByLogin(String loginName, String realmNam
 	 * Update the account login name.
 	 * 
 	 * @param accountObjId Object id of the account to update.
-	 * @param loginName Account login name.
-	 * @param transaction Transaction 
+	 * @param loginName    Account login name.
+	 * @param transaction  Transaction
+	 *
 	 * 
 	 * @return OsAccount Updated account.
 	 * 
@@ -736,14 +736,7 @@ OsAccount updateAccount(OsAccount osAccount, CaseDbTransaction transaction ) thr
 		CaseDbConnection connection = transaction.getConnection();
 		db.acquireSingleUserCaseWriteLock();
 		
-		String signature;
-		if (osAccount.getUniqueIdWithinRealm().isPresent())  {
-			signature = String.format("%d/%s", osAccount.getRealm().getId(), osAccount.getUniqueIdWithinRealm().get());
-		} else if (osAccount.getLoginName().isPresent() == false)  {
-			signature = String.format("%d/%s", osAccount.getRealm().getId(), osAccount.getLoginName().get());
-		} else {
-			throw new IllegalArgumentException("Cannot update OS Account, either a uniqueID or a login name must be provided.");
-		}
+		String signature = makeAccountSignature(osAccount.getRealm(), osAccount.getUniqueIdWithinRealm().orElse(null), osAccount.getLoginName().orElse(null));
 		
 		try {
 			String updateSQL = "UPDATE tsk_os_accounts SET "
@@ -771,8 +764,8 @@ OsAccount updateAccount(OsAccount osAccount, CaseDbTransaction transaction ) thr
 			preparedStatement.setInt(5, osAccount.getOsAccountStatus().getId());
 			preparedStatement.setInt(6, osAccount.isAdmin() ? 1 : 0);
 			preparedStatement.setInt(7, osAccount.getOsAccountType().getId());
-			preparedStatement.setLong(8, osAccount.getCreationTime());
-			
+
+			preparedStatement.setLong(8, osAccount.getCreationTime().orElse(null));
 			preparedStatement.setLong(9, osAccount.getId());
 			
 			connection.executeUpdate(preparedStatement);
@@ -827,4 +820,29 @@ private OsAccount osAccountFromResultSet(ResultSet rs, OsAccountRealm realm) thr
 
 		return osAccount;
 	}
+	
+	/**
+	 * Created an account signature for an OS Account. This signature is simply
+	 * to prevent duplicate accounts from being created. Signature is set to:
+	 * realmId/uniqueId: if the account has a uniqueId, otherwise
+	 * realmId/loginName: if the account has a login name.
+	 *
+	 * @param realm     Account realm
+	 * @param uniqueId  Unique id.
+	 * @param loginName Login name.
+	 *
+	 * @return Account signature.
+	 */
+	private String makeAccountSignature(OsAccountRealm realm, String uniqueId,  String loginName) {
+		// Create a signature. 
+		String signature;
+		if (Strings.isNullOrEmpty(uniqueId) == false) {
+			signature = String.format("%d/%s", realm.getId(), uniqueId);
+		} else if (Strings.isNullOrEmpty(loginName) == false)  {
+			signature = String.format("%d/%s", realm.getId(), loginName);
+		} else {
+			throw new IllegalArgumentException("OS Account must have either a uniqueID or a login name.");
+		}
+		return signature;
+	}
 }
diff --git a/bindings/java/src/org/sleuthkit/datamodel/OsAccountRealmManager.java b/bindings/java/src/org/sleuthkit/datamodel/OsAccountRealmManager.java
index e31dba03e9b52afb6ecfe57bbb16e062167e713d..43d3b7bfe5f5dc8f88d69f74120880ba7bd2751e 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/OsAccountRealmManager.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/OsAccountRealmManager.java
@@ -57,7 +57,7 @@ public final class OsAccountRealmManager {
 	 *
 	 * @param realmName Realm name.
 	 * @param host      Host that realm reference was found on. May be null if
-	 *                  you know the realm is a domain and not host-specific.
+	 *                  the realm is a domain and not host-specific.
 	 *
 	 * @return OsAccountRealm Realm.
 	 *
@@ -78,7 +78,7 @@ public OsAccountRealm createRealmByName(String realmName, Host host) throws TskC
 				if (accountRealm.isPresent()) {
 					return accountRealm.get();
 				} else {
-					throw new TskCoreException(String.format("Error creating realm with name = %s", realmName), ex);
+					throw new TskCoreException(String.format("Error creating realm with name = %s and host name = %s", realmName, (host != null ? host.getName() : "null")), ex);
 				}
 			}
 		}
@@ -121,17 +121,14 @@ public OsAccountRealm createRealmByWindowsSid(String sid, Host host) throws TskC
 		}
 		
 		// get subAuthority sid
-		if (org.apache.commons.lang3.StringUtils.countMatches(sid, "-") < 5 ) {
-			throw new IllegalArgumentException(String.format("Invalid SID %s for a host/domain", sid));
-		}
-		String subAuthorityId = sid.substring(0, sid.lastIndexOf('-'));
+		String subAuthorityId = getSubAuthorityId(sid);
 		
 		// RAMAN TBD: can the SID be parsed in some way to determine local vs domain ??
 			
 		try (CaseDbConnection connection = this.db.getConnection()) {
 			return createRealm("Unknown Domain Name", OsAccountRealm.RealmNameType.INFERRED, subAuthorityId, host, connection);
 		} catch (SQLException ex) {
-			// Create may have failed if the realm already exists. try to get the realm by name.
+			// Create may have failed if the realm already exists. try to get the realm by addr.
 			try (CaseDbConnection connection = this.db.getConnection()) {
 				Optional<OsAccountRealm >accountRealm = this.getRealmByAddr(subAuthorityId, host, connection);
 				if (accountRealm.isPresent()) {
@@ -148,8 +145,8 @@ public OsAccountRealm createRealmByWindowsSid(String sid, Host host) throws TskC
 	 * Get the realm for the given user/group SID. The input SID is a user/group
 	 * SID. The domain SID is extracted from this incoming SID.
 	 * 
-	 * @param sid user SID.
-	 * @param host Host for realm, may be null.
+	 * @param sid         User SID.
+	 * @param host        Host for realm, may be null.
 	 * @param transaction Transaction to use for database connection.
 	 * 
 	 * @return Optional with OsAccountRealm, Optional.empty if no realm found with matching real address.
@@ -159,10 +156,7 @@ public OsAccountRealm createRealmByWindowsSid(String sid, Host host) throws TskC
 	public Optional<OsAccountRealm> getRealmByWindowsSid(String sid, Host host, CaseDbTransaction transaction) throws TskCoreException {
 		
 		// get subAuthority sid
-		if (org.apache.commons.lang3.StringUtils.countMatches(sid, "-") < 5 ) {
-			throw new IllegalArgumentException(String.format("Invalid SID %s for a host/domain", sid));
-		}
-		String subAuthorityId = sid.substring(0, sid.lastIndexOf('-'));
+		String subAuthorityId = getSubAuthorityId(sid);
 		
 		CaseDbConnection connection = transaction.getConnection();
 		return this.getRealmByAddr(subAuthorityId, host, connection);
@@ -194,14 +188,13 @@ OsAccountRealm updateRealmName(long realmId, String realmName, OsAccountRealm.Re
 
 			return getRealm(realmId, connection );
 		} catch (SQLException ex) {
-			LOGGER.log(Level.SEVERE, null, ex);
 			throw new TskCoreException(String.format("Error updating realm with name = %s, id = %d", realmName, realmId), ex);
 		} finally {
 			db.releaseSingleUserCaseWriteLock();
 		}
 	}
 	
-	private final String REALM_QUERY_STRING = "SELECT realms.id as realm_id, realms.name as realm_name,"
+	private final static String REALM_QUERY_STRING = "SELECT realms.id as realm_id, realms.name as realm_name,"
 			+ " realms.realm_addr as realm_addr, realms.host_id, realms.name_type, "
 			+ " hosts.id, hosts.name as host_name "
 			+ " FROM tsk_os_account_realms as realms"
@@ -227,6 +220,8 @@ OsAccountRealm getRealm(long id, CaseDbConnection connection) throws TskCoreExce
 			OsAccountRealm accountRealm = null;
 			if (rs.next()) { 
 				accountRealm = resultSetToAccountRealm(rs);
+			} else {
+				throw new TskCoreException(String.format("No realm found with id = %d", id));
 			}
 
 			return accountRealm;
@@ -248,6 +243,8 @@ OsAccountRealm getRealm(long id, CaseDbConnection connection) throws TskCoreExce
 	 */
 	Optional<OsAccountRealm> getRealmByAddr(String realmAddr, Host host, CaseDbConnection connection) throws TskCoreException {
 		
+		// If a host is specified, we want to match the realm with matching name and specified host, or a realm with matching name and no host.
+		// If no host is specified, then we return the first realm with matching name.
 		String whereHostClause = (host == null) 
 							? " 1 = 1 " 
 							: " ( realms.host_id = " + host.getId() + " OR realms.host_id IS NULL) ";
@@ -277,7 +274,8 @@ Optional<OsAccountRealm> getRealmByAddr(String realmAddr, Host host, CaseDbConne
 			} 
 			return Optional.ofNullable(accountRealm);
 		} catch (SQLException ex) {
-			throw new TskCoreException(String.format("Error running the realms query = %s", queryString), ex);
+			throw new TskCoreException(String.format("Error running the realms query = %s with realmaddr = %s and host name = %s", 
+														queryString, realmAddr, (host != null ? host.getName() : "Null")  ), ex);
 		}
 	}
 	
@@ -293,6 +291,8 @@ Optional<OsAccountRealm> getRealmByAddr(String realmAddr, Host host, CaseDbConne
 	 */
 	Optional<OsAccountRealm> getRealmByName(String realmName, Host host, CaseDbConnection connection) throws TskCoreException {
 		
+		// If a host is specified, we want to match the realm with matching name and specified host, or a realm with matching name and no host.
+		// If no host is specified, then we return the first realm with matching name.
 		String whereHostClause = (host == null) 
 							? " 1 = 1 " 
 							: " ( realms.host_id = " + host.getId() + " OR realms.host_id IS NULL ) ";
@@ -348,11 +348,11 @@ private OsAccountRealm resultSetToAccountRealm(ResultSet rs) throws SQLException
 				rs.getString("realm_addr"), realmhost);
 	}
 	
-	/**
-	 * Get all realms.
-	 * 
-	 * @return Collection of OsAccountRealm
-	 */
+//	/**
+//	 * Get all realms.
+//	 * 
+//	 * @return Collection of OsAccountRealm
+//	 */
 //	Collection<OsAccountRealm> getRealms() throws TskCoreException {
 //		String queryString = "SELECT realms.id as realm_id, realms.name as realm_name, realms.realm_addr as realm_addr, realms.host_id, realms.name_type, "
 //				+ " hosts.id, hosts.name as host_name "
@@ -421,15 +421,27 @@ private OsAccountRealm createRealm(String realmName, OsAccountRealm.RealmNameTyp
 
 			// Read back the row id
 			try (ResultSet resultSet = preparedStatement.getGeneratedKeys();) {
-				if (resultSet.next()) {
-					long rowId = resultSet.getLong(1); ;//last_insert_rowid()
-					return  new OsAccountRealm(rowId, realmName, nameType, realmAddr, host);
-				} else {
-					throw new SQLException("Error executing  " + realmInsertSQL);
-				}
+				long rowId = resultSet.getLong(1); // last_insert_rowid()
+				return  new OsAccountRealm(rowId, realmName, nameType, realmAddr, host);
 			}
 		}  finally {
 			db.releaseSingleUserCaseWriteLock();
 		}
 	}
+	
+	/**
+	 * Gets the sub authority id from the given SID.
+	 * 
+	 * @param sid SID
+	 * 
+	 * @return Sub-authority id string.
+	 */
+	private String getSubAuthorityId(String sid) {
+			if (org.apache.commons.lang3.StringUtils.countMatches(sid, "-") < 5 ) {
+			throw new IllegalArgumentException(String.format("Invalid SID %s for a host/domain", sid));
+		}
+		String subAuthorityId = sid.substring(0, sid.lastIndexOf('-'));
+		
+		return subAuthorityId;
+	}
 }
diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
index 159e8c88cd69e7a756a7b27fe25a51c06222ad43..10530f2d45b2566c1eb50d17f5f74b48ea68f5d5 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
@@ -2357,7 +2357,7 @@ private CaseDbSchemaVersionNumber updateFromSchema8dot6toSchema8dot7(CaseDbSchem
 					+ "FOREIGN KEY(attribute_type_id) REFERENCES blackboard_attribute_types(attribute_type_id))");
 
 			// create analysis results tables
-			statement.execute("CREATE TABLE tsk_analysis_results (artifact_obj_id " + bigIntDataType + " NOT NULL, "
+			statement.execute("CREATE TABLE tsk_analysis_results (artifact_obj_id " + bigIntDataType + " PRIMARY KEY, "
 					+ "conclusion TEXT, "
 					+ "significance INTEGER NOT NULL, "
 					+ "confidence INTEGER NOT NULL, "
@@ -2366,7 +2366,7 @@ private CaseDbSchemaVersionNumber updateFromSchema8dot6toSchema8dot7(CaseDbSchem
 					+ "FOREIGN KEY(artifact_obj_id) REFERENCES blackboard_artifacts(artifact_obj_id) ON DELETE CASCADE"
 					+ ")");
 
-			statement.execute("CREATE TABLE tsk_aggregate_score( obj_id " + bigIntDataType + " NOT NULL, "
+			statement.execute("CREATE TABLE tsk_aggregate_score( obj_id " + bigIntDataType + " PRIMARY KEY, "
 					+ "data_source_obj_id " + bigIntDataType + " NOT NULL, "
 					+ "significance INTEGER NOT NULL, "
 					+ "confidence INTEGER NOT NULL, "
@@ -2383,7 +2383,7 @@ private CaseDbSchemaVersionNumber updateFromSchema8dot6toSchema8dot7(CaseDbSchem
 					+ "status INTEGER DEFAULT 0, " // to indicate if the host was merged/deleted
 					+ "UNIQUE(name)) ");
 
-			// Create OS Account and realted tables 
+			// Create OS Account and related tables 
 			statement.execute("CREATE TABLE tsk_os_account_realms (id " + primaryKeyType + " PRIMARY KEY, "
 					+ "name TEXT NOT NULL, " // realm name - host name or domain name
 					+ "realm_addr TEXT DEFAULT NULL, " // a sid/uid or some some other unique identifier, may be null
@@ -2402,7 +2402,7 @@ private CaseDbSchemaVersionNumber updateFromSchema8dot6toSchema8dot7(CaseDbSchem
 					+ "status INTEGER, " // enabled/disabled/deleted
 					+ "admin INTEGER DEFAULT 0," // is admin account
 					+ "type INTEGER, " // service/interactive
-					+ "created_date " + bigIntDataType + ", "
+					+ "created_date " + bigIntDataType + " DEFAULT NULL, "
 					+ "UNIQUE(signature), "
 					+ "FOREIGN KEY(os_account_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
 					+ "FOREIGN KEY(realm_id) REFERENCES tsk_os_account_realms(id) )");
@@ -2434,13 +2434,13 @@ private CaseDbSchemaVersionNumber updateFromSchema8dot6toSchema8dot7(CaseDbSchem
 
 			statement.execute("CREATE TABLE tsk_data_artifacts ( "
 					+ "artifact_obj_id " + bigIntDataType + " PRIMARY KEY, "
-					+ "os_account_obj_id " + bigIntDataType + " NOT NULL, "
+					+ "os_account_obj_id " + bigIntDataType + ", "
 					+ "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) ON DELETE CASCADE) ");
 
 			// add owner_uid & os_account_obj_id columns to tsk_files
 			statement.execute("ALTER TABLE tsk_files ADD COLUMN owner_uid TEXT DEFAULT NULL");
-			statement.execute("ALTER TABLE tsk_files ADD COLUMN os_account_obj_id " + bigIntDataType + " REFERENCES tsk_os_accounts(os_account_obj_id) DEFAULT NULL");
+			statement.execute("ALTER TABLE tsk_files ADD COLUMN os_account_obj_id " + bigIntDataType + " DEFAULT NULL REFERENCES tsk_os_accounts(os_account_obj_id) DEFAULT NULL");
 
 
 			return new CaseDbSchemaVersionNumber(8, 7);
@@ -9212,10 +9212,7 @@ private List<AbstractFile> resultSetToAbstractFiles(ResultSet rs, CaseDbConnecti
 						parentPath = "/"; //NON-NLS
 					}
 					
-					long osAccountObjId = rs.getInt("os_account_obj_id");
-					if (rs.wasNull()) {
-						osAccountObjId = OsAccount.NO_ACCOUNT;
-					}
+					Long osAccountObjId = rs.getLong("os_account_obj_id");
 		
 					LayoutFile lf = new LayoutFile(this,
 							rs.getLong("obj_id"), //NON-NLS
@@ -9293,10 +9290,7 @@ org.sleuthkit.datamodel.File file(ResultSet rs, FileSystem fs) throws SQLExcepti
 	 * @throws SQLException thrown if SQL error occurred
 	 */
 	Directory directory(ResultSet rs, FileSystem fs) throws SQLException {
-		long osAccountObjId = rs.getInt("os_account_obj_id");
-		if (rs.wasNull()) {
-			osAccountObjId = OsAccount.NO_ACCOUNT;
-		}
+		Long osAccountObjId = rs.getLong("os_account_obj_id");
 		
 		Directory dir = new Directory(this, rs.getLong("obj_id"), rs.getLong("data_source_obj_id"), rs.getLong("fs_obj_id"), //NON-NLS
 				TskData.TSK_FS_ATTR_TYPE_ENUM.valueOf(rs.getShort("attr_type")), //NON-NLS
@@ -9446,10 +9440,7 @@ private DerivedFile derivedFile(ResultSet rs, CaseDbConnection connection, long
 			parentPath = "";
 		}
 		
-		long osAccountObjId = rs.getInt("os_account_obj_id");
-		if (rs.wasNull()) {
-			osAccountObjId = OsAccount.NO_ACCOUNT;
-		}
+		Long osAccountObjId = rs.getLong("os_account_obj_id");
 				
 		final DerivedFile df = new DerivedFile(this, objId, rs.getLong("data_source_obj_id"),
 				rs.getString("name"), //NON-NLS
@@ -9505,10 +9496,7 @@ private LocalFile localFile(ResultSet rs, CaseDbConnection connection, long pare
 		if (null == parentPath) {
 			parentPath = "";
 		}
-		long osAccountObjId = rs.getInt("os_account_obj_id");
-		if (rs.wasNull()) {
-			osAccountObjId = OsAccount.NO_ACCOUNT;
-		}
+		Long osAccountObjId = rs.getLong("os_account_obj_id");
 		
 		LocalFile file = new LocalFile(this, objId, rs.getString("name"), //NON-NLS
 				TSK_DB_FILES_TYPE_ENUM.valueOf(rs.getShort("type")), //NON-NLS
@@ -9536,10 +9524,7 @@ private LocalFile localFile(ResultSet rs, CaseDbConnection connection, long pare
 	 * @throws SQLException
 	 */
 	org.sleuthkit.datamodel.SlackFile slackFile(ResultSet rs, FileSystem fs) throws SQLException {
-		long osAccountObjId = rs.getInt("os_account_obj_id");
-		if (rs.wasNull()) {
-			osAccountObjId = OsAccount.NO_ACCOUNT;
-		}
+		Long osAccountObjId = rs.getLong("os_account_obj_id");
 		org.sleuthkit.datamodel.SlackFile f = new org.sleuthkit.datamodel.SlackFile(this, rs.getLong("obj_id"), //NON-NLS
 				rs.getLong("data_source_obj_id"), rs.getLong("fs_obj_id"), //NON-NLS
 				TskData.TSK_FS_ATTR_TYPE_ENUM.valueOf(rs.getShort("attr_type")), //NON-NLS
@@ -9606,10 +9591,7 @@ List<Content> fileChildren(ResultSet rs, CaseDbConnection connection, long paren
 						if (parentPath == null) {
 							parentPath = "";
 						}
-						long osAccountObjId = rs.getInt("os_account_obj_id");
-						if (rs.wasNull()) {
-							osAccountObjId = OsAccount.NO_ACCOUNT;
-						}
+						Long osAccountObjId = rs.getLong("os_account_obj_id");
 						final LayoutFile lf = new LayoutFile(this, rs.getLong("obj_id"),
 								rs.getLong("data_source_obj_id"), rs.getString("name"), type,
 								TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort("dir_type")),
diff --git a/bindings/java/test/org/sleuthkit/datamodel/OsAccountTest.java b/bindings/java/test/org/sleuthkit/datamodel/OsAccountTest.java
index 48990b68833621fd2812482b5882b89f8f0333a9..b6a0f90fd73e280a473dd4a6791061cd6bfb89c3 100644
--- a/bindings/java/test/org/sleuthkit/datamodel/OsAccountTest.java
+++ b/bindings/java/test/org/sleuthkit/datamodel/OsAccountTest.java
@@ -252,14 +252,14 @@ public void basicOsAccountTests() throws TskCoreException {
 			
 			// Let's update osAccount1
 			String fullName1 = "Johnny Depp";
-			long creationTime1 = 1611858618;
+			Long creationTime1 = 1611858618L;
 			osAccount1.setCreationTime(creationTime1);
 			osAccount1.setFullName(fullName1);
 			osAccount1.setIsAdmin(true);
 			
 			osAccount1 = caseDB.getOsAccountManager().updateAccount(osAccount1, transaction);
 			
-			assertEquals(osAccount1.getCreationTime(), creationTime1);
+			assertEquals(osAccount1.getCreationTime().orElse(null), creationTime1);
 			
 			
 			transaction.commit();
@@ -279,7 +279,7 @@ public void basicOsAccountTests() throws TskCoreException {
 			
 			assertEquals(osAccount1_copy1.isAdmin(), true); // should be true now
 			assertEquals(osAccount1_copy1.getFullName().orElse("").equalsIgnoreCase(fullName1), true);
-			assertEquals(osAccount1_copy1.getCreationTime(), creationTime1);
+			assertEquals(osAccount1.getCreationTime().orElse(null), creationTime1);
 			
 		}