- User entity contains links to other objects
- When we want to connect two users then we update two documents
- Concurrent issues fixed with version + retry or manual rollback or use @Transactions
- Consistency issues should be resolved manually (background job). Example: when we remove one user then
another one will contain broken link.
@Document(collection = "users")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class User {
@Id
private String id;
private String name;
@Version
private Long version;
@DocumentReference(lazy = true)
private List<User> friends;
}
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
public User create(String name) {
User user = User.builder()
.name(name)
.build();
userRepository.save(user);
return user;
}
public void delete(String id) {
userRepository.deleteById(id);
}
public void connect(String userId1, String userId2) {
var user1 = userRepository.findById(userId1).orElseThrow();
var user2 = userRepository.findById(userId2).orElseThrow();
if (user1.getFriends() == null) {
user1.setFriends(new ArrayList<>());
}
user1.getFriends().add(user2);
if (user2.getFriends() == null) {
user2.setFriends(new ArrayList<>());
}
user2.getFriends().add(user1);
userRepository.saveAll(List.of(user1, user2)); // is not atomic
}
}