UUID as Entity ID in MongoDB – UUID作为MongoDB中的实体ID

最后修改: 2022年 7月 3日

1. Overview


By default, the MongoDB Java driver generates IDs of the type ObjectId. Sometimes, we may want to use another type of data as the unique identifier of an object, such as a UUID. However, the MongoDB Java driver can’t generate UUIDs automatically.

默认情况下,MongoDB Java 驱动程序会生成类型为 ObjectId 的 ID。有时,我们可能希望使用其他类型的数据作为对象的唯一标识符,例如UID。然而,MongoDB Java 驱动程序不能自动生成 UUID

In this tutorial, we’ll look at three ways to generate UUIDs with the MongoDB Java driver and Spring Data MongoDB.

在本教程中,我们将了解使用 MongoDB Java 驱动程序和Spring Data MongoDB生成 UUID 的三种方法。

2. Common Points


It’s quite rare for an application to manage only one type of data. To simplify the management of the IDs in our MongoDB database, it’s easier to implement an abstract class that will define the ID of all our Document classes.


public abstract class UuidIdentifiedEntity {

    protected UUID id;    

    public void setId(UUID id) {

        if (this.id != null) {
            throw new UnsupportedOperationException("ID is already defined");

        this.id = id;

    // Getter

For the examples in this tutorial, we’ll assume that all classes persisted in the MongoDB database inherited from this class.


3. Configuring UUID Support


To allow storage of UUIDs in MongoDB, we must configure the driver. This configuration is very simple and only tells the driver how to store UUIDs in the database. We must handle this carefully if several applications use the same database.


All we have to do is to specify the uuidRepresentation parameter in our MongoDB client at startup:


public MongoClient mongo() throws Exception {
    ConnectionString connectionString = new ConnectionString("mongodb://localhost:27017/test");
    MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
    return MongoClients.create(mongoClientSettings);

If we use Spring Boot, we can specify this parameter in our application.properties file:

如果我们使用Spring Boot,我们可以在application.properties文件中指定这个参数。


4. Using Lifecycle Events


The first method to handle the generation of UUID is by using Spring’s lifecycle events. With MongoDB entities, we can’t use JPA annotations @PrePersist and so on. Therefore, we have to implement event listener classes registered in the ApplicationContext. To do so, our classes must extend the Spring’s AbstractMongoEventListener class:

处理UUID生成的第一种方法是通过使用Spring的生命周期事件。对于MongoDB实体,我们不能使用JPA注解@PrePersist等。因此,我们必须实现在ApplicationContext中注册的事件监听器类。为此,我们的类必须扩展 Spring 的 AbstractMongoEventListener class

public class UuidIdentifiedEntityEventListener extends AbstractMongoEventListener<UuidIdentifiedEntity> {
    public void onBeforeConvert(BeforeConvertEvent<UuidIdentifiedEntity> event) {
        UuidIdentifiedEntity entity = event.getSource();
        if (entity.getId() == null) {

In this case, we’re using the OnBeforeConvert event, which is triggered before Spring converts our Java object to a Document object and sends it to the MongoDB driver.


Typing our event to catch UuidIdentifiedEntity class allows handling all subclasses of this abstract supertype. Spring will call our code as soon as an object using a UUID as ID is converted.


We must be aware that, Spring delegates event handling to a TaskExecutor which may be asynchronous. Spring does not guarantee that the event is processed before the object is effectively converted. This method is discouraged in the case your TaskExecutor is asynchronous as the ID may be generated after the object has been converted, leading to an Exception:


InvalidDataAccessApiUsageException: Cannot autogenerate id of type java.util.UUID for entity

InvalidDataAccessApiUsageException。无法为实体自动生成 java.util.UUID 类型的 ID

We can register the event listener in the ApplicationContext by annotating it with @Component or by generating it in a @Configuration class:


public UuidIdentifiedEntityEventListener uuidIdentifiedEntityEventListener() {
    return new UuidIdentifiedEntityEventListener();

5. Using Entity Callbacks


Spring infrastructure provides hooks to execute custom code at some points in the lifecycle of an entity. Those are called EntityCallbacks, and we can use them in our case to generate a UUID before the object is persisted in the database.


Unlike the event listener method seen previously, callbacks guarantee that their execution is synchronous and the code will run at the expected point in the object’s lifecycle.


Spring Data MongoDB provides a set of callbacks we can use in our application. In our case, we’ll use the same event as previously. Callbacks can be provided directly in the @Configuration class:

Spring Data MongoDB提供了一组我们可以在应用中使用的回调。在我们的案例中,我们将使用与之前相同的事件。回调可以直接在@Configuration类中提供

public BeforeConvertCallback<UuidIdentifiedEntity> beforeSaveCallback() {
    return (entity, collection) -> {
        if (entity.getId() == null) {
        return entity;

We can also use a Component that implements the BeforeConvertCallback interface.


6. Using Custom Repositories


Spring Data MongoDB provides a third method to achieve our goal: using a custom repository implementation. Usually, we just have to declare an interface inheriting from MongoRepository, and then Spring handles repositories-related code.

Spring Data MongoDB提供了第三种方法来实现我们的目标:使用自定义的存储库实现。通常情况下,我们只需声明一个继承自MongoRepository的接口,然后由Spring处理与存储库相关的代码。

If we want to change the way Spring Data handles our objects, we can define custom code that Spring will execute at the repository level. To do so, we must first define an interface extending MongoRepository:

如果我们想改变Spring Data处理对象的方式,我们可以定义Spring将在存储库级别执行的自定义代码。要做到这一点,我们必须首先定义一个扩展MongoRepository的接口。

public interface CustomMongoRepository<T extends UuidIdentifiedEntity> extends MongoRepository<T, UUID> { }

The @NoRepositoryBean annotation prevents Spring from generating the usual piece of code associated with a MongoRepository. This interface forces the use of UUID as the type of the ID in the objects.

@NoRepositoryBean 注释阻止 Spring 生成与 MongoRepository 相关的常规代码。该接口强制使用 UUID 作为对象中的 ID 类型。

Then, we must create a repository class that will define the required behavior to handle our UUIDs:


public class CustomMongoRepositoryImpl<T extends UuidIdentifiedEntity> 
  extends SimpleMongoRepository<T, UUID> implements CustomMongoRepository<T>

In this repository, we’ll have to catch all methods calls where we need to generate an ID by overriding the relevant methods of SimpleMongoRepository. Those methods are save() and insert() in our case:


public <S extends T> S save(S entity) {
    return super.save(entity);

Finally, we need to tell Spring to use our custom class as the implementation of the repositories instead of the default implementation. We do that in the @Configuration class:


@EnableMongoRepositories(basePackages = "com.baeldung.repository", repositoryBaseClass = CustomMongoRepositoryImpl.class)

Then, we can declare our repositories as usual with no changes:


public interface BookRepository extends MongoRepository<Book, UUID> { }

7. Conclusion


In this article, we have seen three ways to implement UUIDs as MongoDB object’s ID with Spring Data MongoDB.

在这篇文章中,我们看到了用Spring Data MongoDB实现UUID作为MongoDB对象ID的三种方法。

As always, the code used in this article is available over on GitHub.