RED-6310: Moved code to create user-preferences to a separate class so that the calling code can handle a persistence exception
This commit is contained in:
parent
643ffc8723
commit
45bd8e6003
@ -10,6 +10,8 @@ import java.util.stream.Collectors;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.notification.NotificationPreferencesEntity;
|
||||
@ -18,15 +20,20 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.notification.NotificationPreferences;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.notification.NotificationType;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
|
||||
public class NotificationPreferencesPersistenceService {
|
||||
|
||||
private final NotificationPreferencesRepository notificationPreferencesRepository;
|
||||
NotificationPreferencesRepository notificationPreferencesRepository;
|
||||
|
||||
private final NotificationRepository notificationRepository;
|
||||
NonThreadSafeNotificationPreferencesRepositoryWrapper notificationPreferencesRepositoryWrapper;
|
||||
|
||||
NotificationRepository notificationRepository;
|
||||
|
||||
|
||||
@Transactional
|
||||
@ -64,18 +71,17 @@ public class NotificationPreferencesPersistenceService {
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
// This method intentionally does not have a @Transactional annotation, since it needs to handle an underlying transaction exception.
|
||||
public NotificationPreferencesEntity getOrCreateNotificationPreferences(String userId) {
|
||||
|
||||
return notificationPreferencesRepository.findByUserId(userId).orElseGet(() -> {
|
||||
|
||||
var notificationPreference = new NotificationPreferencesEntity();
|
||||
notificationPreference.setUserId(userId);
|
||||
notificationPreference.setEmailNotificationsEnabled(false);
|
||||
notificationPreference.setInAppNotificationsEnabled(true);
|
||||
notificationPreference.setInAppNotifications(Arrays.stream(NotificationType.values()).map(Enum::name).collect(Collectors.toList()));
|
||||
return notificationPreferencesRepository.save(notificationPreference);
|
||||
});
|
||||
try {
|
||||
// The method called here will fail if it is called concurrently (more than 1 thread), since it will always try to create
|
||||
// the desired entity. But the exception only means, that the entity has been created by another thread.
|
||||
// In that case we can just fetch the data from the db.
|
||||
return notificationPreferencesRepositoryWrapper.getOrCreateNotificationPreferences(userId);
|
||||
} catch (DataIntegrityViolationException ex) {
|
||||
return notificationPreferencesRepository.getByUserId(userId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -91,4 +97,29 @@ public class NotificationPreferencesPersistenceService {
|
||||
return notificationPreferencesRepository.findAll();
|
||||
}
|
||||
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
|
||||
private static class NonThreadSafeNotificationPreferencesRepositoryWrapper {
|
||||
|
||||
NotificationPreferencesRepository notificationPreferencesRepository;
|
||||
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRES_NEW)
|
||||
public NotificationPreferencesEntity getOrCreateNotificationPreferences(String userId) {
|
||||
|
||||
return notificationPreferencesRepository.findByUserId(userId).orElseGet(() -> {
|
||||
|
||||
var notificationPreference = new NotificationPreferencesEntity();
|
||||
notificationPreference.setUserId(userId);
|
||||
notificationPreference.setEmailNotificationsEnabled(false);
|
||||
notificationPreference.setInAppNotificationsEnabled(true);
|
||||
notificationPreference.setInAppNotifications(Arrays.stream(NotificationType.values()).map(Enum::name).collect(Collectors.toList()));
|
||||
return notificationPreferencesRepository.save(notificationPreference);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -11,6 +11,9 @@ public interface NotificationPreferencesRepository extends JpaRepository<Notific
|
||||
Optional<NotificationPreferencesEntity> findByUserId(String userId);
|
||||
|
||||
|
||||
NotificationPreferencesEntity getByUserId(String userId);
|
||||
|
||||
|
||||
void deleteByUserId(String userId);
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user