orb-livan
orb-livan

Reputation: 43

Java Quarkus + MongoDB : Unable to make connection to the database

I have a small containerized application running Java Quarkus, connected to a MongoDB database. For whatever reason, I've been struggling with this simple error for a long time.

    
2025-01-12 23:50:26,954 INFO  [org.mon.dri.cluster] (executor-thread-1) 
No server chosen by ReadPreferenceServerSelector{readPreference=primary} from cluster description ClusterDescription{type=UNKNOWN, connectionMode=SINGLE, serverDescriptions=[ServerDescription{address=localhost:27017, type=UNKNOWN, state=CONNECTING, 
exception={com.mongodb.MongoSocketOpenException: 
Exception opening socket}, 
caused by {java.net.ConnectException: Connection refused}}]}. Waiting for 30000 ms before timing out

To me this seems like an indication of the application being unable to connect to the mongodb instance and read from it, which is something I've been unable to resolve up until now.

These are the entity classes that represent the objects, I'm trying to read/write.

package com.mongodb;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.bson.types.ObjectId;

import java.util.Objects;

public class PersonEntity {

    @JsonSerialize(using = ToStringSerializer.class)
    public ObjectId id;
    public String name;
    public Integer age;

    public PersonEntity() {
    }

    public PersonEntity(ObjectId id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    @Override
    public int hashCode() {
        int result = id != null ? id.hashCode() : 0;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        result = 31 * result + (age != null ? age.hashCode() : 0);
        return result;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        PersonEntity that = (PersonEntity) o;

        if (!Objects.equals(id, that.id)) return false;
        if (!Objects.equals(name, that.name)) return false;
        return Objects.equals(age, that.age);
    }

    public ObjectId getId() {
        return id;
    }

    public void setId(ObjectId id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}


package com.mongodb;

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoCollection;
import jakarta.enterprise.context.ApplicationScoped;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;

import java.util.ArrayList;
import java.util.List;

import static com.mongodb.client.model.Filters.eq;
import static com.mongodb.client.model.Updates.inc;

@ApplicationScoped
public class PersonRepository {

    private final MongoClient mongoClient;
    private final MongoCollection<PersonEntity> coll;

    public PersonRepository(MongoClient mongoClient) {
        this.mongoClient = mongoClient;
        this.coll = mongoClient.getDatabase("test").getCollection("persons", PersonEntity.class);
    }

    public String add(PersonEntity person) {
        return coll.insertOne(person).getInsertedId().asObjectId().getValue().toHexString();
    }

    public List<PersonEntity> getPersons() {
        return coll.find().into(new ArrayList<>());
    }

    public long anniversaryPerson(String id) {
        Bson filter = eq("_id", new ObjectId(id));
        Bson update = inc("age", 1);
        return coll.updateOne(filter, update).getModifiedCount();
    }

    public long deletePerson(String id) {
        Bson filter = eq("_id", new ObjectId(id));
        return coll.deleteOne(filter).getDeletedCount();
    }
}



package com.mongodb;

import jakarta.inject.Inject;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;

import java.util.List;

@Path("/api")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class PersonResource {

    @Inject
    PersonRepository personRepository;

    @GET
    @Path("/hello")
    public String hello() {
        return "Hello from Quarkus REST";
    }

    @POST
    @Path("/person")
    public String createPerson(PersonEntity person) {
        return personRepository.add(person);
    }

    @GET
    @Path("/persons")
    public List<PersonEntity> getPersons() {
        return personRepository.getPersons();
    }

    @PUT
    @Path("/person/{id}")
    public long anniversaryPerson(@PathParam("id") String id) {
        return personRepository.anniversaryPerson(id);
    }

    @DELETE
    @Path("/person/{id}")
    public long deletePerson(@PathParam("id") String id) {
        return personRepository.deletePerson(id);
    }
}

The connection string in my application.properties is as follows:

quarkus.mongodb.connection-string=mongodb://localhost:27017

Im using MongoDB v8.0.4 on Ubuntu 22.04. The project is built with Maven (v3.9.9)

What I've tried so far:

Any help would be greatly appreciated, as this issue has been bothering me for an entire day now.

Kind regards

Upvotes: 0

Views: 94

Answers (1)

Muhammad Naeem
Muhammad Naeem

Reputation: 1

I faced a similar issue integrating MongoDB with my Java application. The error occurs because the MongoDB container refuses connections due to network accessibility. To fix it:

  1. Update the bindIp in mongod.conf to 0.0.0.0 and restart MongoDB:
    net:
      bindIp: 0.0.0.0
    
  2. If using Docker, ensure the container exposes the port:
    docker run -d -p 27017:27017 mongo:8.0.4
    
  3. Use the correct connection string (e.g., container name if both are containerized):
    quarkus.mongodb.connection-string=mongodb://mongodb-container-name:27017
    
  4. Allow port 27017 through your firewall:
    sudo ufw allow 27017
    

Hope this helps!

Upvotes: 0

Related Questions