Skip to content

Commit 86727ed

Browse files
committed
migrate to Kotlin
1 parent 7f1113a commit 86727ed

42 files changed

Lines changed: 853 additions & 1053 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build.yaml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ jobs:
55
name: Build
66
runs-on: ubuntu-latest
77
steps:
8-
- uses: actions/checkout@v3
8+
- uses: actions/checkout@v4
99

10-
- uses: actions/setup-java@v3
10+
- uses: actions/setup-java@v4
1111
with:
1212
distribution: "corretto"
1313
java-version: "21"
1414
cache: "gradle"
1515

16+
- name: Validate styles
17+
uses: pre-commit/action@v3.0.0
18+
1619
- name: Build project
1720
run: ./gradlew clean build

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66

77
## Аннотация
88

9+
Наверняка вы много раз сталкивались с тем, что при работе Hibernate вам приходилось писать много кода по перекладыванию
10+
из `@Entity` в DTO и обратно. Это громоздкий некрасивый boilerplate код, к тому же подверженный ошибкам. И вот, казалось
11+
бы появился спаситель – MapStruct! С помощью codegen он забирает на себя всю рутинную работу по перекладке, а вы лишь
12+
вызываете готовый метод. Но так ли все просто и радужно? В докладе поговорим про сложные случаи, когда нам надо
13+
создавать и обновлять сущности, имеющие связи на другие объекты.
14+
915
## План
1016

1117
1. Что за настройка `spring.jpa.open-in-view=false` и почему появилась проблема?

_config.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
title: JPA example
2+
description: JPA and MapStruct usage example
3+
author:
4+
name: Romanow Alexey
5+
email: romanowalex@mail.ru
6+
7+
show_downloads: false
8+
remote_theme: jekyll/minima
9+
header_pages: ['']
10+
11+
minima:
12+
skin: classic
13+
social_links:
14+
- { platform: linkedin, user_url: "https://www.linkedin.com/company/it-enduro" }
15+
- { platform: telegram, user_url: "https://t.me/romanowalex" }
16+
- { platform: youtube, user_url: "https://www.youtube.com/@it_enduro" }

build.gradle

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,34 @@
11
plugins {
2-
id "java"
32
id "idea"
3+
id "org.jetbrains.kotlin.jvm" version "1.9.25"
4+
id "org.jetbrains.kotlin.plugin.jpa" version "1.9.25"
5+
id "org.jetbrains.kotlin.plugin.spring" version "1.9.25"
6+
id "org.jetbrains.kotlin.kapt" version "1.9.25"
7+
id "org.jlleitschuh.gradle.ktlint" version "12.1.2"
48
id "org.springframework.boot" version "3.5.7"
59
id "com.gorylenko.gradle-git-properties" version "2.4.2"
610
id "com.adarshr.test-logger" version "4.0.0"
711
id "io.spring.dependency-management" version "1.1.7"
812
}
913

14+
ext {
15+
springBootVersion = "3.5.7"
16+
mapstructVersion = "1.6.3"
17+
jetbrainsAnnotationsVersion = "22.0.0"
18+
postgresContainerVersion = "1.21.3"
19+
}
20+
1021
idea {
1122
module {
1223
downloadJavadoc = true
1324
downloadSources = true
1425
}
1526
}
1627

17-
ext {
18-
springBootVersion = "3.5.7"
19-
mapstructVersion = "1.6.3"
20-
jetbrainsAnnotationsVersion = "22.0.0"
21-
postgresContainerVersion = "1.21.3"
28+
[compileKotlin, compileTestKotlin]*.kotlinOptions*.jvmTarget = "21"
29+
30+
ktlint {
31+
version.set("1.1.1")
2232
}
2333

2434
repositories {
@@ -40,13 +50,12 @@ dependencies {
4050
implementation "org.postgresql:postgresql"
4151
implementation "org.flywaydb:flyway-database-postgresql"
4252

43-
implementation "org.jetbrains:annotations:$jetbrainsAnnotationsVersion"
44-
implementation "org.mapstruct:mapstruct:$mapstructVersion"
4553
implementation "org.apache.commons:commons-lang3"
46-
47-
compileOnly "org.projectlombok:lombok"
48-
annotationProcessor "org.projectlombok:lombok"
49-
annotationProcessor "org.mapstruct:mapstruct-processor:$mapstructVersion"
54+
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
55+
implementation "org.jetbrains.kotlin:kotlin-reflect"
56+
implementation "com.fasterxml.jackson.module:jackson-module-kotlin"
57+
implementation "org.mapstruct:mapstruct:$mapstructVersion"
58+
kapt "org.mapstruct:mapstruct-processor:$mapstructVersion"
5059

5160
testImplementation "org.springframework.boot:spring-boot-starter-test"
5261
testImplementation "org.springframework.boot:spring-boot-testcontainers"
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
package ru.romanow.jpa;
1+
package ru.romanow.jpa
22

3-
import org.springframework.boot.SpringApplication;
4-
import org.springframework.boot.autoconfigure.SpringBootApplication;
3+
import org.springframework.boot.autoconfigure.SpringBootApplication
4+
import org.springframework.boot.runApplication
55

66
@SpringBootApplication
7-
public class JpaExampleApplication {
8-
public static void main(String[] args) {
9-
SpringApplication.run(JpaExampleApplication.class, args);
10-
}
7+
class JpaExampleApplication
8+
9+
fun main(args: Array<String>) {
10+
runApplication<JpaExampleApplication>(*args)
1111
}
Lines changed: 29 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,49 @@
1-
package ru.romanow.jpa.domain;
1+
package ru.romanow.jpa.domain
22

3-
import lombok.Data;
4-
import lombok.experimental.Accessors;
5-
import org.apache.commons.lang3.builder.ToStringBuilder;
3+
import jakarta.persistence.*
64

7-
import jakarta.persistence.*;
8-
import java.util.List;
9-
import java.util.Objects;
10-
import java.util.StringJoiner;
11-
12-
@Data
13-
@Accessors(chain = true)
145
@Entity
156
@Table(name = "address")
16-
public class Address {
17-
7+
data class Address(
188
@Id
199
@GeneratedValue(strategy = GenerationType.IDENTITY)
20-
private Integer id;
10+
val id: Int? = null,
2111

2212
@Column(name = "city", nullable = false)
23-
private String city;
13+
var city: String? = null,
2414

2515
@Column(name = "country", nullable = false)
26-
private String country;
16+
var country: String? = null,
2717

2818
@Column(name = "street")
29-
private String street;
19+
var street: String? = null,
3020

3121
@Column(name = "address", nullable = false)
32-
private String address;
33-
34-
@Override
35-
public boolean equals(Object o) {
36-
if (this == o) return true;
37-
if (o == null || getClass() != o.getClass()) return false;
38-
Address other = (Address) o;
39-
return Objects.equals(city, other.city) && Objects.equals(country, other.country) && Objects.equals(street, other.street) && Objects.equals(address, other.address);
22+
var address: String? = null,
23+
) {
24+
override fun equals(other: Any?): Boolean {
25+
if (this === other) return true
26+
if (other !is Address) return false
27+
28+
if (id != other.id) return false
29+
if (city != other.city) return false
30+
if (country != other.country) return false
31+
if (street != other.street) return false
32+
if (address != other.address) return false
33+
34+
return true
4035
}
4136

42-
@Override
43-
public int hashCode() {
44-
return Objects.hash(city, country, street, address);
37+
override fun hashCode(): Int {
38+
var result = id ?: 0
39+
result = 31 * result + (city?.hashCode() ?: 0)
40+
result = 31 * result + (country?.hashCode() ?: 0)
41+
result = 31 * result + (street?.hashCode() ?: 0)
42+
result = 31 * result + (address?.hashCode() ?: 0)
43+
return result
4544
}
4645

47-
@Override
48-
public String toString() {
49-
return new ToStringBuilder(this)
50-
.append("id", id)
51-
.append("city", city)
52-
.append("country", country)
53-
.append("street", street)
54-
.append("address", address)
55-
.toString();
46+
override fun toString(): String {
47+
return "Address(id=$id, city=$city, country=$country, street=$street, address=$address)"
5648
}
5749
}
Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,42 @@
1-
package ru.romanow.jpa.domain;
1+
package ru.romanow.jpa.domain
22

3-
import lombok.Data;
4-
import lombok.experimental.Accessors;
5-
import org.apache.commons.lang3.builder.ToStringBuilder;
3+
import jakarta.persistence.*
64

7-
import jakarta.persistence.*;
8-
import java.util.Objects;
9-
10-
@Data
11-
@Accessors(chain = true)
125
@Entity
136
@Table(name = "authority")
14-
public class Authority {
15-
7+
data class Authority(
168
@Id
179
@GeneratedValue(strategy = GenerationType.IDENTITY)
18-
private Integer id;
10+
val id: Int? = null,
1911

2012
@Column(name = "name", length = 80, nullable = false)
21-
private String name;
13+
var name: String? = null,
2214

2315
@Column(name = "priority", nullable = false)
24-
private Integer priority;
16+
var priority: Int? = null,
2517

2618
@ManyToOne(fetch = FetchType.LAZY)
27-
private Person person;
28-
29-
@Override
30-
public boolean equals(Object o) {
31-
if (this == o) return true;
32-
if (o == null || getClass() != o.getClass()) return false;
33-
Authority grant = (Authority) o;
34-
return Objects.equals(id, grant.id) && Objects.equals(name, grant.name) && Objects.equals(priority, grant.priority);
19+
val person: Person? = null,
20+
) {
21+
override fun equals(other: Any?): Boolean {
22+
if (this === other) return true
23+
if (other !is Authority) return false
24+
25+
if (id != other.id) return false
26+
if (name != other.name) return false
27+
if (priority != other.priority) return false
28+
29+
return true
3530
}
3631

37-
@Override
38-
public int hashCode() {
39-
return Objects.hash(id, name, priority);
32+
override fun hashCode(): Int {
33+
var result = id ?: 0
34+
result = 31 * result + (name?.hashCode() ?: 0)
35+
result = 31 * result + (priority ?: 0)
36+
return result
4037
}
4138

42-
@Override
43-
public String toString() {
44-
return new ToStringBuilder(this)
45-
.append("id", id)
46-
.append("name", name)
47-
.append("priority", priority)
48-
.toString();
39+
override fun toString(): String {
40+
return "Authority(id=$id, name=$name, priority=$priority)"
4941
}
5042
}

0 commit comments

Comments
 (0)