Source:
<code>public void updateParticipant(Study study, StudyParticipant participant) { checkNotNull(study); checkNotNull(participant); StudyParticipantValidator validator = new StudyParticipantValidator( externalIdService, substudyService, study, false); Validate.entityThrowingException(validator, participant); Account account = getAccountThrowingException(study, participant.getId()); Set<Roles> callerRoles = BridgeUtils.getRequestContext().getCallerRoles(); boolean isSimpleAdd = account.getExternalId() == null && participant.getExternalId() != null; boolean isResearcherChange = callerRoles.contains(Roles.RESEARCHER) && !Objects.equals(account.getExternalId(), participant.getExternalId()); boolean assigningExternalId = isSimpleAdd || isResearcherChange; if (assigningExternalId) { if (account.getExternalId() != null) { externalIdService.unassignExternalId(account, account.getExternalId()); } account.setExternalId(participant.getExternalId()); } updateAccountAndRoles(study, account, participant, false); if (participant.getStatus() != null) { if (callerRoles.contains(Roles.ADMIN) || callerRoles.contains(Roles.WORKER)) { account.setStatus(participant.getStatus()); } } if (assigningExternalId) { final ExternalIdentifier externalId = externalIdService.beginAssignExternalId(account, participant.getExternalId()); accountDao.updateAccount(account, (modifiedAccount) -> externalIdService.commitAssignExternalId(externalId)); } else { <START> accountDao.updateAccount(account, null); <END> } }</code><technical_language>tests for cases (a) assign external ID call commit hook (b) assign external ID, pass in a commit hook</technical_language>

Target:
public void updateParticipant(Study study, StudyParticipant participant) { checkNotNull(study); checkNotNull(participant); Account account = null; if (participant.getId() != null) { account = getAccountThrowingExceptionIfSubstudyMatches( AccountId.forId(study.getIdentifier(), participant.getId())); } StudyParticipantValidator validator = new StudyParticipantValidator( externalIdService, substudyService, study, false); Validate.entityThrowingException(validator, participant); Set<Roles> callerRoles = BridgeUtils.getRequestContext().getCallerRoles(); Set<String> allExternalIds = BridgeUtils.collectExternalIds(account); boolean isSimpleAdd = allExternalIds.isEmpty() && participant.getExternalId() != null; boolean isResearcherAdd = callerRoles.contains(Roles.RESEARCHER) && !allExternalIds.contains(participant.getExternalId()) && participant.getExternalId() != null; boolean assigningExternalId = isSimpleAdd || isResearcherAdd; if (assigningExternalId) { account.setExternalId(participant.getExternalId()); } updateAccountAndRoles(study, account, participant, false); if (participant.getStatus() != null) { if (callerRoles.contains(Roles.ADMIN) || callerRoles.contains(Roles.WORKER)) { account.setStatus(participant.getStatus()); } } if (!assigningExternalId) { accountDao.updateAccount(account, null); return; } ExternalIdentifier externalId = beginAssignExternalId(account, participant.getExternalId()); try { accountDao.updateAccount(account, (modifiedAccount) -> externalIdService.commitAssignExternalId(externalId)); } catch (Exception e) { if (externalId != null) { externalIdService.unassignExternalId(account, externalId.getIdentifier()); } throw e; } }