Compare commits

..

No commits in common. "0b8d94c670fa0fe3630ad3edbdab314c05e26348" and "5cf200dd0f98fd7a7604d00b31f065e2cf04d40f" have entirely different histories.

6 changed files with 34 additions and 24 deletions

View file

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

View file

@ -21,6 +21,13 @@ 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,8 +94,6 @@ 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
@ -104,6 +102,7 @@ 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)
} }
@ -116,8 +115,6 @@ 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
@ -128,4 +125,4 @@ internal class JpaCityServiceTest {
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)
} }
} }

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>Spring Boot Kotlin and JPA Demo</name> <name></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.9.RELEASE</version> <version>1.5.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository --> <relativePath/> <!-- lookup parent from repository -->
</parent> </parent>
@ -23,11 +23,9 @@
<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.2.10</kotlin.version> <kotlin.version>1.1.2-2</kotlin.version>
<mockito.version>2.13.0</mockito.version> <mockito.version>2.8.9</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>
@ -91,7 +89,7 @@
<dependency> <dependency>
<groupId>com.nhaarman</groupId> <groupId>com.nhaarman</groupId>
<artifactId>mockito-kotlin</artifactId> <artifactId>mockito-kotlin</artifactId>
<version>${mockito-kotlin.version}</version> <version>1.4.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
@ -107,7 +105,6 @@
<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>
@ -133,11 +130,6 @@
<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,5 +1,8 @@
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
@ -15,6 +18,13 @@ 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>) {