@Override public void saveAllMembersAndSubsystems(Collection<Member> members) { LocalDateTime now = LocalDateTime.now(); // process members Map<MemberId, Member> unprocessedOldMembers = new HashMap<>(); StreamSupport.stream(memberRepository.findAll().spliterator(), false) .forEach(member -> unprocessedOldMembers.put(member.createKey(), member)); for (Member member : members) { Member oldMember = unprocessedOldMembers.get(member.createKey()); if (oldMember == null) { // brand new item member.getStatusInfo().setTimestampsForNew(now); for (Subsystem subsystem : member.getAllSubsystems()) { subsystem.getStatusInfo().setTimestampsForNew(now); subsystem.setMember(member); } member = memberRepository.save(member); } else { handleOldMember(now, member, oldMember); member = memberRepository.save(oldMember); } unprocessedOldMembers.remove(member.createKey()); } // now unprocessedOldMembers should all be removed (either already removed, or will be now) removeUnprocessedOldMembers(now, unprocessedOldMembers); }
private void handleOldMember(LocalDateTime now, Member member, Member oldMember) { oldMember.updateWithDataFrom(member, now); // process subsystems for the old member Map<SubsystemId, Subsystem> unprocessedOldSubsystems = new HashMap<>(); for (Subsystem subsystem : oldMember.getAllSubsystems()) { unprocessedOldSubsystems.put(subsystem.createKey(), subsystem); } for (Subsystem subsystem : member.getAllSubsystems()) { Subsystem oldSubsystem = unprocessedOldSubsystems.get(subsystem.createKey()); if (oldSubsystem == null) { // brand new item, add it subsystem.getStatusInfo().setTimestampsForNew(now); subsystem.setMember(oldMember); oldMember.getAllSubsystems().add(subsystem); } else { oldSubsystem.getStatusInfo().setTimestampsForFetched(now); } unprocessedOldSubsystems.remove(subsystem.createKey()); } // remaining old subsystems - that were not included in member.subsystems - // are removed (if not already) for (Subsystem oldToRemove : unprocessedOldSubsystems.values()) { StatusInfo status = oldToRemove.getStatusInfo(); if (!status.isRemoved()) { status.setTimestampsForRemoved(now); } } }