Рубрики
Без рубрики

Автоматически сгенерированное поле для MongoDB с помощью Spring Boot

Узнайте, как генерировать последовательные, автоматически увеличиваемые значения для поля id и имитировать то же поведение, что и в базах данных SQL.

Автор оригинала: baeldung.

1. Обзор

В этом уроке мы узнаем, как реализовать последовательное, автоматически сгенерированное поле для MongoDB в Spring Boot.

Когда мы используем MongoDB в качестве базы данных для приложения Spring Boot, мы не можем использовать аннотацию @GeneratedValue в наших моделях, поскольку она недоступна. Следовательно, нам нужен метод, который даст тот же эффект, что и при использовании JPA и базы данных SQL.

Общее решение этой проблемы простое. Мы создадим коллекцию (таблицу), в которой будет храниться сгенерированная последовательность для других коллекций. Во время создания новой записи мы будем использовать ее для получения следующего значения.

2. Зависимости

Давайте добавим следующие стартеры spring-boot в наш pom.xml :


    
        org.springframework.boot
        spring-boot-starter-web
        2.2.2.RELEASE
    
    
        org.springframework.boot
        spring-boot-starter-data-mongodb
        2.2.2.RELEASE
    

Последняя версия зависимостей управляется spring-boot-starter-parent .

3. Коллекции

Как описано в обзоре, мы создадим коллекцию, в которой будет храниться автоматически увеличенная последовательность для других коллекций. Мы назовем эту коллекцию database_sequences. Он может быть создан с помощью mongo shell или компаса MongoDB. Давайте создадим соответствующий класс модели:

@Document(collection = "database_sequences")
public class DatabaseSequence {

    @Id
    private String id;

    private long seq;

    //getters and setters omitted
}

Затем давайте создадим коллекцию users и соответствующий объект модели, в котором будут храниться сведения о людях, использующих нашу систему:

@Document(collection = "users")
public class User {

    @Transient
    public static final String SEQUENCE_NAME = "users_sequence";

    @Id
    private long id;

    private String email;

    //getters and setters omitted
}

В модели User , созданной выше, мы добавили статическое поле SEQUENCE_NAME, которое является уникальной ссылкой на автоматически увеличиваемую последовательность для коллекции users .

Мы также аннотируем его с помощью @Transient , чтобы он не сохранялся вместе с другими свойствами модели.

4. Создание новой записи

До сих пор мы создали необходимые коллекции и модели. Теперь мы создадим сервис, который будет генерировать автоматически увеличиваемое значение, которое можно использовать в качестве id для наших сущностей.

Давайте создадим Службу генератора последовательностей , которая имеет generate Sequence() :

public long generateSequence(String seqName) {
    DatabaseSequence counter = mongoOperations.findAndModify(query(where("_id").is(seqName)),
      new Update().inc("seq",1), options().returnNew(true).upsert(true),
      DatabaseSequence.class);
    return !Objects.isNull(counter) ? counter.getSeq() : 1;
}

Теперь мы можем использовать generate Sequence() при создании новой записи:

User user = new User();
user.setId(sequenceGenerator.generateSequence(User.SEQUENCE_NAME));
user.setEmail("[email protected]");
userRepository.save(user);

Чтобы перечислить всех пользователей, мы будем использовать UserRepository :

List storedUsers = userRepository.findAll();
storedUsers.forEach(System.out::println);

Как и сейчас, мы должны устанавливать поле id каждый раз, когда создаем новый экземпляр нашей модели. Мы можем обойти этот процесс, создав прослушиватель для событий жизненного цикла Spring Data MongoDB.

Для этого мы создадим Прослушиватель модели пользователя это распространяется AbstractMongoEventListener<Пользователь> и тогда мы переопределим onBeforeConvert() :

@Override
public void onBeforeConvert(BeforeConvertEvent event) {
    if (event.getSource().getId() < 1) {
        event.getSource().setId(sequenceGenerator.generateSequence(User.SEQUENCE_NAME));
    }
}

Теперь каждый раз, когда мы сохраняем нового Пользователя, идентификатор будет установлен автоматически.

5. Заключение

В заключение мы рассмотрели, как генерировать последовательные, автоматически увеличивающиеся значения для поля id и имитировать то же поведение, что и в базах данных SQL.

Hibernate использует аналогичный метод для создания автоматически увеличиваемых значений по умолчанию.

Как обычно, полный исходный код доступен на Github .