class IssueManager {

    @Transactional(propagation = Propagation.REQUIRED)
    public Issue updateIssue(Long issueId, IssueVO issueVO) {
        validateIssueParameters(issueVO);
        Issue existingIssue = loadIssueAndCheckIfNotClosed(issueId);
        Issue issue = updateIssueObject(existingIssue, issueVO);
        issueDao.updateIssue(issue);

        // Find the attachments that were removed during update and delete them
        HashSet<Attachment> newAttachments = new HashSet<>(issueVO.getAttachments());
        List<Attachment> allAttachments = attachmentDao.loadAttachmentsByIssueId(issueId);
        List<Attachment> toDelete = allAttachments.stream().filter(a -> !newAttachments.contains(a))
            .collect(Collectors.toList());
        attachmentFileManager.deleteAttachments(toDelete);

        // Link new attachments to this issue
        issueVO.getAttachments().forEach(a -> attachmentDao.updateAttachmentIssueId(a.getId(), issueId));

        return issue;
    }

}