Spring
provides default type mapping between Java and MongoDB documents. MongoDB
drivers has native support to map java primitive types to a mogoDB document
types. Apart from tis, Spring Data MongoDB provides built-in in converters to
map LocalDate, DateTime etc.,
If you
want to map a custom type or types that do not have build-in converters, you
can create a Custom Type converter by implementing Converter interface.
Let’s
write a converter to convert ZonedDateTime to Date and vice versa.
@Component
@ReadingConverter
public class ZonedDateTimeReadConverter implements Converter<Date, ZonedDateTime> {
@Override
public ZonedDateTime convert(Date date) {
System.out.println("Reading Converter called");
return date.toInstant().atZone(ZoneOffset.UTC);
}
}
Step 2:
Create a writing converter that converts ZonedDateTime
to Date.
@Component
@WritingConverter
public class ZonedDateTimeWriteConverter implements Converter<ZonedDateTime, Date> {
@Override
public Date convert(ZonedDateTime zonedDateTime) {
System.out.println("Writing Converter called");
return Date.from(zonedDateTime.toInstant());
}
}
Step 3:
Create an instance of
MongoCustomConversions and register the converters ZonedDateTimeReadConverter,
ZonedDateTimeWriteConverter.
@Bean
public MongoCustomConversions customConversions() {
List<Converter<?, ?>> converters = new ArrayList<>();
converters.add(new ZonedDateTimeReadConverter());
converters.add(new ZonedDateTimeWriteConverter());
return new MongoCustomConversions(converters);
}
That’s it
you are done.
Find the
below working application.
package com.sample.app.entity;
import java.time.ZonedDateTime;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.index.IndexDirection;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
@Document("employees")
public class Employee {
@Id
private String id;
@Field("employee_first_name")
@Indexed(name = "emp_first_name", direction = IndexDirection.ASCENDING)
private String firstName;
@Field("employee_last_name")
private String lastName;
@Transient
private String fullName;
private ZonedDateTime dateOfBirth;
public Employee() {
}
public Employee(String firstName, String lastName, ZonedDateTime dateOfBirth) {
this.firstName = firstName;
this.lastName = lastName;
this.dateOfBirth = dateOfBirth;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFullName() {
return this.firstName + "," + this.lastName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public ZonedDateTime getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(ZonedDateTime dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Employee [id=").append(id).append(", firstName=").append(firstName).append(", lastName=")
.append(lastName).append(", fullName=").append(fullName).append(", dateOfBirth=").append(dateOfBirth)
.append("]");
return builder.toString();
}
}
EmployeeRepository.java
package com.sample.app.repository;
import java.util.List;
import java.util.stream.Stream;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.stereotype.Repository;
import com.sample.app.entity.Employee;
@Repository
public interface EmployeeRepository extends MongoRepository<Employee, String> {
List<Employee> findByFirstName(String firstName);
List<Employee> findByLastName(String lastName);
List<Employee> findByFirstNameAndLastName(String firstName, String lastName);
@Query("{'firstName' : ?0}")
Stream<Employee> findAllByCustomQueryAndStream(String firstName);
}
ZonedDateTimeReadConverter.java
package com.sample.app.converter;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.stereotype.Component;
@Component
@ReadingConverter
public class ZonedDateTimeReadConverter implements Converter<Date, ZonedDateTime> {
@Override
public ZonedDateTime convert(Date date) {
System.out.println("Reading Converter called");
return date.toInstant().atZone(ZoneOffset.UTC);
}
}
ZonedDateTimeWriteConverter.java
package com.sample.app.converter;
import java.time.ZonedDateTime;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.WritingConverter;
import org.springframework.stereotype.Component;
@Component
@WritingConverter
public class ZonedDateTimeWriteConverter implements Converter<ZonedDateTime, Date> {
@Override
public Date convert(ZonedDateTime zonedDateTime) {
System.out.println("Writing Converter called");
return Date.from(zonedDateTime.toInstant());
}
}
application.properties
spring.data.mongodb.database=myorg spring.data.mongodb.port=27017 spring.data.mongodb.host=localhost logging.level.org.springframework.data=WARN
pom.xml
<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>springDataMongo</groupId>
<artifactId>springDataMongo</artifactId>
<version>1</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
</dependencies>
</project>
App.java
package com.sample.app;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import com.mongodb.MongoClient;
import com.sample.app.converter.ZonedDateTimeReadConverter;
import com.sample.app.converter.ZonedDateTimeWriteConverter;
import com.sample.app.entity.Employee;
import com.sample.app.repository.EmployeeRepository;
@SpringBootApplication
public class App {
@Value("${spring.data.mongodb.database}")
private String database;
@Value("${spring.data.mongodb.host}")
private String host;
@Value("${spring.data.mongodb.port}")
private int port;
@Autowired
private EmployeeRepository empRepository;
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
public void dropPreviousData() {
MongoClient mongoClient = new MongoClient(host, port);
MongoOperations mongoOps = new MongoTemplate(mongoClient, database);
mongoOps.dropCollection("employees");
}
@Bean
public CommandLineRunner demo() {
return (args) -> {
dropPreviousData();
ZonedDateTime dateOfBirth1 = ZonedDateTime.of(1965, 5, 15, 12, 5, 43, 1, ZoneOffset.UTC);
ZonedDateTime dateOfBirth2 = ZonedDateTime.of(1975, 6, 16, 13, 6, 44, 2, ZoneOffset.UTC);
ZonedDateTime dateOfBirth3 = ZonedDateTime.of(1985, 7, 17, 14, 7, 45, 3, ZoneOffset.UTC);
ZonedDateTime dateOfBirth4 = ZonedDateTime.of(1995, 8, 18, 15, 8, 46, 4, ZoneOffset.UTC);
Employee emp1 = new Employee("Phalgun", "Garimella", dateOfBirth1);
Employee emp2 = new Employee("Sankalp", "Dubey", dateOfBirth2);
Employee emp3 = new Employee("Arpan", "Garimella", dateOfBirth3);
Employee emp4 = new Employee("Phalgun", "Dubey", dateOfBirth4);
empRepository.saveAll(Arrays.asList(emp1, emp2, emp3, emp4));
List<Employee> emps = empRepository.findAll();
emps.forEach(System.out::println);
};
}
@Bean
public MongoCustomConversions customConversions() {
List<Converter<?, ?>> converters = new ArrayList<>();
converters.add(new ZonedDateTimeReadConverter());
converters.add(new ZonedDateTimeWriteConverter());
return new MongoCustomConversions(converters);
}
}
Total
project structure looks like below.
Run
App.java, you can see below messages in console.
Writing Converter called Writing Converter called Writing Converter called Writing Converter called Reading Converter called Reading Converter called Reading Converter called Reading Converter called Employee [id=5d54c216e4c7d861d5fb57c2, firstName=Phalgun, lastName=Garimella, fullName=null, dateOfBirth=1965-05-15T12:05:43Z] Employee [id=5d54c216e4c7d861d5fb57c3, firstName=Sankalp, lastName=Dubey, fullName=null, dateOfBirth=1975-06-16T13:06:44Z] Employee [id=5d54c216e4c7d861d5fb57c4, firstName=Arpan, lastName=Garimella, fullName=null, dateOfBirth=1985-07-17T14:07:45Z] Employee [id=5d54c216e4c7d861d5fb57c5, firstName=Phalgun, lastName=Dubey, fullName=null, dateOfBirth=1995-08-18T15:08:46Z]
You can
download complete working application from this link.
No comments:
Post a Comment