Compare commits

..

10 commits

Author SHA1 Message Date
Reinhard Prechtl
0b8d94c670
Merge pull request #4 from rillig/fix-date-comparison-in-tests
Fix date comparison in JpaCityServiceTest
2017-12-30 23:21:21 +01:00
Reinhard Prechtl
6baabd4d3b Update README 2017-12-29 17:15:36 +01:00
Reinhard Prechtl
0778caba02 Update Spring Boot Version 2017-12-29 16:50:04 +01:00
Reinhard Prechtl
bfb4309c50 Update Kotlin version and Jackson version 2017-12-29 16:10:12 +01:00
Reinhard Prechtl
44d06e2a58 Updated Mockito, Mockito-Kotlin and AssertJ dependency versions 2017-12-29 11:44:47 +01:00
Reinhard Prechtl
7ccc36c412
Merge pull request #1 from sdeleuze/master
Refactor to idiomatic Spring + Kotlin code
2017-12-28 23:38:41 +01:00
Reinhard Prechtl
3bf872c278
Merge pull request #2 from rillig/patch-1
Cross-reference the blog article
2017-12-28 23:35:08 +01:00
Roland Illig
9c715ce075 Fix test for updatedAt property
Both `save` and `updateCity` calls can happen at the same millisecond,
therefore the `updatedAt` was not necessarily increased.

The `Thread.sleep` method doesn't mention any guarantees of increasing
the system time mentioned by `LocalDateTime` used in `CityEntity`, but
the tests didn't fail again with this change, even when run repeatedly.
2017-11-12 15:17:24 +01:00
Roland Illig
0aa6090ac9
Cross-reference the blog article 2017-11-12 08:16:25 +01:00
Sebastien Deleuze
5bbb84dce6 Refactor to idiomatic Spring + Kotlin code
- Usage of Kotlin JPA compiler plugin to generate default constructors
 - Jackson builder already register Kotlin module with sensible defaults
 - One liner syntax + type inference when possible
2017-06-16 22:36:18 +02:00
6 changed files with 24 additions and 34 deletions

View file

@ -1,3 +1,5 @@
# spring-kotlin-jpa # spring-kotlin-jpa
This repository contains sample code using Spring Boot and Kotlin to work with JPA. This repository contains sample code using Spring Boot and Kotlin to work with JPA.
For further information, please refer to this [article](https://blog.codecentric.de/en/2017/06/kotlin-spring-working-jpa-data-classes/) on the codecentric blog.

View file

@ -5,15 +5,9 @@ import javax.persistence.AttributeConverter
class DoubleAttributeConverter : AttributeConverter<Double, BigDecimal?> { class DoubleAttributeConverter : AttributeConverter<Double, BigDecimal?> {
override fun convertToDatabaseColumn(attribute: Double?): BigDecimal? { override fun convertToDatabaseColumn(attribute: Double?) =
return if (attribute != null) { if (attribute != null) { BigDecimal(attribute) } else { null }
BigDecimal(attribute)
} else {
null
}
}
override fun convertToEntityAttribute(dbData: BigDecimal?): Double? { override fun convertToEntityAttribute(dbData: BigDecimal?) =
return dbData?.toDouble() dbData?.toDouble()
}
} }

View file

@ -21,13 +21,6 @@ internal data class CityEntity(
val updatedAt: LocalDateTime = LocalDateTime.now(), val updatedAt: LocalDateTime = LocalDateTime.now(),
val createdAt: LocalDateTime = LocalDateTime.now()) { val createdAt: LocalDateTime = LocalDateTime.now()) {
// Default constructor for JPA
@Suppress("unused")
private constructor() : this(
name = "",
location = Coordinate.origin(),
updatedAt = LocalDateTime.MIN)
fun toDto(): CityDto = CityDto( fun toDto(): CityDto = CityDto(
id = this.id!!, id = this.id!!,
name = this.name, name = this.name,

View file

@ -94,6 +94,8 @@ internal class JpaCityServiceTest {
fun `'updateCity' should update existing values`() { fun `'updateCity' should update existing values`() {
val existingCity = repository.save(CityEntity("city", "cityname", "description", Coordinate(1.0, -1.0))).toDto() val existingCity = repository.save(CityEntity("city", "cityname", "description", Coordinate(1.0, -1.0))).toDto()
Thread.sleep(1)
val result = service.updateCity(existingCity.id, UpdateCityDto("new name", "new description", CoordinateDto(-1.0, -1.0))) val result = service.updateCity(existingCity.id, UpdateCityDto("new name", "new description", CoordinateDto(-1.0, -1.0)))
softly.assertThat(result).isNotNull softly.assertThat(result).isNotNull
@ -102,7 +104,6 @@ internal class JpaCityServiceTest {
softly.assertThat(result?.description).isEqualTo("new description") softly.assertThat(result?.description).isEqualTo("new description")
softly.assertThat(result?.location).isEqualTo(CoordinateDto(-1.0, -1.0)) softly.assertThat(result?.location).isEqualTo(CoordinateDto(-1.0, -1.0))
softly.assertThat(result?.updatedAt).isAfter(existingCity.updatedAt) softly.assertThat(result?.updatedAt).isAfter(existingCity.updatedAt)
softly.assertThat(result?.updatedAt).isAfter(existingCity.updatedAt)
softly.assertThat(result?.createdAt).isEqualTo(existingCity.createdAt) softly.assertThat(result?.createdAt).isEqualTo(existingCity.createdAt)
} }
@ -115,6 +116,8 @@ internal class JpaCityServiceTest {
location = Coordinate(1.0, -1.0), location = Coordinate(1.0, -1.0),
updatedAt = LocalDateTime.now().minusYears(1))).toDto() updatedAt = LocalDateTime.now().minusYears(1))).toDto()
Thread.sleep(1)
val result = service.updateCity(existingCity.id, UpdateCityDto(null, null, null)) val result = service.updateCity(existingCity.id, UpdateCityDto(null, null, null))
softly.assertThat(result).isNotNull softly.assertThat(result).isNotNull

18
pom.xml
View file

@ -8,13 +8,13 @@
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name></name> <name>Spring Boot Kotlin and JPA Demo</name>
<description>Demo project for Spring Boot</description> <description>Demo project for Spring Boot</description>
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version> <version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository --> <relativePath/> <!-- lookup parent from repository -->
</parent> </parent>
@ -23,9 +23,11 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<kotlin.version>1.1.2-2</kotlin.version> <kotlin.version>1.2.10</kotlin.version>
<mockito.version>2.8.9</mockito.version> <mockito.version>2.13.0</mockito.version>
<assertj.version>3.8.0</assertj.version> <assertj.version>3.8.0</assertj.version>
<mockito-kotlin.version>1.5.0</mockito-kotlin.version>
<jackson.version>2.9.3</jackson.version>
</properties> </properties>
<modules> <modules>
@ -89,7 +91,7 @@
<dependency> <dependency>
<groupId>com.nhaarman</groupId> <groupId>com.nhaarman</groupId>
<artifactId>mockito-kotlin</artifactId> <artifactId>mockito-kotlin</artifactId>
<version>1.4.0</version> <version>${mockito-kotlin.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
@ -105,6 +107,7 @@
<configuration> <configuration>
<compilerPlugins> <compilerPlugins>
<plugin>spring</plugin> <plugin>spring</plugin>
<plugin>jpa</plugin>
</compilerPlugins> </compilerPlugins>
<jvmTarget>1.8</jvmTarget> <jvmTarget>1.8</jvmTarget>
</configuration> </configuration>
@ -130,6 +133,11 @@
<artifactId>kotlin-maven-allopen</artifactId> <artifactId>kotlin-maven-allopen</artifactId>
<version>${kotlin.version}</version> <version>${kotlin.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-noarg</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies> </dependencies>
</plugin> </plugin>
</plugins> </plugins>

View file

@ -1,8 +1,5 @@
package de.rpr.mycity package de.rpr.mycity
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.KotlinModule
import org.slf4j.Logger import org.slf4j.Logger
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import org.springframework.beans.factory.InjectionPoint import org.springframework.beans.factory.InjectionPoint
@ -18,13 +15,6 @@ class Application {
@Scope("prototype") @Scope("prototype")
fun logger(injectionPoint: InjectionPoint): Logger = LoggerFactory.getLogger(injectionPoint.methodParameter.containingClass) fun logger(injectionPoint: InjectionPoint): Logger = LoggerFactory.getLogger(injectionPoint.methodParameter.containingClass)
@Bean
fun objectMapper(): ObjectMapper {
val mapper = ObjectMapper().registerModule(KotlinModule())
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
return mapper
}
} }
fun main(args: Array<String>) { fun main(args: Array<String>) {