Spring Boot Kotlin JPA CRUD Example with MySQL



In this tutorial, we will learn how to build Restful APIs with Kotlin, Spring Boot, MySQL, JPA, and Hibernate.

What will we build?

In this tutorial, we’ll build Restful APIs for a mini blog application. The blog has a list of Posts. We’ll write APIs for creating, retrieving, updating, and deleting a Post

We’ll use MySQL as our data source and JPA & Hibernate to access the data from the database.

All right, Let’s now create the application.

1. Creating the Spring Boot Application

We’ll use Spring initializr web tool to bootstrap our application. Follow the steps below to generate the application :


Go to http://start.spring.io

Select Kotlin in the language section.

Enter Artifact as kotlin-demo

Add Web, JPA, and MySQL dependencies.

Click Generate to generate and download the project.

Once the project is generated, unzip it and import it into your favorite IDE.

2. Configure MySQL Database

We’ll need to configure MySQL database URL, username, and password so that Spring Boot can create a Data source.

Open src/main/resources/application.properties file and add the following properties to it -

spring.datasource.url = jdbc:mysql://localhost:3306/demo?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false
spring.datasource.username = root
spring.datasource.password = root
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto = update
Change spring.datasource.username and spring.datasource.password as per your MySQL installation.

Note that, I’ve set spring.jpa.hibernate.ddl-auto property to update. This property updates the database schema whenever you create or modify the domain models in your application.

3. Create JPA Entity - Post.kt

Create a new package called model inside com.example.kotlindemo package, and then create a new Kotlin file called Post.kt with the following contents -
package com.example.kotlindemo.model

import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Id
import javax.validation.constraints.NotBlank

@Entity
data class Post (
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long = 0,

    @get: NotBlank
    val title: String = "",

    @get: NotBlank
    val content: String = ""
)

4. Create JPA Repository - PostRepository.kt

Let’s now create the repository for accessing the data from the database. First, create a package called repository inside com.example.kotlindemo package, and then create a Kotlin file named PostRepository.kt with the following contents -

package com.example.kotlindemo.repository

import com.example.kotlindemo.model.Post
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository

@Repository
interface PostRepository : JpaRepository<Post, Long>

5. Create Spring MVC Controller - PostController.kt

Finally, Let’s create the controller end-points for all the CRUD operations on the Post entity.

First, create a new package called controller inside com.example.kotlindemo package and then create a new kotlin file called PostController.kt inside controller package with the following contents -

package com.example.kotlindemo.controller

import com.example.kotlindemo.model.Post
import com.example.kotlindemo.repository.PostRepository
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import java.util.*
import javax.validation.Valid

@RestController
@RequestMapping("/api")
class PostController(private val postRepository: PostRepository) {

    @GetMapping("/posts")
    fun getAllPosts(): List<Post> =
            postRepository.findAll()


    @PostMapping("/posts")
    fun createNewPost(@Valid @RequestBody post: Post): Post =
            postRepository.save(post)


    @GetMapping("/posts/{id}")
    fun getPostById(@PathVariable(value = "id") postId: Long): ResponseEntity<Post> {
        return postRepository.findById(postId).map { post ->
            ResponseEntity.ok(post)
        }.orElse(ResponseEntity.notFound().build())
    }

    @PutMapping("/posts/{id}")
    fun updatePostById(@PathVariable(value = "id") postId: Long,
                          @Valid @RequestBody newPost: Post): ResponseEntity<Post> {

        return postRepository.findById(postId).map { existingPost ->
            val updatedPost: Post = existingPost
                    .copy(title = newPost.title, content = newPost.content)

            ResponseEntity.ok().body(postRepository.save(updatedPost))
        }.orElse(ResponseEntity.notFound().build())

    }

    @DeleteMapping("/posts/{id}")
    fun deletePostById(@PathVariable(value = "id") postId: Long): ResponseEntity<Void> {

        return postRepository.findById(postId).map { post  ->
            postRepository.delete(post)
            ResponseEntity<Void>(HttpStatus.OK)
        }.orElse(ResponseEntity.notFound().build())

    }
}
The controller defines APIs for all the CRUD operations. I have used Kotlin’s functional style syntax in all the methods to make them short and concise.

6. Running the Application

You can run the application by typing the following command in the terminal -

mvn spring-boot:run
The application will start at Spring Boot’s default port 8080.

7. Testing the Rest APIs

  1. POST /api/posts - Create an Post

curl -i -H "Content-Type: application/json" -X POST \
-d '{"title": "How to learn Kotlin", "content": "Resources to learn Kotlin"}' \
http://localhost:8080/api/posts

# Output
HTTP/1.1 200 
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
{"id":1,"title":"How to learn Kotlin","content":"Resources to learn Kotlin"}

  1. GET /api/posts - Get all Posts

curl -i -H 'Accept: application/json' http://localhost:8080/api/posts

# Output
HTTP/1.1 200 
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked

[{"id":1,"title":"How to learn Kotlin","content":"Resources to learn Kotlin"}]

  1. Get /api/posts/{id} - Get an Post by id

curl -i -H 'Accept: application/json' http://localhost:8080/api/posts/1

# Output
HTTP/1.1 200 
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked

{"id":1,"title":"How to learn Kotlin","content":"Resources to learn Kotlin"}

  1. PUT /api/posts/{id} - Update an Post

curl -i -H "Content-Type: application/json" -X PUT \
-d '{"id":1,"title":"How to learn Kotlin","content":"Resources to learn Kotlin"}' \
http://localhost:8080/api/posts/1

# Output
HTTP/1.1 200 
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked

{"id":1,"title":"How to learn Kotlin","content":"Resources to learn Kotlin"}

  1. DELETE /api/posts/{id} - Delete an Post

curl -i -X DELETE http://localhost:8080/api/posts/1

# Output
HTTP/1.1 200 
Content-Length: 0
The source code of this tutorial is hosted on the GitHub repository at https://github.com/sourcecodeexamples/springboot-kotlin-crud-example

Comments