Java MongoDb getting id as a timestamp but need the hexadecimal string
Asked Answered
C

3

5

I'm doing a CRUD for a collection named Schema and need to retrieve de _id as a hexadecimal string, but when i use the collection.find() i get the timestamp and date instead of the string.

I'm receving this structure:

{
"_id": {
            "timestamp": 1604689898,
            "date": "2020-11-06T19:11:38.000+00:00"
        }
}

But i need something like this:

{
"_id": "5fa5a085a4b09b307d53ed57"
}

Here are my configurations

Pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>co.com.itau</groupId>
    <artifactId>crypto-mongodb-java-ms</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>crypto-mongodb-java-ms</name>
    <description>Microservice to save and read data from mongoDB using CSFLE</description>

    <properties>
        <java.version>1.8</java.version>
        <version.fabric8-maven-plugin>3.5.41</version.fabric8-maven-plugin>
        <swagger.version>3.0.0</swagger.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.plugin</groupId>
            <artifactId>spring-plugin-core</artifactId>
            <version>2.0.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
        <dependency> 
            <groupId>io.springfox</groupId> 
            <artifactId>springfox-boot-starter</artifactId> 
            <version>${swagger.version}</version> 
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.1.2.RELEASE</version>
        </dependency>
          <dependency>
            <groupId>org.springframework.plugin</groupId>
            <artifactId>spring-plugin-core</artifactId>
            <version>2.0.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongodb-crypt</artifactId>
            <version>1.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    
    <profiles>
        <profile>
            <id>openshift</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>io.fabric8</groupId>
                        <artifactId>fabric8-maven-plugin</artifactId>
                        <version>${version.fabric8-maven-plugin}</version>
                        <executions>
                            <execution>
                                <id>fmp</id>
                                <phase>package</phase>
                                <goals>
                                    <goal>resource</goal>
                                    <goal>build</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <generator>
                                <config>
                                    <spring-boot>
                                        <fromMode>isTag</fromMode>
                                        <from>redhat-openjdk18-openshift:1.2</from>
                                    </spring-boot>
                                </config>
                            </generator>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

</project>

MongoClient configuration

CodecRegistry pojoCodecRegistry = fromProviders(PojoCodecProvider.builder().automatic(true).build());
        CodecRegistry codecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), pojoCodecRegistry);
        
        MongoClient mongoAux = MongoClients.create(MongoClientSettings.builder()
                .applyConnectionString(new ConnectionString(connectionString))
                .codecRegistry(codecRegistry)
                .build());
        
        return mongoAux;

Schema Model

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Schema {
    
    @JsonProperty("_id")
    @SerializedName("_id")
    public ObjectId id;

    public String db;
    
    public String collection;
    
    public Document schema;
}

** Repository **

@Repository
public class SchemaMongoRepository implements SchemaRepository{


    @Value("${mongodb.schema.db}")
    private String mongoDatabase;

    @Value("${mongodb.schema.collection}")
    private String mongoCollection;
    
    
    private static final Logger logger = LoggerFactory.getLogger(SchemaMongoRepository.class);

    @Autowired
    private MongoClient mongoClient;
    
    @Autowired
    private DataKey datakey;
    
    private MongoCollection<Schema> schemaCollection;
    
    @PostConstruct
    void init() {
        schemaCollection = mongoClient.getDatabase(mongoDatabase).getCollection(mongoCollection, Schema.class);
    }

    @Override
    public List<Schema> getSchemas() {
    
        List<Schema> schemaList = new ArrayList<Schema>();
        FindIterable<Schema> result = schemaCollection.find();
        
        for(Schema currentSchema: result) {
            schemaList.add(currentSchema);
        }
        return schemaList;
    }
}
Cineaste answered 7/11, 2020 at 0:22 Comment(0)
M
5

The problem you face is ObjectId becomes extended (Deserialized). we make it serialization.Add this dependency in pom

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.0.rc1</version>
</dependency>

Add the following method in main class.

@Bean
public Jackson2ObjectMapperBuilderCustomizer customizer()
{
    return builder -> builder.serializerByType(ObjectId.class,new ToStringSerializer());
}

This will give you expected output.

Meilhac answered 7/11, 2020 at 2:10 Comment(3)
I've applied this solution but still I'm in a situation where I've a array of objectId in a field and while returning, it's returning jobTypes as date and timestamp. "jobTypes": [{"timestamp": 1683773584, "date": 1683773584000}, {"timestamp": 1683773591, "date": 1683773591000}] but it should be like following "jobTypes": ["645c5890a24c041c3697d23f", "645c5897a24c041c3697d240"]Swiercz
@RafiMahmud did you try adding in the main class?Meilhac
Yes, same as you showed in your answer.Swiercz
Q
2

In my case, using Kotlin it was so simple as to add a Jackson JSON serializer:

@JsonSerialize(using = ToStringSerializer::class)
val id: ObjectId = ObjectId.get(),

In order to get:

{
    "id": "622b34af87c70514f6452363",
    ...
}

instead of:

{
    "id": {
        "timestamp": 1646998703,
        "date": "2022-03-11T11:38:23.000+00:00"
    },
    ...
}
Quartering answered 11/3, 2022 at 14:25 Comment(0)
G
1

Adding this annotation to the id variable fixed it for me in Java 17.

@JsonSerialize(using = ToStringSerializer.class)
Ginzburg answered 25/3, 2023 at 6:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.