BAEL-5404 - UUID as Entity ID in MongoDB

Commit to spring-data-mongodb-2
This commit is contained in:
HARDEMAN Sebastien 2022-06-27 15:32:38 +02:00
parent 02e904b225
commit 073a07f4ca
12 changed files with 456 additions and 0 deletions

View File

@ -0,0 +1,23 @@
package com.baeldung.uuid.event;
import java.util.UUID;
import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
import com.baeldung.uuid.model.UuidIdentifiedEntity;
public class UuidIdentifiedEntityEventListener extends AbstractMongoEventListener<UuidIdentifiedEntity> {
@Override
public void onBeforeConvert(BeforeConvertEvent<UuidIdentifiedEntity> event) {
super.onBeforeConvert(event);
UuidIdentifiedEntity entity = event.getSource();
if(entity.getId() == null) {
entity.setId(UUID.randomUUID());
}
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.uuid.model;
import org.springframework.data.mongodb.core.mapping.Document;
@Document
public class Book extends UuidIdentifiedEntity {
private String title;
private String author;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}

View File

@ -0,0 +1,25 @@
package com.baeldung.uuid.model;
import java.util.UUID;
import org.springframework.data.annotation.Id;
public abstract class UuidIdentifiedEntity {
@Id
protected UUID id;
public UUID getId() {
return id;
}
public void setId(UUID id) {
if(this.id != null) {
throw new UnsupportedOperationException("ID is already defined");
}
this.id = id;
}
}

View File

@ -0,0 +1,11 @@
package com.baeldung.uuid.repository;
import java.util.UUID;
import org.springframework.data.mongodb.repository.MongoRepository;
import com.baeldung.uuid.model.Book;
public interface BookRepository extends MongoRepository<Book, UUID> {
}

View File

@ -0,0 +1,14 @@
package com.baeldung.uuid.repository;
import java.util.UUID;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.repository.NoRepositoryBean;
import com.baeldung.uuid.model.UuidIdentifiedEntity;
@NoRepositoryBean
public interface CustomMongoRepository<T extends UuidIdentifiedEntity> extends MongoRepository<T, UUID> {
}

View File

@ -0,0 +1,52 @@
package com.baeldung.uuid.repository.impl;
import java.util.List;
import java.util.UUID;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;
import com.baeldung.uuid.model.UuidIdentifiedEntity;
import com.baeldung.uuid.repository.CustomMongoRepository;
public class CustomMongoRepositoryImpl<T extends UuidIdentifiedEntity> extends SimpleMongoRepository<T, UUID> implements CustomMongoRepository<T> {
public CustomMongoRepositoryImpl(MongoEntityInformation<T, UUID> metadata, MongoOperations mongoOperations) {
super(metadata, mongoOperations);
}
@Override
public <S extends T> S save(S entity) {
generateId(entity);
return super.save(entity);
}
@Override
public <S extends T> List<S> saveAll(Iterable<S> entities) {
entities.forEach(entity -> generateId(entity));
return super.saveAll(entities);
}
@Override
public <S extends T> S insert(S entity) {
generateId(entity);
return super.insert(entity);
}
@Override
public <S extends T> List<S> insert(Iterable<S> entities) {
entities.forEach(entity -> generateId(entity));
return super.insert(entities);
}
protected <S extends T> void generateId(S entity) {
if(entity != null && entity.getId() == null) {
entity.setId(UUID.randomUUID());
}
}
}

View File

@ -0,0 +1,59 @@
package com.baeldung.uuid;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.baeldung.uuid.config.CustomRepositoryMongoConfig;
import com.baeldung.uuid.model.Book;
import com.baeldung.uuid.repository.BookRepository;
/**
*
* This test requires:
* * mongodb instance running on the environment
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CustomRepositoryMongoConfig.class)
public class CustomRepositoryLiveTest {
@Autowired
private BookRepository bookRepository;
@Autowired
private MongoOperations mongoOps;
@Before
public void testSetup() {
if (!mongoOps.collectionExists(Book.class)) {
mongoOps.createCollection(Book.class);
}
}
@After
public void tearDown() {
mongoOps.dropCollection(Book.class);
}
@Test
public void whenInsertingBook_thenBookIsInserted() {
final Book book = new Book();
book.setTitle("The Lord of the Rings");
book.setAuthor("JRR Tolkien");
Book savedBook = bookRepository.save(book);
Book result = mongoOps.findOne(Query.query(Criteria.where("_id").is(savedBook.getId())), Book.class);
assertEquals(result.getTitle(), "The Lord of the Rings");
}
}

View File

@ -0,0 +1,64 @@
package com.baeldung.uuid;
import static org.junit.Assert.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.baeldung.uuid.config.EntityCallbackMongoConfig;
import com.baeldung.uuid.model.Book;
import com.baeldung.uuid.repository.BookRepository;
/**
*
* This test requires:
* * mongodb instance running on the environment
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = EntityCallbackMongoConfig.class)
public class EntityCallbackLiveTest {
@Autowired
private BookRepository bookRepository;
@Autowired
private MongoOperations mongoOps;
@Before
public void testSetup() {
if (!mongoOps.collectionExists(Book.class)) {
mongoOps.createCollection(Book.class);
}
}
@After
public void tearDown() {
mongoOps.dropCollection(Book.class);
}
@Test
public void whenSavingArticle_thenArticleIsInserted() {
final Book book = new Book();
book.setTitle("The Lord of the Rings");
book.setAuthor("JRR Tolkien");
Book savedArticle = bookRepository.save(book);
Book result = mongoOps.findOne(Query.query(Criteria.where("_id").is(savedArticle.getId())), Book.class);
assertNotNull(result);
assertEquals(result.getTitle(), "The Lord of the Rings");
}
}

View File

@ -0,0 +1,64 @@
package com.baeldung.uuid;
import static org.junit.Assert.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.baeldung.uuid.config.EventMongoConfig;
import com.baeldung.uuid.model.Book;
import com.baeldung.uuid.repository.BookRepository;
/**
*
* This test requires:
* * mongodb instance running on the environment
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = EventMongoConfig.class)
public class EventLiveTest {
@Autowired
private BookRepository bookRepository;
@Autowired
private MongoOperations mongoOps;
@Before
public void testSetup() {
if (!mongoOps.collectionExists(Book.class)) {
mongoOps.createCollection(Book.class);
}
}
@After
public void tearDown() {
mongoOps.dropCollection(Book.class);
}
@Test
public void whenSavingArticle_thenArticleIsInserted() {
final Book book = new Book();
book.setTitle("The Lord of the Rings");
book.setAuthor("JRR Tolkien");
Book savedArticle = bookRepository.save(book);
Book result = mongoOps.findOne(Query.query(Criteria.where("_id").is(savedArticle.getId())), Book.class);
assertNotNull(result);
assertEquals(result.getTitle(), "The Lord of the Rings");
}
}

View File

@ -0,0 +1,32 @@
package com.baeldung.uuid.config;
import org.bson.UuidRepresentation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import com.baeldung.uuid.repository.impl.CustomMongoRepositoryImpl;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
@Configuration
@EnableMongoRepositories(basePackages = "com.baeldung.uuid.repository", repositoryBaseClass = CustomMongoRepositoryImpl.class)
public class CustomRepositoryMongoConfig {
@Bean
public MongoClient mongo() throws Exception {
final ConnectionString connectionString = new ConnectionString("mongodb://localhost:27017/test");
final MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
.uuidRepresentation(UuidRepresentation.STANDARD)
.applyConnectionString(connectionString).build();
return MongoClients.create(mongoClientSettings);
}
@Bean
public MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongo(), "test");
}
}

View File

@ -0,0 +1,48 @@
package com.baeldung.uuid.config;
import java.util.UUID;
import org.bson.UuidRepresentation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertCallback;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import com.baeldung.uuid.model.UuidIdentifiedEntity;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
@Configuration
@EnableMongoRepositories(basePackages = "com.baeldung.uuid.repository")
public class EntityCallbackMongoConfig {
@Bean
public MongoClient mongo() throws Exception {
final ConnectionString connectionString = new ConnectionString("mongodb://localhost:27017/test");
final MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
.uuidRepresentation(UuidRepresentation.STANDARD)
.applyConnectionString(connectionString).build();
return MongoClients.create(mongoClientSettings);
}
@Bean
public MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongo(), "test");
}
@Bean
public BeforeConvertCallback<UuidIdentifiedEntity> beforeSaveCallback() {
return (entity, collection) -> {
if(entity.getId() == null) {
entity.setId(UUID.randomUUID());
}
return entity;
};
}
}

View File

@ -0,0 +1,38 @@
package com.baeldung.uuid.config;
import org.bson.UuidRepresentation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import com.baeldung.uuid.event.UuidIdentifiedEntityEventListener;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
@Configuration
@EnableMongoRepositories(basePackages = "com.baeldung.uuid.repository")
public class EventMongoConfig {
@Bean
public MongoClient mongo() throws Exception {
final ConnectionString connectionString = new ConnectionString("mongodb://localhost:27017/test");
final MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
.uuidRepresentation(UuidRepresentation.STANDARD)
.applyConnectionString(connectionString).build();
return MongoClients.create(mongoClientSettings);
}
@Bean
public MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongo(), "test");
}
@Bean
public UuidIdentifiedEntityEventListener uuidIdentifiedEntityEventListener() {
return new UuidIdentifiedEntityEventListener();
}
}