Kotlin – SpringBoot MongoDB – Model One-to-One, One-to-Many Relationships Embedded Documents

With MongoDB, we can structure related data by embedded documents. In general, embedding gives a better performance for read operations. So in the tutorial, JavaSampleApproach will show you way to work with Embedded Documents using SpringBoot by Kotlin language.

I. Technologies

– Kotlin 1.2.20
– Apache Maven 3.5.2
– Spring Tool Suite – Version 3.9.0.RELEASE
– Spring Boot – 1.5.10.RELEASE
– MongoDB: v3.4.1

II. MongoDB – Embedded Documents

Embedded Documents are generally known as denormalized models. It is a way to structure related data in a single document. See below diagram:

kotlin mongodb-embedded-document-structure

In general, we decide to design data as embedded models in case: data contains one-to-one or one-to-many relationships between entities.

With embedding data model, in general, it gives us a better performance for read operations. And we can use a single atomic read/write database operation to request and retrieve or update related data.

However, a weakness point is embedding related data in documents may lead to situations where documents grow after creation.

III. Practice

In the tutorial, we use SpringToolSuite to create a Kotlin SpringBoot project for MongoDB embedded documents:

kotlin mongodb-embedded-document-project structure

Step to do
– Create Kotlin SpringBoot project
– Create Document models
– Create MongoRepository
– Implement Client
– Run and check results

1. Create Kotlin SpringBoot project

Using Spring Tool Suite, create a Kotlin SpringBoot project. Then open pom.xml file, add dependencies:


    org.springframework.boot
    spring-boot-starter-data-mongodb

 

    com.fasterxml.jackson.core
    jackson-databind

2. Create Document models

Create 3 class models {Company, Product, Contact} with one-to-one relationship between Company & Contact, and one-to-many relationship between >Company & Product in embedded data model structure.

– Company model:

package com.javasampleapproach.kotlin.mongodb.model

import org.springframework.data.annotation.Id
import org.springframework.data.mongodb.core.mapping.Document

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

@Document(collection="company")
class Company(
	@Id
	val id: Int,
    val name: String,
    val products: List,
    val contact: Contact
){
	override fun toString(): String{
		val mapper = ObjectMapper()
		mapper.enable(SerializationFeature.INDENT_OUTPUT)
		val jsonString = mapper.writeValueAsString(this)
		return jsonString 
	}
}

– Contact model:

package com.javasampleapproach.kotlin.mongodb.model

class Contact(
	val address: String,
	val phone: String
)

– Product model:

package com.javasampleapproach.kotlin.mongodb.model

class Product(
	val code: String,
	val name: String,
	val details: String
)
3. Create MongoRepository
package com.javasampleapproach.kotlin.mongodb.repository

import com.javasampleapproach.kotlin.mongodb.model.Company

import org.springframework.data.mongodb.repository.MongoRepository
import org.springframework.data.mongodb.repository.Query

interface CompanyRepository: MongoRepository{
	fun findByName(name: String): List
	
	@Query("{'contact.address': ?0}")
	fun findByAddress(address: String): List
}

– Open application.properties, add configuration to connect with Mongo Server:

spring.data.mongodb.database=jsa_mongodb
spring.data.mongodb.port=27017
4. Implement Client

Use CommandLineRunner to implement a simple client to manipulate data from MongoDB via CompanyRepository:

package com.javasampleapproach.kotlin.mongodb

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

import org.springframework.context.annotation.Bean
import org.springframework.boot.CommandLineRunner

import com.javasampleapproach.kotlin.mongodb.model.*
import com.javasampleapproach.kotlin.mongodb.repository.CompanyRepository

@SpringBootApplication
class KotlinSpringMongoDbEmbeddedDocumentApplication{

	@Bean
	fun imageProcess(companyRepo: CompanyRepository) = CommandLineRunner {
		// clear database
		println("==========Delete all company entities==========");
		companyRepo.deleteAll();
		
		// save Documents to MongoDB
		System.out.println("==========Save list of company entities==========");
		companyRepo.save(listOf(
				// Apple company & products
				Company(1, "Apple",
						
						        // list of products
								listOf(Product("A-123", "Iphone 7", "Price: 649.00 USD & FREE shipping"),
													  Product("A-456", "IPadPro", "Price: 417.67 USD & FREE shipping")),
								
								// contact
								Contact("Cupertino, CA 95014", "1-408-996-1010")),
				
				// Samsung company & products
				Company(2, "Samsung",
						
						       // list of products
						       listOf(Product("S-012", "GalaxyJ7", "Price: 219.00 USD & FREE shipping"),
														Product("S-456", "GalaxyTabA", "Price: 299.99 USD & FREE shipping")),
						       
						       // contact
						       Contact("Seocho District, Seoul, South Korea", "+82-2-2053-3000"))))
		// fetch all documents
		println("==========Fetch aLL companies:==========")
		var companies = companyRepo.findAll()
		companies.forEach{println(it)}
		
		// find Company by name
		println("==========Find a company by name:==========")
		companies = companyRepo.findByName("Samsung")
		companies.forEach{println(it)}
		
		// find Company by address
		println("==========Find a company by address:==========")
		companies = companyRepo.findByAddress("Cupertino, CA 95014")
		companies.forEach{println(it)}
	}
}

fun main(args: Array) {
    SpringApplication.run(KotlinSpringMongoDbEmbeddedDocumentApplication::class.java, *args)
}

5. Run and check results

Start MongoDB server by commandline: .\MongoDB\Server\3.4\bin>mongod.exe

-> Logs:

2018-02-11T00:04:10.112-0700 I CONTROL  [initandlisten] MongoDB starting : pid=7976 port=27017 dbpath=D:\data\db\ 64-bit host=LOILE-COMPUTER
2018-02-11T00:04:10.113-0700 I CONTROL  [initandlisten] targetMinOS: Windows 7/Windows Server 2008 R2
2018-02-11T00:04:10.116-0700 I CONTROL  [initandlisten] db version v3.4.9

Run the SpringBoot project with commandline: mvn spring-boot:run

-> Logs:

==========Delete all company entities==========
==========Save list of company entities==========
==========Fetch aLL companies:==========
{
  "id" : 1,
  "name" : "Apple",
  "products" : [ {
    "code" : "A-123",
    "name" : "Iphone 7",
    "details" : "Price: 649.00 USD & FREE shipping"
  }, {
    "code" : "A-456",
    "name" : "IPadPro",
    "details" : "Price: 417.67 USD & FREE shipping"
  } ],
  "contact" : {
    "address" : "Cupertino, CA 95014",
    "phone" : "1-408-996-1010"
  }
}
{
  "id" : 2,
  "name" : "Samsung",
  "products" : [ {
    "code" : "S-012",
    "name" : "GalaxyJ7",
    "details" : "Price: 219.00 USD & FREE shipping"
  }, {
    "code" : "S-456",
    "name" : "GalaxyTabA",
    "details" : "Price: 299.99 USD & FREE shipping"
  } ],
  "contact" : {
    "address" : "Seocho District, Seoul, South Korea",
    "phone" : "+82-2-2053-3000"
  }
}
==========Find a company by name:==========
{
  "id" : 2,
  "name" : "Samsung",
  "products" : [ {
    "code" : "S-012",
    "name" : "GalaxyJ7",
    "details" : "Price: 219.00 USD & FREE shipping"
  }, {
    "code" : "S-456",
    "name" : "GalaxyTabA",
    "details" : "Price: 299.99 USD & FREE shipping"
  } ],
  "contact" : {
    "address" : "Seocho District, Seoul, South Korea",
    "phone" : "+82-2-2053-3000"
  }
}
==========Find a company by address:==========
{
  "id" : 1,
  "name" : "Apple",
  "products" : [ {
    "code" : "A-123",
    "name" : "Iphone 7",
    "details" : "Price: 649.00 USD & FREE shipping"
  }, {
    "code" : "A-456",
    "name" : "IPadPro",
    "details" : "Price: 417.67 USD & FREE shipping"
  } ],
  "contact" : {
    "address" : "Cupertino, CA 95014",
    "phone" : "1-408-996-1010"
  }
}

Run MongoDB shell by commandline: .\MongoDB\Server\3.4\bin>mongo.exe.

-> Logs:

 
MongoDB shell version v3.4.9
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.9

Results with MongoDB shell:

>
>
> show dbs
jsa_mongodb  0.000GB
>
> use jsa_mongodb
switched to db jsa_mongodb
>
> show collections
company
>
> db.company.find()
{ "_id" : 1, "_class" : "com.javasampleapproach.kotlin.mongodb.model.Company", "name" : "Apple", "products" : [ { "code" : "A-123", "name" : "Iphone 7", "details" : "Price: 649.00 USD & FREE shipping" }, { "code" : "A-456", "name" : "IPadPro", "details" : "Price: 417.67 USD & FREE shipping" } ], "contact" : { "address" : "Cupertino, CA 95014", "phone" : "1-408-996-1010" } }
{ "_id" : 2, "_class" : "com.javasampleapproach.kotlin.mongodb.model.Company", "name" : "Samsung", "products" : [ { "code" : "S-012", "name" : "GalaxyJ7", "details" : "Price: 219.00 USD & FREE shipping" }, { "code" : "S-456", "name" : "GalaxyTabA", "details" : "Price: 299.99 USD & FREE shipping" } ], "contact" : { "address" : "Seocho District, Seoul, South Korea", "phone" : "+82-2-2053-3000" } }
>
>

IV. Sourcecode

KotlinSpringMongoDbEmbeddedDocument



By grokonez | February 11, 2018.


Related Posts


Got Something To Say:

Your email address will not be published. Required fields are marked *

*