{"id":305007,"date":"2020-06-08T15:00:30","date_gmt":"2020-06-08T15:00:30","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=305007"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=305007","title":{"rendered":"Spring Boot, Hibernate \u0438 Kotlin \u0434\u043b\u044f \u043d\u043e\u0432\u0438\u0447\u043a\u043e\u0432 \u0448\u0430\u0433 \u0437\u0430 \u0448\u0430\u0433\u043e\u043c"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/company\/domclick\/blog\/505860\/\">\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/4c\/4m\/k7\/4c4mk7pj7ozce-14ymchq4bsa4s.jpeg\" width=\"500\"><\/div>\n<p>  \u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u043c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041e\u043b\u0435\u0433, \u044f \u0442\u0435\u0445\u043b\u0438\u0434 \u0432 \u0414\u043e\u043c\u041a\u043b\u0438\u043a\u0435. \u0412 \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 \u044f\u0434\u0440\u043e\u043c \u0441\u0442\u0435\u043a\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f Kotlin \u0438 Spring Boot. \u0425\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0432\u0430\u043c\u0438 \u0441\u0432\u043e\u0438\u043c \u043e\u043f\u044b\u0442\u043e\u043c \u043f\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044e \u0438 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044f\u0445 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 PostgreSQL \u0438 Hibernate \u0432 \u0441\u0432\u044f\u0437\u043a\u0435 \u0441\u043e Spring Boot \u0438 Kotlin. \u0422\u0430\u043a\u0436\u0435 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u0430, \u043f\u043e\u043a\u0430\u0436\u0443 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 Kotlin \u0438 \u0435\u0433\u043e \u043e\u0442\u043b\u0438\u0447\u0438\u044f \u043e\u0442 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 Java. \u0420\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u0445 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u0445, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043c\u043e\u0433\u0443\u0442 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u0442\u044c\u0441\u044f \u043d\u043e\u0432\u0438\u0447\u043a\u0438 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u0441\u0442\u0435\u043a\u0430 \u0441 Hibernate. \u0421\u0442\u0430\u0442\u044c\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c, \u0436\u0435\u043b\u0430\u044e\u0449\u0438\u043c \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0430 Kotlin \u0438 \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0445 \u0441\u043e Spring Boot, Hibernate Java.<br \/>  <a name=\"habracut\"><\/a>  <\/p>\n<h2>\u041f\u043b\u0430\u0433\u0438\u043d\u044b<\/h2>\n<p>  \u0414\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 Kotlin \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432\u043e\u0437\u044c\u043c\u0451\u043c Gradle Kotlin DSL. \u0421\u043f\u0438\u0441\u043e\u043a \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0445 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c \u0434\u043b\u044f Spring Boot, \u0430 \u0434\u043b\u044f Kotlin \u0441 Hibernate \u0443 \u043d\u0430\u0441 \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u043e\u0432\u044b\u0445: <\/p>\n<pre><code class=\"kotlin\">plugins {     id(&quot;org.springframework.boot&quot;) version &quot;2.2.7.RELEASE&quot;     id(&quot;io.spring.dependency-management&quot;) version &quot;1.0.9.RELEASE&quot;     kotlin(&quot;jvm&quot;) version &quot;1.3.72&quot;     kotlin(&quot;plugin.spring&quot;) version &quot;1.3.72&quot;     kotlin(&quot;plugin.jpa&quot;) version &quot;1.3.72&quot; } <\/code><\/pre>\n<p>  \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0442\u0440\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445.<\/p>\n<p>  <code>kotlin(\u00abjvm\u00bb)<\/code> \u2014 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043f\u043b\u0430\u0433\u0438\u043d Kotlin \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430 JVM. \u0411\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0435 \u0437\u0430\u0432\u0435\u0434\u0435\u0442\u0441\u044f \u043d\u0438 \u043e\u0434\u043d\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 Java-\u0441\u0442\u0435\u043a\u0435.<\/p>\n<p>  <code>kotlin(\u00abplugin.spring\u00bb)<\/code> \u2014 \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043a\u043b\u0430\u0441\u0441\u044b \u0432 Kotlin \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b, \u0442\u043e \u044d\u0442\u043e\u0442 \u043f\u043b\u0430\u0433\u0438\u043d \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u0434\u0435\u043b\u0430\u0435\u0442 \u043a\u043b\u0430\u0441\u0441\u044b, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f\u043c\u0438 <a href=\"http:\/\/docs.spring.io\/spring-framework\/docs\/current\/javadoc-api\/org\/springframework\/stereotype\/Component.html\"><code>@Component<\/code><\/a>, <a href=\"http:\/\/docs.spring.io\/spring\/docs\/current\/javadoc-api\/org\/springframework\/scheduling\/annotation\/Async.html\"><code>@Async<\/code><\/a>, <a href=\"http:\/\/docs.spring.io\/spring-framework\/docs\/current\/javadoc-api\/org\/springframework\/transaction\/annotation\/Transactional.html\"><code>@Transactional<\/code><\/a>, <a href=\"http:\/\/docs.spring.io\/spring-framework\/docs\/current\/javadoc-api\/org\/springframework\/cache\/annotation\/Cacheable.html\"><code>@Cacheable<\/code><\/a> \u0438 <a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/current\/api\/org\/springframework\/boot\/test\/context\/SpringBootTest.html\"><code>@SpringBootTest<\/code><\/a> \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c\u0438 \u043a \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044e, \u0430 \u0432 \u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0435, \u043e\u0442\u043d\u043e\u0441\u044f\u0449\u0435\u0439\u0441\u044f \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435, \u044d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043a\u043b\u0430\u0441\u0441\u0430\u043c, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u043c \u043d\u0430 Kotlin \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0432 Spring \u0447\u0435\u0440\u0435\u0437 CGLib \u043f\u0440\u043e\u043a\u0441\u0438.<\/p>\n<p>  \u0412\u0430\u0436\u043d\u043e \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f\u043c\u0438 <code>@Entity<\/code>, <code>@MappedSuperclass<\/code> \u0438 <code>@Embaddable<\/code>, \u043d\u0435 \u0441\u0442\u0430\u043d\u0443\u0442 <code>open<\/code> \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043f\u043b\u0430\u0433\u0438\u043d\u0430. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, <code>get accessor<\/code>\u2019\u044b \u0442\u043e\u0436\u0435 \u0431\u0443\u0434\u0443\u0442 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u043c\u0438, \u0438 \u0442\u043e\u0433\u0434\u0430 <strong>\u043c\u044b \u043f\u043e\u0442\u0435\u0440\u044f\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c<\/strong> \u0441 <code>entity reference<\/code>. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e\u0433\u043e \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c <code>Entity<\/code> \u0438 \u0435\u0433\u043e \u043f\u043e\u043b\u044f <code>open<\/code>, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 build.gradle.kts:<\/p>\n<pre><code class=\"kotlin\">allOpen {    annotation(&quot;javax.persistence.Entity&quot;)    annotation(&quot;javax.persistence.MappedSuperclass&quot;)    annotation(&quot;javax.persistence.Embeddable&quot;) }<\/code><\/pre>\n<p>  <code>kotlin(\u00abplugin.jpa\u00bb)<\/code> \u2014 \u0415\u0441\u043b\u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0435 \u0434\u0432\u0430 \u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043a \u043b\u044e\u0431\u043e\u043c\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e \u043d\u0430 Kotlin + Spring Boot, \u0442\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439, \u0443\u0436\u0435 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u043a Hibernate. \u0410 \u043e\u043d, \u043a\u0430\u043a \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e, \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <code>Entity<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043a\u043b\u0430\u0441\u0441 \u0441 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u043c \u0431\u0435\u0437 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u041d\u043e \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u043f\u0438\u0448\u0435\u043c \u043d\u0430 Kotlin, \u0442\u0430\u043a\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430 \u043c\u043e\u0436\u0435\u0442 \u0438 \u043d\u0435 \u043d\u0430\u0439\u0442\u0438\u0441\u044c. \u0415\u0441\u043b\u0438 \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u0438 \u0441\u0432\u043e\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 (<i>primary constructor<\/i>), \u0442\u043e \u043f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 <code>Entity<\/code> \u0443 \u043d\u0430\u0441 \u0432\u044b\u043a\u0438\u043d\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435:<\/p>\n<pre><code class=\"plaintext\">org.hibernate.InstantiationException: No default constructor for entity <\/code><\/pre>\n<p>  <\/p>\n<h2>\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438<\/h2>\n<p>  \u041d\u0430\u0431\u043e\u0440 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0443 \u043d\u0430\u0441 \u0442\u043e\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440\u0443 \u043d\u0430 Java:<\/p>\n<pre><code class=\"kotlin\">dependencies {   implementation(&quot;org.springframework.boot:spring-boot-starter-web&quot;)   implementation(&quot;org.springframework.boot:spring-boot-starter-data-jpa&quot;)   implementation(&quot;com.fasterxml.jackson.module:jackson-module-kotlin&quot;)   implementation(&quot;org.jetbrains.kotlin:kotlin-reflect&quot;)   implementation(&quot;org.jetbrains.kotlin:kotlin-stdlib-jdk8&quot;)   implementation(&quot;org.liquibase:liquibase-core&quot;)    runtimeOnly(&quot;org.postgresql:postgresql&quot;)    testImplementation(&quot;org.springframework.boot:spring-boot-starter-test&quot;)   testImplementation(&quot;org.testcontainers:testcontainers:$testContainersVer&quot;)   testImplementation(&quot;org.testcontainers:postgresql:$testContainersVer&quot;) }<\/code><\/pre>\n<p>  \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0435\u0449\u0435 \u043f\u0430\u0440\u0443 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0432 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u043c\u0443 \u0432\u0435\u0431-\u0441\u0442\u0430\u0440\u0442\u0435\u0440\u0443 Spring Boot \u0438 \u043a \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0449\u0435\u043c\u0443 \u043d\u0430\u0441 \u0441\u0442\u0430\u0440\u0442\u0435\u0440\u0443 <code>org.springframework.boot:spring-boot-starter-data-jpa<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 JPA \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0442\u044f\u043d\u0435\u0442 Hibernate: <\/p>\n<p>  <code>org.jetbrains.kotlin:kotlin-reflect<\/code> \u2014 \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438 \u043d\u0430 Kotlin, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u0436\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 Spring Boot \u0438 \u0448\u0438\u0440\u043e\u043a\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432.<\/p>\n<p>  <code>org.jetbrains.kotlin:kotlin-stdlib-jdk8<\/code> \u2014 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f\u043c\u0438 Java, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0441\u0442\u0440\u0438\u043c\u043e\u0432 \u0438 \u043c\u043d\u043e\u0433\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435. <\/p>\n<p>  \u041d\u0430 \u044d\u0442\u043e\u043c \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u044f \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 Kotlin \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 Java \u0443 \u043d\u0430\u0441 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044e\u0442\u0441\u044f, \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0441\u0430\u043c\u043e\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443, \u0435\u0433\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0442\u0430\u0431\u043b\u0438\u0446 \u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439.<\/p>\n<h2>\u0422\u0430\u0431\u043b\u0438\u0446\u044b \u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438<\/h2>\n<p>  \u041d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0434\u0432\u0443\u0445 \u0442\u0430\u0431\u043b\u0438\u0446 department \u0438 employee, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435\u043c \u00ab\u043e\u0434\u0438\u043d \u043a\u043e \u043c\u043d\u043e\u0433\u0438\u043c\u00bb.<\/p>\n<p>  \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0442\u0430\u0431\u043b\u0438\u0446:<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/53d\/260\/2a9\/53d2602a91d6b89c3fddb16c27bc824a.png\"><\/div>\n<p>  \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0431\u0430\u0437\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0421\u0423\u0411\u0414 <i>PostgreSQL<\/i>. \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0442\u0430\u0431\u043b\u0438\u0446 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <i>liquibase<\/i>, \u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0441\u0442\u0430\u0440\u0442\u0435\u0440: <\/p>\n<p>  <code>org.springframework.boot:spring-boot-starter-test<\/code> \u2014 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0431\u0443\u0434\u0435\u043c \u0432 Docker \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <i>testcontainers.<\/i><\/p>\n<h4>\u0421\u0443\u0449\u043d\u043e\u0441\u0442\u0438<\/h4>\n<p>  \u041a\u0430\u043a \u0438 \u0432 \u043b\u044e\u0431\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0441 \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u043e\u0434\u043d\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c\u044e, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043e\u0431\u0449\u0435\u0433\u043e \u043f\u0440\u0435\u0434\u043a\u0430 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 <code>entity<\/code>.<\/p>\n<p>  <code>BaseEntity<\/code>:<\/p>\n<pre><code class=\"kotlin\">@MappedSuperclass abstract class BaseEntity&lt;T&gt; {     @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    var id: T? = null     override fun equals(other: Any?): Boolean {        other ?: return false         if (this === other) return true         if (javaClass != ProxyUtils.getUserClass(other)) return false         other as BaseEntity&lt;*&gt;         return this.id != null &amp;&amp; this.id == other.id    }     override fun hashCode() = 25     override fun toString(): String {        return &quot;${this.javaClass.simpleName}(id=$id)&quot;    } }<\/code><\/pre>\n<p>  <code>DepartmentEntity<\/code>:<\/p>\n<pre><code class=\"kotlin\">@Entity @Table(name = &quot;department&quot;) class DepartmentEntity(         val name: String,         @OneToMany(                mappedBy = &quot;department&quot;,                fetch = FetchType.LAZY,                orphanRemoval = true,                cascade = [CascadeType.ALL]        )        val employees: MutableList&lt;EmployeeEntity&gt; = mutableListOf() ) : BaseAuditEntity&lt;Long&gt;() {     fun addEmployee(block: DepartmentEntity.() -&gt; EmployeeEntity) {        employees.add(block())    }     fun setEmployees(block: DepartmentEntity.() -&gt; MutableSet&lt;EmployeeEntity&gt;) {        employees.clear()        employees.addAll(block())    } }<\/code><\/pre>\n<p>  <code>EmployeeEntity<\/code>:<\/p>\n<pre><code class=\"kotlin\">@Entity @Table(name = &quot;employee&quot;) class EmployeeEntity(         val firstName: String,         var lastName: String? = null,         @ManyToOne        @JoinColumn(name = &quot;department_id&quot;)        val department: DepartmentEntity ) : BaseAuditEntity&lt;Long&gt;()<\/code><\/pre>\n<p>  <strong>\u041c\u044b \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c Data-\u043a\u043b\u0430\u0441\u0441\u044b<\/strong>. \u042d\u0442\u043e \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u044f\u0432\u043d\u044b\u043c \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u043c Kotlin \u043f\u0435\u0440\u0435\u0434 Java (\u0434\u043e 14 \u0432\u0435\u0440\u0441\u0438\u0438), \u0438 \u044d\u0442\u043e\u043c\u0443 \u0435\u0441\u0442\u044c \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435.<\/p>\n<h4>\u041f\u043e\u0447\u0435\u043c\u0443 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c?<\/h4>\n<p>  Data-\u043a\u043b\u0430\u0441\u0441\u044b, \u043f\u043e\u043c\u0438\u043c\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043e\u043d\u0438 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b \u0441\u0430\u043c\u0438 \u043f\u043e \u0441\u0435\u0431\u0435, \u0438\u043c\u0435\u044e\u0442 \u043f\u043e \u0432\u0441\u0435\u043c \u043f\u043e\u043b\u044f\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 <code>equals<\/code>, <code>hashCode<\/code> \u0438 <code>toString<\/code>. \u0410 \u044d\u0442\u043e <strong>\u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e<\/strong> \u0432 \u0441\u0432\u044f\u0437\u043a\u0435 \u0441 Hibernate.<\/p>\n<p>  \u041f\u043e\u0447\u0435\u043c\u0443? \u0410 \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u0447\u0435\u043c <code>hashCode<\/code> \u0432\u0441\u0435\u0433\u0434\u0430 \u0440\u0430\u0432\u0435\u043d \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0435 \u2014 \u043e\u0442\u0432\u0435\u0442 \u0432 <a href=\"https:\/\/docs.jboss.org\/hibernate\/orm\/5.1\/userguide\/html_single\/chapters\/domain\/entity.html\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0441\u0430\u043c\u043e\u0433\u043e Hibernate<\/a>. \u041a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0432\u043e\u0442 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437\u0434\u0435\u043b: <\/p>\n<blockquote><p>Although using a natural-id is best for <strong>equals<\/strong> and <strong>hashCode<\/strong>, sometimes you only have the entity identifier that provides a unique constraint.<\/p>\n<p>  It\u2019s possible to use the entity identifier for equality check, but it needs a workaround:<\/p>\n<ul>\n<li>you need to provide a constant value for <strong>hashCode<\/strong> so that the hash code value does not change before and after the entity is flushed.<\/li>\n<li>you need to compare the entity identifier equality only for non-transient entities.<\/li>\n<\/ul>\n<\/blockquote>\n<p>  \u0422\u043e \u0435\u0441\u0442\u044c \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u043e \u043b\u0438\u0431\u043e \u043f\u043e <code>natural id<\/code>, \u043b\u0438\u0431\u043e, \u043a\u0430\u043a \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435, \u043f\u043e <code>primary key id<\/code>. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u043f\u0440\u0438 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0438 \u0443\u0431\u0435\u0440\u0435\u0436\u0435\u0442 \u043e\u0442 \u0435\u0435 \u043f\u043e\u0442\u0435\u0440\u0438 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432 <code>Set<\/code>. <\/p>\n<p>  \u041d\u0430\u043b\u0438\u0447\u0438\u0435 \u0436\u0435 <code>toString<\/code>, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u043e \u0432\u0441\u0435\u043c \u043f\u043e\u043b\u044f\u043c, \u0438 \u0432\u043e\u0432\u0441\u0435 \u0443\u0431\u0438\u0432\u0430\u0435\u0442 \u0432\u0441\u044e \u043b\u0435\u043d\u0438\u0432\u043e\u0441\u0442\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u0438 \u0436\u0443\u0440\u043d\u0430\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438, \u0442\u0430\u043a \u043a\u0430\u043a \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0432\u0441\u0435 \u043f\u043e\u043b\u044f \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u0432 \u0441\u0442\u0440\u043e\u043a\u0443.<\/p>\n<p>  \u0423\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 Hibernate, \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c Kotlin \u043d\u0430\u043c \u043d\u0435 \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u0442. <\/p>\n<h4>\u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u043a\u043b\u0430\u0441\u0441\u0430<\/h4>\n<p>  Kotlin \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440, \u0447\u0435\u043c \u0433\u0440\u0435\u0445 \u043d\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0435\u0449\u0435 \u0440\u0430\u0437 <code>DepartmentEntity<\/code>:<\/p>\n<pre><code class=\"kotlin\">class DepartmentEntity(         val name: String,         @OneToMany(                mappedBy = &quot;department&quot;,                fetch = FetchType.LAZY,                orphanRemoval = true,                cascade = [CascadeType.ALL]        )        val employees: MutableList&lt;EmployeeEntity&gt; = mutableListOf() ) : BaseAuditEntity&lt;Long&gt;() {<\/code><\/pre>\n<p>  \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0434\u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"kotlin\">departmentRepository.save(DepartmentEntity(name = &quot;Department One&quot;))<\/code><\/pre>\n<p>  \u0427\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u043c\u043e\u0436\u043d\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435, \u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u043a\u043e\u0432 employees. \u041a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438, \u0440\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u043e\u0431\u044a\u044f\u0432\u0438\u043c \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u043c\u0438. <\/p>\n<h4>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 var\/val \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044f<\/h4>\n<p>  \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u044b \u043f\u043e\u043c\u0435\u0442\u0438\u043b\u0438 \u043a\u0430\u043a <code>val<\/code>:<\/p>\n<pre><code class=\"kotlin\">class DepartmentEntity(         val name: String,<\/code><\/pre>\n<p>  \u0438 \u043e\u043d\u043e \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c <code>null<\/code>. <\/p>\n<p>  \u0412\u044b\u0431\u043e\u0440 <code>var<\/code>\/<code>val<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u043e\u043f\u0446\u0438\u0435\u0439 \u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438. \u0412\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u043c\u0435\u0436\u0434\u0443 <code>var<\/code> \u0438 <code>val<\/code> \u043d\u0430\u0434\u043e \u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f: \u0434\u043e\u043b\u0436\u043d\u043e \u043b\u0438 \u043f\u043e\u043b\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0431\u044b\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u043c.<\/p>\n<h4>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c null \u0432 \u043f\u043e\u043b\u044f\u0445 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u0411\u0414<\/h4>\n<p>  \u041d\u0430\u0441\u0447\u0435\u0442 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 <code>null<\/code> \u0432 \u043f\u043e\u043b\u044f\u0445 \u0432\u0441\u0451 \u043d\u0435 \u0442\u0430\u043a \u043f\u0440\u043e\u0441\u0442\u043e. \u0420\u0430\u043d\u0435\u0435 \u043c\u044b \u043f\u043e\u0433\u0440\u0443\u0437\u0438\u043b\u0438\u0441\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0432 \u0433\u043b\u0443\u0431\u0438\u043d\u044b Hibernate: \u0433\u043e\u0432\u043e\u0440\u044f \u043e plugin.jpa, \u044f \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u043b \u043f\u0440\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430 \u0431\u0435\u0437 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>  \u041f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u0435\u0439 \u0442\u043e\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f. \u0418 \u0435\u0441\u043b\u0438 \u0432 \u0431\u0430\u0437\u0435 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u043a\u043e\u043b\u043e\u043d\u043a\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u043e\u0441\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>null<\/code>, \u0442\u043e \u043a\u043b\u0430\u0441\u0441 \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 \u044d\u0442\u0438\u043c \u043f\u043e\u043b\u0435\u043c \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c <code>null<\/code>. \u041f\u0440\u0438 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0438 \u043a \u043d\u0435\u043c\u0443 \u043c\u044b \u0440\u0438\u0441\u043a\u0443\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c NPE, \u0445\u043e\u0442\u044f \u043f\u043e\u043b\u0435 \u0438 \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043e \u043a\u0430\u043a <code>not nullable<\/code>. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0441\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c, \u043d\u0430\u0434\u043e \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0442\u0430\u0431\u043b\u0438\u0446 \u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0435 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u0434\u0432\u0443\u0445 \u0440\u0430\u0437\u0434\u0435\u043b\u0430\u0445 \u0431\u043e\u043b\u0435\u0435 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0441\u043d\u043e, \u0442\u043e \u044d\u0442\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c\u044b \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u0430\u043c, \u043d\u043e \u0438 \u043a \u0441\u0432\u044f\u0437\u043a\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439. <\/p>\n<p>  \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>EmployeeEntity<\/code> \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d \u043a <code>DepartmentEntity<\/code>:<\/p>\n<pre><code class=\"kotlin\">class EmployeeEntity(         val firstName: String,         var lastName: String? = null,         @ManyToOne        @JoinColumn(name = &quot;department_id&quot;)        val department: DepartmentEntity ) : BaseAuditEntity&lt;Long&gt;()<\/code><\/pre>\n<p>  <code>Department<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435 <code>null<\/code> \u0438 \u0435\u0433\u043e \u043d\u0435\u043b\u044c\u0437\u044f \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0438\u0437\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0442 \u0440\u0430\u0437\u043d\u043e\u0433\u043e \u0440\u043e\u0434\u0430 \u043e\u0448\u0438\u0431\u043e\u043a, \u0432 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438, \u0435\u0441\u043b\u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0441\u0442\u0438. <\/p>\n<h4>\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/h4>\n<p>  \u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 Kotlin, \u0443 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0435\u0432 \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c <code>null<\/code>. \u0422\u0430\u043a, \u0435\u0441\u043b\u0438 \u043c\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u043f\u0440\u0438 \u043f\u043e\u0438\u0441\u043a\u0435 <code>department<\/code> \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0431\u0443\u0434\u0435\u0442 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0438 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0442\u0438\u043f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u0430\u043a <code>non nullable<\/code>:<\/p>\n<pre><code class=\"kotlin\">interface DepartmentRepository : JpaRepository&lt;DepartmentEntity, Long&gt; {     fun findOneByName(name: String) : DepartmentEntity }<\/code><\/pre>\n<p>  \u0417\u0434\u0435\u0441\u044c <code>DepartmentEntity<\/code> \u0443\u043a\u0430\u0437\u0430\u043d \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u0438 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c <code>null<\/code>. \u0415\u0441\u043b\u0438 \u0436\u0435 \u043f\u043e \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u043c\u044b \u043d\u0435 \u043d\u0430\u0448\u043b\u0438 \u0438\u0441\u043a\u043e\u043c\u044b\u0439 <code>department<\/code>, \u0442\u043e \u043f\u043e\u0439\u043c\u0430\u0435\u043c \u0443\u0436\u0435 \u043d\u0435 NPE, \u0430 \u043d\u0435\u0447\u0442\u043e \u0434\u0440\u0443\u0433\u043e\u0435:<\/p>\n<pre><code class=\"plaintext\">org.springframework.dao.EmptyResultDataAccessException: Result must not be null! <\/code><\/pre>\n<p>  \u0422\u0430\u043a\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u043e\u0441\u0442\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 Kotlin \u0432 <code>MethodInvocationValidator<\/code> \u0438 <code>ReflectionUtils<\/code> \u0432 spring data commons. <\/p>\n<h4>lateinit var<\/h4>\n<p>  \u0415\u0449\u0451 \u043e\u0434\u043d\u043e\u0439 \u0444\u0438\u0447\u0435\u0439 Kotlin, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>lateinit var<\/code>.<\/p>\n<p>  \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441-\u043f\u0440\u0435\u0434\u043e\u043a: <code>BaseAuditEntity<\/code>.<\/p>\n<pre><code class=\"kotlin\">@MappedSuperclass @EntityListeners(AuditingEntityListener::class) abstract class BaseAuditEntity&lt;T&gt; : BaseEntity&lt;T&gt;() {     @CreatedDate    @Column(updatable = false, nullable = false)    lateinit var created: LocalDateTime     @LastModifiedDate    @Column(nullable = false)    lateinit var modified: LocalDateTime }<\/code><\/pre>\n<p>  \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 <code>lateinit var<\/code> \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u043e\u043b\u0435\u0439 \u0430\u0443\u0434\u0438\u0442\u0430 (<code>created<\/code>, <code>modified<\/code>). <\/p>\n<p>  <code>lateinit var<\/code> \u2014 \u044d\u0442\u043e <code>not null<\/code> \u043f\u043e\u043b\u0435 \u0441 \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0439 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439. \u041e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043a \u043f\u043e\u043b\u044e \u0434\u043e \u0435\u0433\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443:<\/p>\n<pre><code class=\"plaintext\">kotlin.UninitializedPropertyAccessException: lateinit property has not been initialized <\/code><\/pre>\n<p>  \u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043c\u044b \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a \u043f\u043e\u043b\u044f\u043c <code>created<\/code> \u0438 <code>modified<\/code> \u0443\u0436\u0435 \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0431\u044b\u043b\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0430 \u0432 \u0411\u0414. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u044d\u0442\u0438\u0445 \u043f\u043e\u043b\u044f\u0445\u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u043e\u043d\u0438 <code>not null<\/code>, \u0442\u043e <code>lateinit var<\/code> \u043d\u0430\u043c \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442. <\/p>\n<h2>\u0418\u0442\u043e\u0433\u0438<\/h2>\n<p>  \u041c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0443\u0447\u0442\u0435\u043d\u044b \u043c\u043d\u043e\u0433\u0438\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 Kotlin, \u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u0432\u0430\u0436\u043d\u044b\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u044f \u043e\u0442 Java, \u0438\u0437\u0431\u0435\u0436\u0430\u0432 \u043c\u043d\u043e\u0433\u0438\u0445 \u0441\u043a\u0440\u044b\u0442\u044b\u0445 \u0441\u044e\u0440\u043f\u0440\u0438\u0437\u043e\u0432. \u0411\u0443\u0434\u0443 \u0440\u0430\u0434, \u0435\u0441\u043b\u0438 \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u043e\u0432\u0438\u0447\u043a\u0430\u043c. \u041f\u043e\u0437\u0434\u043d\u0435\u0435 \u043c\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u0442\u0435\u043c\u0443 \u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0441 \u0411\u0414.<\/p>\n<p>  <a href=\"https:\/\/github.com\/Klimenkoob\/spring-kotlin-hibernate\">\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435<\/a>.<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/domclick\/blog\/505860\/\"> https:\/\/habr.com\/ru\/company\/domclick\/blog\/505860\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/company\/domclick\/blog\/505860\/\">\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/4c\/4m\/k7\/4c4mk7pj7ozce-14ymchq4bsa4s.jpeg\" width=\"500\"><\/div>\n<p>  \u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u043c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041e\u043b\u0435\u0433, \u044f \u0442\u0435\u0445\u043b\u0438\u0434 \u0432 \u0414\u043e\u043c\u041a\u043b\u0438\u043a\u0435. \u0412 \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 \u044f\u0434\u0440\u043e\u043c \u0441\u0442\u0435\u043a\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f Kotlin \u0438 Spring Boot. \u0425\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0432\u0430\u043c\u0438 \u0441\u0432\u043e\u0438\u043c \u043e\u043f\u044b\u0442\u043e\u043c \u043f\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044e \u0438 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044f\u0445 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 PostgreSQL \u0438 Hibernate \u0432 \u0441\u0432\u044f\u0437\u043a\u0435 \u0441\u043e Spring Boot \u0438 Kotlin. \u0422\u0430\u043a\u0436\u0435 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u0430, \u043f\u043e\u043a\u0430\u0436\u0443 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 Kotlin \u0438 \u0435\u0433\u043e \u043e\u0442\u043b\u0438\u0447\u0438\u044f \u043e\u0442 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 Java. \u0420\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u0445 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u0445, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043c\u043e\u0433\u0443\u0442 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u0442\u044c\u0441\u044f \u043d\u043e\u0432\u0438\u0447\u043a\u0438 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u0441\u0442\u0435\u043a\u0430 \u0441 Hibernate. \u0421\u0442\u0430\u0442\u044c\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c, \u0436\u0435\u043b\u0430\u044e\u0449\u0438\u043c \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0430 Kotlin \u0438 \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0445 \u0441\u043e Spring Boot, Hibernate Java.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-305007","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/305007","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=305007"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/305007\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=305007"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=305007"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=305007"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}