6

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;
    }
}
0

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

3 Comments

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"]
@RafiMahmud did you try adding in the main class?
Yes, same as you showed in your answer.
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"
    },
    ...
}

Comments

2

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

@JsonSerialize(using = ToStringSerializer.class)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.