Spring Boot - Remove _class field from MongoDB document - Walking Techie

Blog about Java programming, Design Pattern, and Data Structure.

Sunday, July 1, 2018

Spring Boot - Remove _class field from MongoDB document

This post will explain, how to remove _class field from MongoDB document. In general, when you save the document in MongoDB collection a _class field also stored. The _class field value is fully qualified name of the model/entity class.

Let's see an example when you save the document in DB without any MongoDB configuration changes in the code.

{
    "_id" : ObjectId("5b3223904406cd02eb752cd7"),
    "name" : "Walking Techie",
    "email" : "walkingtechie.blogspot@gmail.com",
    "address" : {
        "name" : "Walking Techie",
        "address" : "Test",
        "city" : "Bangalore",
        "state" : "KA",
        "country" : "India",
        "pincode" : "560078"
    },
    "_class" : "com.walking.techie.model.Person"
}

Our problem statement is that we need to remove a _class field from above document. So that when we save the document in DB, the _class field should not save in document. The document should look like below example:

{
    "_id" : ObjectId("5b3227654406cd09274fccfa"),
    "name" : "Walking Techie",
    "email" : "walkingtechie.blogspot@gmail.com",
    "address" : {
        "name" : "Walking Techie",
        "address" : "Test",
        "city" : "Bangalore",
        "state" : "KA",
        "country" : "India",
        "pincode" : "560078"
    }
}

Project structure

This is a directory structure of the standard Maven project.
Spring Boot - Remove _class field from MongoDB document

Project dependencies

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.walking.techie</groupId>
    <artifactId>remove-underscore-class-mongodb</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>remove-underscore-class-mongodb</name>
    <description>Remove _class from document in mongodb</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.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</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

application.properties file

Below MongoDB property connect to "db" database on localhost with default port 27017.
#mongo db configuration details
spring.data.mongodb.database=db
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017

Create AppMongoConfig class for MongoDB

AppMongoConfig is a Configuration class. converter.setTypeMapper(new DefaultMongoTypeMapper(null)); will set _class field as null.

package com.walking.techie.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;

@Configuration
public class AppMongoConfig {
  @Autowired private MongoDbFactory mongoDbFactory;

  @Autowired private MongoMappingContext mongoMappingContext;

  @Bean
  public MappingMongoConverter mappingMongoConverter() {

    DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory);
    MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mongoMappingContext);
    converter.setTypeMapper(new DefaultMongoTypeMapper(null));

    return converter;
  }
}

Create bootstrap

PersonBootstrap has implemented an interface ApplicationListener with ContextRefreshedEvent, which actually raise an event when application context gets initialized or refreshed.

When application context gets initialized then onApplicationEvent method gets called and person object will get saved in DB.

package com.walking.techie.bootstrap;

import com.walking.techie.model.Address;
import com.walking.techie.model.Person;
import com.walking.techie.repository.PersonRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import java.util.Optional;

@Slf4j
@Component
public class PersonBootstrap implements ApplicationListener<ContextRefreshedEvent> {
  private final PersonRepository personRepository;

  public PersonBootstrap(PersonRepository personRepository) {
    this.personRepository = personRepository;
  }

  @Override
  public void onApplicationEvent(ContextRefreshedEvent event) {
    Person person = loadPerson();
    Person savedPerson = personRepository.save(person);
    log.info("Person saved in DB :: {}", savedPerson);
    Optional<Person> personById = personRepository.findById(savedPerson.getId());
    if (personById.isPresent()) {
      log.info("Person fetched from DB :: {} with id :: {}", personById.get(), savedPerson.getId());
    }
  }

  private Person loadPerson() {
    Person person = new Person();
    person.setName("Walking Techie");
    person.setEmail("walkingtechie.blogspot@gmail.com");
    person.setAddress(loadAddress());
    return person;
  }

  private Address loadAddress() {
    Address address = new Address();
    address.setName("Walking Techie");
    address.setAddress("Test");
    address.setCity("Bangalore");
    address.setCountry("India");
    address.setPincode("560078");
    address.setState("KA");
    return address;
  }
}

Java model class

package com.walking.techie.model;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document
@Data
public class Person {
  @Id private String id;
  private String name;
  private String email;
  private Address address;
}
package com.walking.techie.model;

import lombok.Data;

@Data
public class Address {

  private String name;
  private String address;
  private String city;
  private String state;
  private String country;
  private String pincode;
}

PersonRepository

PersonRepository will save the person POJO object into MongoDB as a document.

package com.walking.techie.repository;

import com.walking.techie.model.Person;
import org.springframework.data.mongodb.repository.MongoRepository;

public interface PersonRepository extends MongoRepository<Person, String> {}

Run Application

package com.walking.techie;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}

Output

When you run this standalone application you will see something like below:

2018-06-26 17:15:41.505  INFO 2343 --- [           main] org.mongodb.driver.connection            : Opened connection [connectionId{localValue:2, serverValue:87}] to localhost:27017
2018-06-26 17:15:41.524  INFO 2343 --- [           main] c.w.techie.bootstrap.PersonBootstrap     : Person saved in DB :: Person(id=5b3227654406cd09274fccfa, name=Walking Techie, email=walkingtechie.blogspot@gmail.com, address=Address(name=Walking Techie, address=Test, city=Bangalore, state=KA, country=India, pincode=560078))
2018-06-26 17:15:41.544  INFO 2343 --- [           main] c.w.techie.bootstrap.PersonBootstrap     : Person fetched from DB :: Person(id=5b3227654406cd09274fccfa, name=Walking Techie, email=walkingtechie.blogspot@gmail.com, address=Address(name=Walking Techie, address=Test, city=Bangalore, state=KA, country=India, pincode=560078)) with id :: 5b3227654406cd09274fccfa
2018-06-26 17:15:41.547  INFO 2343 --- [           main] com.walking.techie.Application           : Started Application in 2.381 seconds (JVM running for 3.189)

9 comments :

  1. It’s a wonderful blog you shared here, I read the whole content and found it so easy to understand in language and is also full of amazing and useful information. Thanks a lot for sharing it.
    Hire MongoDB Developer India

    ReplyDelete
  2. In AppMongoConfig, MongoDbFactory is deprecated. use MongoDatabaseFactory instead.

    ReplyDelete
  3. Nice article. Keep doing the good work.

    ReplyDelete
  4. Good Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging.

    Digital Marketing Training in Chennai

    Digital Marketing Course in Chennai

    ReplyDelete
  5. nice information thanks for shring............................!
    spring boot certification course training

    ReplyDelete