skip to Main Content

I have studied on mongodb with spring boot

I install mongo with docker-compose, I use Mongo Compass to interactive with mongo database, and I create product database

version: "3.8"
services:
    mongodb:
        image : mongo
        container_name: mongodb
        environment:
        - PUID=1000
        - PGID=1000
        volumes:
        - ./database/product-service/mongodb:/data/db
        ports:
        - 27017:27017
        restart: unless-stopped

Spring Boot code

Controller

@RestController
@RequestMapping("/api/v1/product")
@RequiredArgsConstructor
public class ProductController {
    private final ProductService productService;

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public void createProduct(@RequestBody ProductRequest productRequest) {
        productService.createProduct(productRequest);
    }

    @GetMapping
    @ResponseStatus(HttpStatus.OK)
    public List<ProductResponse> getAllProducts() {
        return productService.getAllProducts();
    }
}

Service

@Service
@RequiredArgsConstructor
@Slf4j
public class ProductService {
    private final ProductRepository productRepository;

    public void createProduct(ProductRequest productRequest) {
        Product product = Product.builder()
                .name(productRequest.getName())
                .description(productRequest.getDescription())
                .price(productRequest.getPrice())
                .build();
        productRepository.save(product);
        log.info("Product {} is saved", product.getId());
    }

    public List<ProductResponse> getAllProducts() {
        List<Product>products = productRepository.findAll();
        log.info("Get all products");
        return products.stream().map(product -> map2ProductResponse(product)).toList();
    }

    private ProductResponse map2ProductResponse(Product product) {
        return ProductResponse.builder()
                .id(product.getId())
                .name(product.getName())
                .description(product.getDescription())
                .price(product.getPrice())
                .build();
    }
}

entity

@Document(value = "product")
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class Product {
    private String id;
    private String name;
    private String description;
    private BigDecimal price;
}

With spring boot app, I configed on appllication.properties file like that

spring.data.mongodb.uri=mongodb://127.0.0.1:27017/product

Because I have found some posts

I have tried replace with this, nothing change

spring.data.mongodb.port=27017
spring.data.mongodb.database=product
spring.data.mongodb.host=localhost

when I check the Mongo Compass, it always connect to test database, although I specify product database like application.properties

enter image description here

I have also found the similar question, I have tried with that solution, it not working for me and the solution is too complicated for me. It raise a error

Error creating bean with name 'mongoConfig': Injection of autowired dependencies failed

And I can not fix that problem, because I’m new with mongo

How I can change spring boot app connect to another database?

2

Answers


  1. Chosen as BEST ANSWER

    I have tried to read mongo for a couple hours docs, I have found the solution.

    Almost of authentication mechanisms, we can not set database name

    For example with default authentication mechanism using connection string or mongo credential, I don't see the parameter for database name, only include username, authenticationDb, and password

    With connection string:

    MongoClient mongoClient = MongoClients
    .create("mongodb://<username>:<password>@<hostname>:<port>/?authSource=<authenticationDb>");
    

    With MongoCredential:

    MongoCredential credential = MongoCredential.createCredential("<username>", "<authenticationDb>", "<password>");
    MongoClient mongoClient = MongoClients.create(
        MongoClientSettings.builder()
            .applyToClusterSettings(builder ->
                    builder.hosts(Arrays.asList(new ServerAddress("<hostname>", <port>))))
            .credential(credential)
            .build());
    

    Other mechanisms are same.

    Thus, I have tried to create config file

    
    @Configuration
    public class MongoDBConfig {
        @Bean
        public MongoClient mongoClient() {
            return MongoClients.create("mongodb://root:[email protected]:27018");
        }
    }
    
    

    and add database name in application.properties

    spring.data.mongodb.database=product
    

    Its amazing, it work perfectly like I want


  2. I see that you have database and collection name same as "product". Try different naming for database and collection for standardization.
    
    For connecting to product database from your java code, you could write a configuration class annotated with @ConfigurationProperties(prefix = "spring.data.mongodb") with a bean for MongoClient like this
    
        @Bean
            public MongoClient mongoClient() {
                    return MongoClients.create(getConnectionString());
            }
    
    You can build the connectionString from your application.properties like this:
    var sb = new StringBuilder();
            sb.append("mongodb://");
            
                sb.append(getDBUsername(dbUserName));
                sb.append(":");
                sb.append(getDBPasswordByPath(dbPassword));
                sb.append("@");
            sb.append(getHost());
            sb.append(":");
            sb.append(getPort());
            sb.append("/");
            sb.append(getDbName());
            sb.append("?retrywrites=false");
       
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search