getAllPersons() {
+ return this.repository.findAll();
+ }
+}
diff --git a/2021-05/spring-32/docker-compose-example/src/main/resources/application.yml b/2021-05/spring-32/docker-compose-example/src/main/resources/application.yml
new file mode 100644
index 00000000..adb9be61
--- /dev/null
+++ b/2021-05/spring-32/docker-compose-example/src/main/resources/application.yml
@@ -0,0 +1,9 @@
+spring:
+ datasource:
+ # Эти свойства будут перегружены свойствами в docker-compose.yml
+ driver-class-name: org.postgresql.Driver
+ url: jdbc:postgresql://localhost:5432/db
+ username: postgres
+ password: postgres
+ jpa:
+ generate-ddl: true
diff --git a/2021-05/spring-32/docker-compose-example/src/main/resources/static/index.html b/2021-05/spring-32/docker-compose-example/src/main/resources/static/index.html
new file mode 100644
index 00000000..a80ea187
--- /dev/null
+++ b/2021-05/spring-32/docker-compose-example/src/main/resources/static/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+ Главная страницв
+
+
+Главная страница
+Список всех лиц доступен по ссылке.
+Перезапустив приложение можно добавить ещё в БД.
+
+
diff --git a/2021-05/spring-32/docker-compose-example/src/test/java/ru/otus/spring/docker/DockerComposeExampleApplicationTests.java b/2021-05/spring-32/docker-compose-example/src/test/java/ru/otus/spring/docker/DockerComposeExampleApplicationTests.java
new file mode 100644
index 00000000..93fe13c4
--- /dev/null
+++ b/2021-05/spring-32/docker-compose-example/src/test/java/ru/otus/spring/docker/DockerComposeExampleApplicationTests.java
@@ -0,0 +1,15 @@
+package ru.otus.spring.docker;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+@AutoConfigureTestDatabase
+class DockerComposeExampleApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/2021-05/spring-32/stacks-example/commands.txt b/2021-05/spring-32/stacks-example/commands.txt
new file mode 100644
index 00000000..7fea8c32
--- /dev/null
+++ b/2021-05/spring-32/stacks-example/commands.txt
@@ -0,0 +1,4 @@
+docker stack deploy -c docker-compose.yml 123
+docker stack ls
+docker stack ps .....
+docker stack services ....
diff --git a/2021-05/spring-32/stacks-example/docker-compose.yml b/2021-05/spring-32/stacks-example/docker-compose.yml
new file mode 100644
index 00000000..e80f8c28
--- /dev/null
+++ b/2021-05/spring-32/stacks-example/docker-compose.yml
@@ -0,0 +1,93 @@
+version: "3"
+services:
+
+ redis:
+ image: redis:alpine
+ networks:
+ - frontend
+ deploy:
+ replicas: 1
+ update_config:
+ parallelism: 2
+ delay: 10s
+ restart_policy:
+ condition: on-failure
+ db:
+ image: postgres:9.4
+ environment:
+ POSTGRES_USER: "postgres"
+ POSTGRES_PASSWORD: "postgres"
+ volumes:
+ - db-data:/var/lib/postgresql/data
+ networks:
+ - backend
+ deploy:
+ placement:
+ constraints: [node.role == manager]
+ vote:
+ image: dockersamples/examplevotingapp_vote:before
+ ports:
+ - 5000:80
+ networks:
+ - frontend
+ depends_on:
+ - redis
+ deploy:
+ replicas: 2
+ update_config:
+ parallelism: 2
+ restart_policy:
+ condition: on-failure
+ result:
+ image: dockersamples/examplevotingapp_result:before
+ ports:
+ - 5001:80
+ networks:
+ - backend
+ depends_on:
+ - db
+ deploy:
+ replicas: 1
+ update_config:
+ parallelism: 2
+ delay: 10s
+ restart_policy:
+ condition: on-failure
+
+ worker:
+ image: dockersamples/examplevotingapp_worker
+ networks:
+ - frontend
+ - backend
+ depends_on:
+ - db
+ - redis
+ deploy:
+ mode: replicated
+ replicas: 1
+ labels: [APP=VOTING]
+ restart_policy:
+ condition: on-failure
+ delay: 10s
+ max_attempts: 3
+ window: 120s
+ placement:
+ constraints: [node.role == manager]
+
+ visualizer:
+ image: dockersamples/visualizer:stable
+ ports:
+ - "8080:8080"
+ stop_grace_period: 1m30s
+ volumes:
+ - "/var/run/docker.sock:/var/run/docker.sock"
+ deploy:
+ placement:
+ constraints: [node.role == manager]
+
+networks:
+ frontend:
+ backend:
+
+volumes:
+ db-data:
diff --git a/2021-08/spring-11-data-jpa/.gitignore b/2021-08/spring-11-data-jpa/.gitignore
new file mode 100644
index 00000000..e62c33c2
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/.gitignore
@@ -0,0 +1,4 @@
+.idea/
+*.iml
+
+target/
diff --git a/2021-08/spring-11-data-jpa/demo/.gitignore b/2021-08/spring-11-data-jpa/demo/.gitignore
new file mode 100644
index 00000000..e62c33c2
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/demo/.gitignore
@@ -0,0 +1,4 @@
+.idea/
+*.iml
+
+target/
diff --git a/2021-08/spring-11-data-jpa/demo/pom.xml b/2021-08/spring-11-data-jpa/demo/pom.xml
new file mode 100644
index 00000000..48523ba6
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/demo/pom.xml
@@ -0,0 +1,55 @@
+
+
+ 4.0.0
+
+ ru.otus
+ demo
+ 1.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.4.5
+
+
+
+ 11
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ com.h2database
+ h2
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/Main.java b/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/Main.java
new file mode 100644
index 00000000..bd056210
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/Main.java
@@ -0,0 +1,75 @@
+package ru.otus.springdata;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+import org.springframework.data.jpa.domain.Specification;
+import ru.otus.springdata.domain.Email;
+import ru.otus.springdata.domain.Person;
+import ru.otus.springdata.repository.EmailRepository;
+import ru.otus.springdata.repository.PersonRepository;
+
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import static ru.otus.springdata.repository.PersonSpecification.emailAddressLike;
+import static ru.otus.springdata.repository.PersonSpecification.nameLike;
+
+@SpringBootApplication
+public class Main {
+
+ public static void main(String[] args) {
+ ConfigurableApplicationContext context = SpringApplication.run(Main.class);
+
+ PersonRepository personRepository = context.getBean(PersonRepository.class);
+ EmailRepository emailRepository = context.getBean(EmailRepository.class);
+
+ var pushkin = new Person("Александр Сергеевич Пушкин", new Email("alex.pushkin@mail.ru"));
+ var block = new Person("Александр Александрович Блок", new Email("alex.block@mail.ru"));
+ var lermontov = new Person("Михаил Юрьевич Лермонтов", new Email("michail.lermontov@bk.ru"));
+ var gorbachev = new Person("Михаил Сергеевич Горбачев", new Email("gorbachev@mail.ru"));
+ var bulgakov = new Person("Михаил Афанасьевич Булгаков", new Email("bulgakov@mail.ru"));
+
+ emailRepository.save(pushkin.getEmail());
+ emailRepository.save(block.getEmail());
+ emailRepository.save(lermontov.getEmail());
+ emailRepository.save(gorbachev.getEmail());
+ emailRepository.save(bulgakov.getEmail());
+
+ personRepository.save(pushkin);
+ personRepository.save(block);
+ personRepository.save(lermontov);
+ personRepository.save(gorbachev);
+ personRepository.save(bulgakov);
+
+ System.out.println("\n\nИщем почту Горбачева по его id");
+ emailRepository.findByPersonId(gorbachev.getId())
+ .ifPresent(System.out::println);
+
+
+ System.out.println("\n\nС помощью Example ищем всех пёрсонов с именем \"Михаил\" и почтой на \"mail.ru\"");
+ ExampleMatcher ignoringExampleMatcher = ExampleMatcher.matchingAll()
+ .withMatcher("email.address", ExampleMatcher.GenericPropertyMatchers.contains().ignoreCase())
+ .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains().ignoreCase())
+ .withIgnorePaths("id", "email.id");
+
+ Example example = Example.of(new Person("Михаил", new Email(0, "mail.ru")), ignoringExampleMatcher);
+
+ System.out.println(personRepository.findAll(example).stream().map(Objects::toString)
+ .collect(Collectors.joining("\n")));
+
+
+ System.out.println("\n\nС помощью Specification ищем всех пёрсонов с именем \"Александр\" или с почтой на \"bk.ru\"");
+
+ Specification specification = Specification.where(nameLike("Александр"))
+ .or(emailAddressLike("bk.ru"));
+
+ System.out.println(personRepository.findAll(specification).stream().map(Objects::toString)
+ .collect(Collectors.joining("\n")));
+
+ System.out.println("\n\n");
+
+ }
+}
diff --git a/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/domain/Email.java b/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/domain/Email.java
new file mode 100644
index 00000000..e3b8d344
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/domain/Email.java
@@ -0,0 +1,27 @@
+package ru.otus.springdata.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+public class Email {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ private String address;
+
+ public Email(String address) {
+ this.address = address;
+ }
+}
diff --git a/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/domain/Person.java b/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/domain/Person.java
new file mode 100644
index 00000000..e24e42aa
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/domain/Person.java
@@ -0,0 +1,30 @@
+package ru.otus.springdata.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+public class Person {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ private String name;
+
+ @OneToOne(orphanRemoval = true)
+ @JoinColumn(name = "email_id")
+ private Email email;
+
+ public Person(String name, Email email) {
+ this.name = name;
+ this.email = email;
+ }
+
+}
diff --git a/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepository.java b/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepository.java
new file mode 100644
index 00000000..a76a43ff
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepository.java
@@ -0,0 +1,21 @@
+package ru.otus.springdata.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.transaction.annotation.Transactional;
+import ru.otus.springdata.domain.Email;
+
+import java.util.Optional;
+
+public interface EmailRepository extends JpaRepository, EmailRepositoryCustom {
+
+ @Query("select e from Email e where e.address = :address")
+ Optional findByEmailAddress(@Param("address") String email);
+
+ @Modifying
+ @Transactional
+ @Query("update Email e set e.address = :address where e.id = :id")
+ void updateEmailById(@Param("id") long id, @Param("address") String address);
+}
diff --git a/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepositoryCustom.java b/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepositoryCustom.java
new file mode 100644
index 00000000..db7112e1
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepositoryCustom.java
@@ -0,0 +1,9 @@
+package ru.otus.springdata.repository;
+
+import ru.otus.springdata.domain.Email;
+
+import java.util.Optional;
+
+public interface EmailRepositoryCustom {
+ Optional findByPersonId(long personId);
+}
diff --git a/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepositoryCustomImpl.java b/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepositoryCustomImpl.java
new file mode 100644
index 00000000..18f9ac33
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepositoryCustomImpl.java
@@ -0,0 +1,20 @@
+package ru.otus.springdata.repository;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Repository;
+import ru.otus.springdata.domain.Email;
+import ru.otus.springdata.domain.Person;
+
+import java.util.Optional;
+
+@Repository
+@RequiredArgsConstructor
+public class EmailRepositoryCustomImpl implements EmailRepositoryCustom {
+
+ private final PersonRepository personRepository;
+
+ @Override
+ public Optional findByPersonId(long personId) {
+ return personRepository.findById(personId).map(Person::getEmail);
+ }
+}
diff --git a/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/repository/PersonRepository.java b/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/repository/PersonRepository.java
new file mode 100644
index 00000000..7bb5c825
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/repository/PersonRepository.java
@@ -0,0 +1,20 @@
+package ru.otus.springdata.repository;
+
+import org.springframework.data.jpa.repository.EntityGraph;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.repository.CrudRepository;
+import ru.otus.springdata.domain.Person;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface PersonRepository extends JpaRepository, JpaSpecificationExecutor {
+
+ @EntityGraph(attributePaths = "email")
+ List findAll();
+
+ Optional findByName(String s);
+
+ Optional findByEmailAddress(String email);
+}
diff --git a/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/repository/PersonSpecification.java b/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/repository/PersonSpecification.java
new file mode 100644
index 00000000..3f8c67b3
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/demo/src/main/java/ru/otus/springdata/repository/PersonSpecification.java
@@ -0,0 +1,21 @@
+package ru.otus.springdata.repository;
+
+import org.springframework.data.jpa.domain.Specification;
+import ru.otus.springdata.domain.Person;
+
+public class PersonSpecification {
+
+ public static Specification nameLike(String name) {
+ if (name == null) {
+ return null;
+ }
+ return (root, query, cb) -> cb.like(root.get("name"), "%" + name + "%");
+ }
+
+ public static Specification emailAddressLike(String address) {
+ if (address == null) {
+ return null;
+ }
+ return (root, query, cb) -> cb.like(root.join("email").get("address"), "%" + address + "%");
+ }
+}
diff --git a/2021-08/spring-11-data-jpa/demo/src/main/resources/application.yml b/2021-08/spring-11-data-jpa/demo/src/main/resources/application.yml
new file mode 100644
index 00000000..bd5b0f98
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/demo/src/main/resources/application.yml
@@ -0,0 +1,20 @@
+spring:
+ datasource:
+ url: jdbc:h2:mem:testdb
+ initialization-mode: never
+
+ jpa:
+ generate-ddl: true
+ hibernate:
+ ddl-auto: create
+
+ properties:
+ hibernate:
+ format_sql: false
+
+ show-sql: true
+
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2021-08/spring-11-data-jpa/exercise/.gitignore b/2021-08/spring-11-data-jpa/exercise/.gitignore
new file mode 100644
index 00000000..e62c33c2
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/exercise/.gitignore
@@ -0,0 +1,4 @@
+.idea/
+*.iml
+
+target/
diff --git a/2021-08/spring-11-data-jpa/exercise/pom.xml b/2021-08/spring-11-data-jpa/exercise/pom.xml
new file mode 100644
index 00000000..172b613d
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/exercise/pom.xml
@@ -0,0 +1,50 @@
+
+
+ 4.0.0
+
+ ru.otus
+ exercise
+ 1.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.4.5
+
+
+
+ 11
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ com.h2database
+ h2
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2021-08/spring-11-data-jpa/exercise/src/main/java/ru/otus/springdata/Main.java b/2021-08/spring-11-data-jpa/exercise/src/main/java/ru/otus/springdata/Main.java
new file mode 100644
index 00000000..dbbe3598
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/exercise/src/main/java/ru/otus/springdata/Main.java
@@ -0,0 +1,23 @@
+package ru.otus.springdata;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.ConfigurableApplicationContext;
+
+
+
+@SpringBootApplication
+public class Main {
+
+ public static void main(String[] args) {
+ ConfigurableApplicationContext context = SpringApplication.run(Main.class);
+ //PersonRepository personRepository = context.getBean(PersonRepository.class);
+ //EmailRepository emailRepository = context.getBean(EmailRepository.class);
+
+ // personRepository.save(new Person("Александр Сергеевич Пушкин"));
+ // personRepository.save(new Person("Михаил Юрьевич Лермонтов"));
+ // personRepository.save(new Person("Михаил Сергеевич Горбачев"));
+ }
+
+
+}
diff --git a/2021-08/spring-11-data-jpa/exercise/src/main/java/ru/otus/springdata/domain/Email.java b/2021-08/spring-11-data-jpa/exercise/src/main/java/ru/otus/springdata/domain/Email.java
new file mode 100644
index 00000000..5cb61fa0
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/exercise/src/main/java/ru/otus/springdata/domain/Email.java
@@ -0,0 +1,21 @@
+package ru.otus.springdata.domain;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class Email {
+
+ private long id;
+
+ private String address;
+
+ public Email(String address) {
+ this.address = address;
+ }
+
+}
diff --git a/2021-08/spring-11-data-jpa/exercise/src/main/java/ru/otus/springdata/domain/Person.java b/2021-08/spring-11-data-jpa/exercise/src/main/java/ru/otus/springdata/domain/Person.java
new file mode 100644
index 00000000..cc8e6d0a
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/exercise/src/main/java/ru/otus/springdata/domain/Person.java
@@ -0,0 +1,26 @@
+package ru.otus.springdata.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+public class Person {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ private String name;
+
+ public Person(String name) {
+ this.name = name;
+ }
+}
diff --git a/2021-08/spring-11-data-jpa/exercise/src/main/java/ru/otus/springdata/repository/EmailRepository.java b/2021-08/spring-11-data-jpa/exercise/src/main/java/ru/otus/springdata/repository/EmailRepository.java
new file mode 100644
index 00000000..7a446b95
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/exercise/src/main/java/ru/otus/springdata/repository/EmailRepository.java
@@ -0,0 +1,4 @@
+package ru.otus.springdata.repository;
+
+public interface EmailRepository {
+}
diff --git a/2021-08/spring-11-data-jpa/exercise/src/main/java/ru/otus/springdata/repository/PersonRepository.java b/2021-08/spring-11-data-jpa/exercise/src/main/java/ru/otus/springdata/repository/PersonRepository.java
new file mode 100644
index 00000000..f8e5fc8a
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/exercise/src/main/java/ru/otus/springdata/repository/PersonRepository.java
@@ -0,0 +1,4 @@
+package ru.otus.springdata.repository;
+
+public interface PersonRepository {
+}
diff --git a/2021-08/spring-11-data-jpa/exercise/src/main/resources/application.yml b/2021-08/spring-11-data-jpa/exercise/src/main/resources/application.yml
new file mode 100644
index 00000000..bd5b0f98
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/exercise/src/main/resources/application.yml
@@ -0,0 +1,20 @@
+spring:
+ datasource:
+ url: jdbc:h2:mem:testdb
+ initialization-mode: never
+
+ jpa:
+ generate-ddl: true
+ hibernate:
+ ddl-auto: create
+
+ properties:
+ hibernate:
+ format_sql: false
+
+ show-sql: true
+
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2021-08/spring-11-data-jpa/pom.xml b/2021-08/spring-11-data-jpa/pom.xml
new file mode 100644
index 00000000..922fc48a
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/pom.xml
@@ -0,0 +1,21 @@
+
+
+ 4.0.0
+
+ ru.otus
+ spring-11-data-jpa
+ 1.0
+
+ pom
+
+
+ exercise
+ solution-01
+ solution-02
+ solution-03
+ solution-04
+ demo
+
+
diff --git a/2021-08/spring-11-data-jpa/solution-01/.gitignore b/2021-08/spring-11-data-jpa/solution-01/.gitignore
new file mode 100644
index 00000000..e62c33c2
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-01/.gitignore
@@ -0,0 +1,4 @@
+.idea/
+*.iml
+
+target/
diff --git a/2021-08/spring-11-data-jpa/solution-01/pom.xml b/2021-08/spring-11-data-jpa/solution-01/pom.xml
new file mode 100644
index 00000000..355f4335
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-01/pom.xml
@@ -0,0 +1,55 @@
+
+
+ 4.0.0
+
+ ru.otus
+ solution-01
+ 1.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.4.5
+
+
+
+ 11
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ com.h2database
+ h2
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2021-08/spring-11-data-jpa/solution-01/src/main/java/ru/otus/springdata/Main.java b/2021-08/spring-11-data-jpa/solution-01/src/main/java/ru/otus/springdata/Main.java
new file mode 100644
index 00000000..4961485f
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-01/src/main/java/ru/otus/springdata/Main.java
@@ -0,0 +1,37 @@
+package ru.otus.springdata;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.ConfigurableApplicationContext;
+import ru.otus.springdata.domain.Person;
+import ru.otus.springdata.repository.PersonRepository;
+
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@SpringBootApplication
+public class Main {
+
+ public static void main(String[] args) {
+ ConfigurableApplicationContext context = SpringApplication.run(Main.class);
+
+ PersonRepository personRepository = context.getBean(PersonRepository.class);
+
+
+ personRepository.save(new Person("Александр Сергеевич Пушкин"));
+ personRepository.save(new Person("Михаил Юрьевич Лермонтов"));
+ personRepository.save(new Person("Михаил Сергеевич Горбачев"));
+
+ System.out.println("\n\nИщем всех пёрсонов");
+ System.out.println(personRepository.findAll().stream().map(Objects::toString)
+ .collect(Collectors.joining("\n")));
+
+ System.out.println("\n\nИщем Пушкина");
+ personRepository.findByName("Александр Сергеевич Пушкин")
+ .ifPresent(System.out::println);
+
+
+ System.out.println("\n\n");
+
+ }
+}
diff --git a/2021-08/spring-11-data-jpa/solution-01/src/main/java/ru/otus/springdata/domain/Email.java b/2021-08/spring-11-data-jpa/solution-01/src/main/java/ru/otus/springdata/domain/Email.java
new file mode 100644
index 00000000..3f0bd00c
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-01/src/main/java/ru/otus/springdata/domain/Email.java
@@ -0,0 +1,24 @@
+package ru.otus.springdata.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class Email {
+
+ private long id;
+
+ private String address;
+
+ public Email(String address) {
+ this.address = address;
+ }
+}
diff --git a/2021-08/spring-11-data-jpa/solution-01/src/main/java/ru/otus/springdata/domain/Person.java b/2021-08/spring-11-data-jpa/solution-01/src/main/java/ru/otus/springdata/domain/Person.java
new file mode 100644
index 00000000..96d92b91
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-01/src/main/java/ru/otus/springdata/domain/Person.java
@@ -0,0 +1,25 @@
+package ru.otus.springdata.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+public class Person {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ private String name;
+
+ public Person(String name) {
+ this.name = name;
+ }
+
+}
diff --git a/2021-08/spring-11-data-jpa/solution-01/src/main/java/ru/otus/springdata/repository/EmailRepository.java b/2021-08/spring-11-data-jpa/solution-01/src/main/java/ru/otus/springdata/repository/EmailRepository.java
new file mode 100644
index 00000000..788feda5
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-01/src/main/java/ru/otus/springdata/repository/EmailRepository.java
@@ -0,0 +1,12 @@
+package ru.otus.springdata.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import ru.otus.springdata.domain.Email;
+
+import java.util.List;
+
+public interface EmailRepository extends JpaRepository {
+
+ @Override
+ List findAll();
+}
diff --git a/2021-08/spring-11-data-jpa/solution-01/src/main/java/ru/otus/springdata/repository/PersonRepository.java b/2021-08/spring-11-data-jpa/solution-01/src/main/java/ru/otus/springdata/repository/PersonRepository.java
new file mode 100644
index 00000000..012ded26
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-01/src/main/java/ru/otus/springdata/repository/PersonRepository.java
@@ -0,0 +1,15 @@
+package ru.otus.springdata.repository;
+
+import org.springframework.data.repository.CrudRepository;
+import ru.otus.springdata.domain.Person;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface PersonRepository extends CrudRepository {
+
+ @Override
+ List findAll();
+
+ Optional findByName(String s);
+}
diff --git a/2021-08/spring-11-data-jpa/solution-01/src/main/resources/application.yml b/2021-08/spring-11-data-jpa/solution-01/src/main/resources/application.yml
new file mode 100644
index 00000000..bd5b0f98
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-01/src/main/resources/application.yml
@@ -0,0 +1,20 @@
+spring:
+ datasource:
+ url: jdbc:h2:mem:testdb
+ initialization-mode: never
+
+ jpa:
+ generate-ddl: true
+ hibernate:
+ ddl-auto: create
+
+ properties:
+ hibernate:
+ format_sql: false
+
+ show-sql: true
+
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2021-08/spring-11-data-jpa/solution-02/.gitignore b/2021-08/spring-11-data-jpa/solution-02/.gitignore
new file mode 100644
index 00000000..e62c33c2
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-02/.gitignore
@@ -0,0 +1,4 @@
+.idea/
+*.iml
+
+target/
diff --git a/2021-08/spring-11-data-jpa/solution-02/pom.xml b/2021-08/spring-11-data-jpa/solution-02/pom.xml
new file mode 100644
index 00000000..c6dd4ab8
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-02/pom.xml
@@ -0,0 +1,55 @@
+
+
+ 4.0.0
+
+ ru.otus
+ solution-02
+ 1.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.4.5
+
+
+
+ 11
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ com.h2database
+ h2
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2021-08/spring-11-data-jpa/solution-02/src/main/java/ru/otus/springdata/Main.java b/2021-08/spring-11-data-jpa/solution-02/src/main/java/ru/otus/springdata/Main.java
new file mode 100644
index 00000000..d25a29d2
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-02/src/main/java/ru/otus/springdata/Main.java
@@ -0,0 +1,53 @@
+package ru.otus.springdata;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.ConfigurableApplicationContext;
+import ru.otus.springdata.domain.Email;
+import ru.otus.springdata.domain.Person;
+import ru.otus.springdata.repository.EmailRepository;
+import ru.otus.springdata.repository.PersonRepository;
+
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@SpringBootApplication
+public class Main {
+
+ public static void main(String[] args) {
+
+ ConfigurableApplicationContext context = SpringApplication.run(Main.class);
+ PersonRepository personRepository = context.getBean(PersonRepository.class);
+ EmailRepository emailRepository = context.getBean(EmailRepository.class);
+
+ var pushkinEmail = new Email("alex.pushkin@mail.ru");
+ var lermontovEmail = new Email("michail.lermontov@mail.ru");
+ var gorbachevEmail = new Email("gorbachev@mail.ru");
+
+ var pushkin = new Person("Александр Сергеевич Пушкин");
+ var lermontov = new Person("Михаил Юрьевич Лермонтов");
+ var gorbachev = new Person("Михаил Сергеевич Горбачев");
+
+ emailRepository.save(pushkinEmail);
+ emailRepository.save(lermontovEmail);
+ emailRepository.save(gorbachevEmail);
+
+ personRepository.save(pushkin);
+ personRepository.save(lermontov);
+ personRepository.save(gorbachev);
+
+ System.out.println("\n\nИщем всех пёрсонов");
+ System.out.println(personRepository.findAll().stream().map(Objects::toString)
+ .collect(Collectors.joining("\n")));
+
+ System.out.println("\n\nИщем Пушкина");
+ personRepository.findByName("Александр Сергеевич Пушкин")
+ .ifPresent(System.out::println);
+
+ System.out.println("\n\nИщем все почты");
+ System.out.println(emailRepository.findAll().stream().map(Objects::toString)
+ .collect(Collectors.joining("\n")));
+
+ System.out.println("\n\n");
+ }
+}
diff --git a/2021-08/spring-11-data-jpa/solution-02/src/main/java/ru/otus/springdata/domain/Email.java b/2021-08/spring-11-data-jpa/solution-02/src/main/java/ru/otus/springdata/domain/Email.java
new file mode 100644
index 00000000..e3b8d344
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-02/src/main/java/ru/otus/springdata/domain/Email.java
@@ -0,0 +1,27 @@
+package ru.otus.springdata.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+public class Email {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ private String address;
+
+ public Email(String address) {
+ this.address = address;
+ }
+}
diff --git a/2021-08/spring-11-data-jpa/solution-02/src/main/java/ru/otus/springdata/domain/Person.java b/2021-08/spring-11-data-jpa/solution-02/src/main/java/ru/otus/springdata/domain/Person.java
new file mode 100644
index 00000000..96d92b91
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-02/src/main/java/ru/otus/springdata/domain/Person.java
@@ -0,0 +1,25 @@
+package ru.otus.springdata.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+public class Person {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ private String name;
+
+ public Person(String name) {
+ this.name = name;
+ }
+
+}
diff --git a/2021-08/spring-11-data-jpa/solution-02/src/main/java/ru/otus/springdata/repository/EmailRepository.java b/2021-08/spring-11-data-jpa/solution-02/src/main/java/ru/otus/springdata/repository/EmailRepository.java
new file mode 100644
index 00000000..3d5c3152
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-02/src/main/java/ru/otus/springdata/repository/EmailRepository.java
@@ -0,0 +1,13 @@
+package ru.otus.springdata.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.transaction.annotation.Transactional;
+import ru.otus.springdata.domain.Email;
+
+import java.util.Optional;
+
+public interface EmailRepository extends JpaRepository{
+}
diff --git a/2021-08/spring-11-data-jpa/solution-02/src/main/java/ru/otus/springdata/repository/PersonRepository.java b/2021-08/spring-11-data-jpa/solution-02/src/main/java/ru/otus/springdata/repository/PersonRepository.java
new file mode 100644
index 00000000..cd5bb3f0
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-02/src/main/java/ru/otus/springdata/repository/PersonRepository.java
@@ -0,0 +1,14 @@
+package ru.otus.springdata.repository;
+
+import org.springframework.data.repository.CrudRepository;
+import ru.otus.springdata.domain.Person;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface PersonRepository extends CrudRepository {
+
+ List findAll();
+
+ Optional findByName(String s);
+}
diff --git a/2021-08/spring-11-data-jpa/solution-02/src/main/resources/application.yml b/2021-08/spring-11-data-jpa/solution-02/src/main/resources/application.yml
new file mode 100644
index 00000000..bd5b0f98
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-02/src/main/resources/application.yml
@@ -0,0 +1,20 @@
+spring:
+ datasource:
+ url: jdbc:h2:mem:testdb
+ initialization-mode: never
+
+ jpa:
+ generate-ddl: true
+ hibernate:
+ ddl-auto: create
+
+ properties:
+ hibernate:
+ format_sql: false
+
+ show-sql: true
+
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2021-08/spring-11-data-jpa/solution-03/.gitignore b/2021-08/spring-11-data-jpa/solution-03/.gitignore
new file mode 100644
index 00000000..e62c33c2
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-03/.gitignore
@@ -0,0 +1,4 @@
+.idea/
+*.iml
+
+target/
diff --git a/2021-08/spring-11-data-jpa/solution-03/pom.xml b/2021-08/spring-11-data-jpa/solution-03/pom.xml
new file mode 100644
index 00000000..4fff22c3
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-03/pom.xml
@@ -0,0 +1,55 @@
+
+
+ 4.0.0
+
+ ru.otus
+ solution-03
+ 1.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.4.5
+
+
+
+ 11
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ com.h2database
+ h2
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2021-08/spring-11-data-jpa/solution-03/src/main/java/ru/otus/springdata/Main.java b/2021-08/spring-11-data-jpa/solution-03/src/main/java/ru/otus/springdata/Main.java
new file mode 100644
index 00000000..a02e3e25
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-03/src/main/java/ru/otus/springdata/Main.java
@@ -0,0 +1,55 @@
+package ru.otus.springdata;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+import ru.otus.springdata.domain.Email;
+import ru.otus.springdata.domain.Person;
+import ru.otus.springdata.repository.EmailRepository;
+import ru.otus.springdata.repository.PersonRepository;
+
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@SpringBootApplication
+public class Main {
+
+ public static void main(String[] args) {
+ ConfigurableApplicationContext context = SpringApplication.run(Main.class);
+
+ PersonRepository personRepository = context.getBean(PersonRepository.class);
+ EmailRepository emailRepository = context.getBean(EmailRepository.class);
+
+ var pushkin = new Person("Александр Сергеевич Пушкин", new Email("alex.pushkin@mail.ru"));
+ var lermontov = new Person("Михаил Юрьевич Лермонтов", new Email("michail.lermontov@mail.ru"));
+ var gorbachev = new Person("Михаил Сергеевич Горбачев", new Email("gorbachev@mail.ru"));
+
+ emailRepository.save(pushkin.getEmail());
+ emailRepository.save(lermontov.getEmail());
+ emailRepository.save(gorbachev.getEmail());
+
+ personRepository.save(pushkin);
+ personRepository.save(lermontov);
+ personRepository.save(gorbachev);
+
+ System.out.println("\n\nИщем всех пёрсонов");
+ System.out.println(personRepository.findAll().stream().map(Objects::toString)
+ .collect(Collectors.joining("\n")));
+
+ System.out.println("\n\nИщем Пушкина");
+ personRepository.findByName("Александр Сергеевич Пушкин")
+ .ifPresent(System.out::println);
+
+ System.out.println("\n\nИщем все почты");
+ System.out.println(emailRepository.findAll().stream().map(Objects::toString)
+ .collect(Collectors.joining("\n")));
+
+ System.out.println("\n\nИщем Пушкина по его почте");
+ personRepository.findByEmailAddress("alex.pushkin@mail.ru")
+ .ifPresent(System.out::println);
+
+ System.out.println("\n\n");
+ }
+}
diff --git a/2021-08/spring-11-data-jpa/solution-03/src/main/java/ru/otus/springdata/domain/Email.java b/2021-08/spring-11-data-jpa/solution-03/src/main/java/ru/otus/springdata/domain/Email.java
new file mode 100644
index 00000000..e3b8d344
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-03/src/main/java/ru/otus/springdata/domain/Email.java
@@ -0,0 +1,27 @@
+package ru.otus.springdata.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+public class Email {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ private String address;
+
+ public Email(String address) {
+ this.address = address;
+ }
+}
diff --git a/2021-08/spring-11-data-jpa/solution-03/src/main/java/ru/otus/springdata/domain/Person.java b/2021-08/spring-11-data-jpa/solution-03/src/main/java/ru/otus/springdata/domain/Person.java
new file mode 100644
index 00000000..e24e42aa
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-03/src/main/java/ru/otus/springdata/domain/Person.java
@@ -0,0 +1,30 @@
+package ru.otus.springdata.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+public class Person {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ private String name;
+
+ @OneToOne(orphanRemoval = true)
+ @JoinColumn(name = "email_id")
+ private Email email;
+
+ public Person(String name, Email email) {
+ this.name = name;
+ this.email = email;
+ }
+
+}
diff --git a/2021-08/spring-11-data-jpa/solution-03/src/main/java/ru/otus/springdata/repository/EmailRepository.java b/2021-08/spring-11-data-jpa/solution-03/src/main/java/ru/otus/springdata/repository/EmailRepository.java
new file mode 100644
index 00000000..16f1d0c9
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-03/src/main/java/ru/otus/springdata/repository/EmailRepository.java
@@ -0,0 +1,13 @@
+package ru.otus.springdata.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.transaction.annotation.Transactional;
+import ru.otus.springdata.domain.Email;
+
+import java.util.Optional;
+
+public interface EmailRepository extends JpaRepository {
+}
diff --git a/2021-08/spring-11-data-jpa/solution-03/src/main/java/ru/otus/springdata/repository/PersonRepository.java b/2021-08/spring-11-data-jpa/solution-03/src/main/java/ru/otus/springdata/repository/PersonRepository.java
new file mode 100644
index 00000000..a6aa8dd3
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-03/src/main/java/ru/otus/springdata/repository/PersonRepository.java
@@ -0,0 +1,18 @@
+package ru.otus.springdata.repository;
+
+import org.springframework.data.jpa.repository.EntityGraph;
+import org.springframework.data.repository.CrudRepository;
+import ru.otus.springdata.domain.Person;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface PersonRepository extends CrudRepository {
+
+ @EntityGraph(attributePaths = "email")
+ List findAll();
+
+ Optional findByName(String s);
+
+ Optional findByEmailAddress(String email);
+}
diff --git a/2021-08/spring-11-data-jpa/solution-03/src/main/resources/application.yml b/2021-08/spring-11-data-jpa/solution-03/src/main/resources/application.yml
new file mode 100644
index 00000000..bd5b0f98
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-03/src/main/resources/application.yml
@@ -0,0 +1,20 @@
+spring:
+ datasource:
+ url: jdbc:h2:mem:testdb
+ initialization-mode: never
+
+ jpa:
+ generate-ddl: true
+ hibernate:
+ ddl-auto: create
+
+ properties:
+ hibernate:
+ format_sql: false
+
+ show-sql: true
+
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2021-08/spring-11-data-jpa/solution-04/.gitignore b/2021-08/spring-11-data-jpa/solution-04/.gitignore
new file mode 100644
index 00000000..e62c33c2
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-04/.gitignore
@@ -0,0 +1,4 @@
+.idea/
+*.iml
+
+target/
diff --git a/2021-08/spring-11-data-jpa/solution-04/pom.xml b/2021-08/spring-11-data-jpa/solution-04/pom.xml
new file mode 100644
index 00000000..6f0a221c
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-04/pom.xml
@@ -0,0 +1,55 @@
+
+
+ 4.0.0
+
+ ru.otus
+ solution-04
+ 1.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.4.5
+
+
+
+ 11
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ com.h2database
+ h2
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2021-08/spring-11-data-jpa/solution-04/src/main/java/ru/otus/springdata/Main.java b/2021-08/spring-11-data-jpa/solution-04/src/main/java/ru/otus/springdata/Main.java
new file mode 100644
index 00000000..4574b783
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-04/src/main/java/ru/otus/springdata/Main.java
@@ -0,0 +1,64 @@
+package ru.otus.springdata;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+import ru.otus.springdata.domain.Email;
+import ru.otus.springdata.domain.Person;
+import ru.otus.springdata.repository.EmailRepository;
+import ru.otus.springdata.repository.PersonRepository;
+
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@SpringBootApplication
+public class Main {
+
+ public static void main(String[] args) {
+ ConfigurableApplicationContext context = SpringApplication.run(Main.class);
+
+ PersonRepository personRepository = context.getBean(PersonRepository.class);
+ EmailRepository emailRepository = context.getBean(EmailRepository.class);
+
+ var pushkin = new Person("Александр Сергеевич Пушкин", new Email("alex.pushkin@mail.ru"));
+ var lermontov = new Person("Михаил Юрьевич Лермонтов", new Email("michail.lermontov@mail.ru"));
+ var gorbachev = new Person("Михаил Сергеевич Горбачев", new Email("gorbachev@mail.ru"));
+
+ emailRepository.save(pushkin.getEmail());
+ emailRepository.save(lermontov.getEmail());
+ emailRepository.save(gorbachev.getEmail());
+
+ personRepository.save(pushkin);
+ personRepository.save(lermontov);
+ personRepository.save(gorbachev);
+
+ System.out.println("\n\nИщем всех пёрсонов");
+ System.out.println(personRepository.findAll().stream().map(Objects::toString)
+ .collect(Collectors.joining("\n")));
+
+ System.out.println("\n\nИщем Пушкина");
+ personRepository.findByName("Александр Сергеевич Пушкин")
+ .ifPresent(System.out::println);
+
+ System.out.println("\n\nИщем все почты");
+ System.out.println(emailRepository.findAll().stream().map(Objects::toString)
+ .collect(Collectors.joining("\n")));
+
+ System.out.println("\n\nИщем Пушкина по его почте");
+ personRepository.findByEmailAddress("alex.pushkin@mail.ru")
+ .ifPresent(System.out::println);
+
+ System.out.println("\n\nОбновляем почту Лермонтову");
+ System.out.println("До обновления: " + lermontov.getEmail());
+ emailRepository.updateEmailById(lermontov.getId(), "michail1984@lermontov.ru");
+
+ System.out.println("\n\nИщем почту Лермонтова по новому адресу");
+ emailRepository.findByEmailAddress("michail1984@lermontov.ru")
+ .ifPresent(e -> System.out.println("После обновления: " + e));
+
+ System.out.println("\n\n");
+
+ }
+}
diff --git a/2021-08/spring-11-data-jpa/solution-04/src/main/java/ru/otus/springdata/domain/Email.java b/2021-08/spring-11-data-jpa/solution-04/src/main/java/ru/otus/springdata/domain/Email.java
new file mode 100644
index 00000000..e3b8d344
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-04/src/main/java/ru/otus/springdata/domain/Email.java
@@ -0,0 +1,27 @@
+package ru.otus.springdata.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+public class Email {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ private String address;
+
+ public Email(String address) {
+ this.address = address;
+ }
+}
diff --git a/2021-08/spring-11-data-jpa/solution-04/src/main/java/ru/otus/springdata/domain/Person.java b/2021-08/spring-11-data-jpa/solution-04/src/main/java/ru/otus/springdata/domain/Person.java
new file mode 100644
index 00000000..e24e42aa
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-04/src/main/java/ru/otus/springdata/domain/Person.java
@@ -0,0 +1,30 @@
+package ru.otus.springdata.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+public class Person {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ private String name;
+
+ @OneToOne(orphanRemoval = true)
+ @JoinColumn(name = "email_id")
+ private Email email;
+
+ public Person(String name, Email email) {
+ this.name = name;
+ this.email = email;
+ }
+
+}
diff --git a/2021-08/spring-11-data-jpa/solution-04/src/main/java/ru/otus/springdata/repository/EmailRepository.java b/2021-08/spring-11-data-jpa/solution-04/src/main/java/ru/otus/springdata/repository/EmailRepository.java
new file mode 100644
index 00000000..66b4da80
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-04/src/main/java/ru/otus/springdata/repository/EmailRepository.java
@@ -0,0 +1,21 @@
+package ru.otus.springdata.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.transaction.annotation.Transactional;
+import ru.otus.springdata.domain.Email;
+
+import java.util.Optional;
+
+public interface EmailRepository extends JpaRepository {
+
+ @Query("select e from Email e where e.address = :address")
+ Optional findByEmailAddress(@Param("address") String email);
+
+ @Modifying
+ @Transactional
+ @Query("update Email e set e.address = :address where e.id = :id")
+ void updateEmailById(@Param("id") long id, @Param("address") String address);
+}
diff --git a/2021-08/spring-11-data-jpa/solution-04/src/main/java/ru/otus/springdata/repository/PersonRepository.java b/2021-08/spring-11-data-jpa/solution-04/src/main/java/ru/otus/springdata/repository/PersonRepository.java
new file mode 100644
index 00000000..a6aa8dd3
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-04/src/main/java/ru/otus/springdata/repository/PersonRepository.java
@@ -0,0 +1,18 @@
+package ru.otus.springdata.repository;
+
+import org.springframework.data.jpa.repository.EntityGraph;
+import org.springframework.data.repository.CrudRepository;
+import ru.otus.springdata.domain.Person;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface PersonRepository extends CrudRepository {
+
+ @EntityGraph(attributePaths = "email")
+ List findAll();
+
+ Optional findByName(String s);
+
+ Optional findByEmailAddress(String email);
+}
diff --git a/2021-08/spring-11-data-jpa/solution-04/src/main/resources/application.yml b/2021-08/spring-11-data-jpa/solution-04/src/main/resources/application.yml
new file mode 100644
index 00000000..bd5b0f98
--- /dev/null
+++ b/2021-08/spring-11-data-jpa/solution-04/src/main/resources/application.yml
@@ -0,0 +1,20 @@
+spring:
+ datasource:
+ url: jdbc:h2:mem:testdb
+ initialization-mode: never
+
+ jpa:
+ generate-ddl: true
+ hibernate:
+ ddl-auto: create
+
+ properties:
+ hibernate:
+ format_sql: false
+
+ show-sql: true
+
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2021-08/spring-13/spring-data-keyvalue-class-work/pom.xml b/2021-08/spring-13/spring-data-keyvalue-class-work/pom.xml
new file mode 100644
index 00000000..b2fbb1c3
--- /dev/null
+++ b/2021-08/spring-13/spring-data-keyvalue-class-work/pom.xml
@@ -0,0 +1,17 @@
+
+
+ 4.0.0
+
+ ru.otus
+ spring-data-keyvalue-class-work
+ 1.0
+
+ pom
+
+
+ spring-data-keyvalue-exercise
+ spring-data-keyvalue-solution
+
+
diff --git a/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-exercise/pom.xml b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-exercise/pom.xml
new file mode 100644
index 00000000..180b1a60
--- /dev/null
+++ b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-exercise/pom.xml
@@ -0,0 +1,43 @@
+
+
+ 4.0.0
+
+ ru.otus
+ spring-data-keyvalue-exercise
+ 1.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.2.1.RELEASE
+
+
+
+
+ 11
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-exercise/src/main/java/ru/otus/spring/Main.java b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-exercise/src/main/java/ru/otus/spring/Main.java
new file mode 100644
index 00000000..d0d34e97
--- /dev/null
+++ b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-exercise/src/main/java/ru/otus/spring/Main.java
@@ -0,0 +1,29 @@
+package ru.otus.spring;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.data.map.repository.config.EnableMapRepositories;
+import ru.otus.spring.domain.Person;
+import ru.otus.spring.repostory.PersonRepository;
+
+import javax.annotation.PostConstruct;
+
+@SpringBootApplication
+public class Main {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Main.class);
+ }
+
+ @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
+ @Autowired
+ private PersonRepository repository;
+
+ @PostConstruct
+ public void init() {
+ repository.save(new Person(1, "Pushkin"));
+
+ repository.findAll();
+ }
+}
diff --git a/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-exercise/src/main/java/ru/otus/spring/domain/Email.java b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-exercise/src/main/java/ru/otus/spring/domain/Email.java
new file mode 100644
index 00000000..c1e24a7d
--- /dev/null
+++ b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-exercise/src/main/java/ru/otus/spring/domain/Email.java
@@ -0,0 +1,25 @@
+package ru.otus.spring.domain;
+
+public class Email {
+
+ private int id;
+
+ private String email;
+
+ public Email(String email) {
+ this.email = email;
+ }
+
+ public Email(int id, String email) {
+ this.id = id;
+ this.email = email;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+}
diff --git a/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-exercise/src/main/java/ru/otus/spring/domain/Person.java b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-exercise/src/main/java/ru/otus/spring/domain/Person.java
new file mode 100644
index 00000000..f707e14e
--- /dev/null
+++ b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-exercise/src/main/java/ru/otus/spring/domain/Person.java
@@ -0,0 +1,35 @@
+package ru.otus.spring.domain;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.keyvalue.annotation.KeySpace;
+
+public class Person {
+
+ private int id;
+ private String name;
+
+ public Person(String name) {
+ this.name = name;
+ }
+
+ public Person(int id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-exercise/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-exercise/src/main/java/ru/otus/spring/repostory/PersonRepository.java
new file mode 100644
index 00000000..4b20e5b7
--- /dev/null
+++ b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-exercise/src/main/java/ru/otus/spring/repostory/PersonRepository.java
@@ -0,0 +1,11 @@
+package ru.otus.spring.repostory;
+
+import org.springframework.data.repository.CrudRepository;
+import ru.otus.spring.domain.Person;
+
+import java.util.List;
+
+public interface PersonRepository extends CrudRepository {
+
+ List findAll();
+}
diff --git a/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/pom.xml b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/pom.xml
new file mode 100644
index 00000000..7d0041e8
--- /dev/null
+++ b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/pom.xml
@@ -0,0 +1,43 @@
+
+
+ 4.0.0
+
+ ru.otus
+ spring-data-keyvalue-solution
+ 1.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.2.1.RELEASE
+
+
+
+
+ 11
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.data
+ spring-data-keyvalue
+ 2.2.1.RELEASE
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/src/main/java/ru/otus/spring/Main.java b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/src/main/java/ru/otus/spring/Main.java
new file mode 100644
index 00000000..42d9078f
--- /dev/null
+++ b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/src/main/java/ru/otus/spring/Main.java
@@ -0,0 +1,39 @@
+package ru.otus.spring;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.data.map.repository.config.EnableMapRepositories;
+import ru.otus.spring.domain.Email;
+import ru.otus.spring.domain.Person;
+import ru.otus.spring.repostory.EmailRepository;
+import ru.otus.spring.repostory.PersonRepository;
+
+import javax.annotation.PostConstruct;
+
+@SpringBootApplication
+@EnableMapRepositories
+public class Main {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Main.class);
+ }
+
+ @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
+ @Autowired
+ private PersonRepository repository;
+
+ @Autowired
+ private EmailRepository emailRepository;
+
+ @PostConstruct
+ public void init() {
+ repository.save(new Person(1, "Pushkin"));
+ repository.save(new Person(2, "Lermontov"));
+ System.out.println(repository.findAll());
+
+ emailRepository.save(new Email(1, "alex@pushkin.com"));
+ emailRepository.save(new Email(2, "micha@pushkin.com"));
+ System.out.println(emailRepository.findAll());
+ }
+}
diff --git a/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/src/main/java/ru/otus/spring/domain/Email.java b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/src/main/java/ru/otus/spring/domain/Email.java
new file mode 100644
index 00000000..86ddb0c1
--- /dev/null
+++ b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/src/main/java/ru/otus/spring/domain/Email.java
@@ -0,0 +1,37 @@
+package ru.otus.spring.domain;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.keyvalue.annotation.KeySpace;
+
+@KeySpace("email")
+public class Email {
+ @Id
+ private int id;
+
+ private String email;
+
+ public Email(int id, String email) {
+ this.id = id;
+ this.email = email;
+ }
+
+ public Email(String email) {
+ this.email = email;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ @Override
+ public String toString() {
+ return "Email{" +
+ "id=" + id +
+ ", email='" + email + '\'' +
+ '}';
+ }
+}
diff --git a/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/src/main/java/ru/otus/spring/domain/Person.java b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/src/main/java/ru/otus/spring/domain/Person.java
new file mode 100644
index 00000000..b0181bd1
--- /dev/null
+++ b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/src/main/java/ru/otus/spring/domain/Person.java
@@ -0,0 +1,45 @@
+package ru.otus.spring.domain;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.keyvalue.annotation.KeySpace;
+
+@KeySpace("person")
+public class Person {
+
+ @Id
+ private int id;
+ private String name;
+
+ public Person(int id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public Person(String name) {
+ this.name = name;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return "Person{" +
+ "id=" + id +
+ ", name='" + name + '\'' +
+ '}';
+ }
+}
diff --git a/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/src/main/java/ru/otus/spring/repostory/EmailRepository.java b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/src/main/java/ru/otus/spring/repostory/EmailRepository.java
new file mode 100644
index 00000000..6ce870a2
--- /dev/null
+++ b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/src/main/java/ru/otus/spring/repostory/EmailRepository.java
@@ -0,0 +1,14 @@
+package ru.otus.spring.repostory;
+
+import org.springframework.data.keyvalue.repository.KeyValueRepository;
+import org.springframework.stereotype.Repository;
+import ru.otus.spring.domain.Email;
+import ru.otus.spring.domain.Person;
+
+import java.util.List;
+
+public interface EmailRepository {
+
+ List findAll();
+ Email save(Email email);
+}
diff --git a/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/src/main/java/ru/otus/spring/repostory/EmailRepositoryImpl.java b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/src/main/java/ru/otus/spring/repostory/EmailRepositoryImpl.java
new file mode 100644
index 00000000..e2aa75a1
--- /dev/null
+++ b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/src/main/java/ru/otus/spring/repostory/EmailRepositoryImpl.java
@@ -0,0 +1,27 @@
+package ru.otus.spring.repostory;
+
+import org.springframework.data.keyvalue.core.KeyValueOperations;
+import org.springframework.stereotype.Repository;
+import ru.otus.spring.domain.Email;
+
+import java.util.List;
+
+@Repository
+public class EmailRepositoryImpl implements EmailRepository {
+
+ final private KeyValueOperations keyValueTemplate;
+
+ public EmailRepositoryImpl(KeyValueOperations keyValueTemplate) {
+ this.keyValueTemplate = keyValueTemplate;
+ }
+
+ @Override
+ public List findAll() {
+ return (List) keyValueTemplate.findAll(Email.class);
+ }
+
+ @Override
+ public Email save(Email email) {
+ return keyValueTemplate.insert(email);
+ }
+}
diff --git a/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/src/main/java/ru/otus/spring/repostory/PersonRepository.java
new file mode 100644
index 00000000..99a93c24
--- /dev/null
+++ b/2021-08/spring-13/spring-data-keyvalue-class-work/spring-data-keyvalue-solution/src/main/java/ru/otus/spring/repostory/PersonRepository.java
@@ -0,0 +1,12 @@
+package ru.otus.spring.repostory;
+
+import org.springframework.data.keyvalue.repository.KeyValueRepository;
+import org.springframework.data.repository.CrudRepository;
+import ru.otus.spring.domain.Person;
+
+import java.util.List;
+
+public interface PersonRepository extends KeyValueRepository {
+
+ List findAll();
+}
diff --git a/2021-08/spring-13/spring-data-mongo-class-work/pom.xml b/2021-08/spring-13/spring-data-mongo-class-work/pom.xml
new file mode 100644
index 00000000..a13c15b7
--- /dev/null
+++ b/2021-08/spring-13/spring-data-mongo-class-work/pom.xml
@@ -0,0 +1,17 @@
+
+
+ 4.0.0
+
+ ru.otus
+ spring-data-mongo-class-work
+ 1.0
+
+ pom
+
+
+ spring-data-mongo-exercise
+ spring-data-mongo-solution
+
+
diff --git a/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-exercise/pom.xml b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-exercise/pom.xml
new file mode 100644
index 00000000..5cb9d0e1
--- /dev/null
+++ b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-exercise/pom.xml
@@ -0,0 +1,46 @@
+
+
+ 4.0.0
+
+ ru.otus
+ spring-data-mongo-exercise
+ 1.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.3.4.RELEASE
+
+
+
+
+ 11
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb
+
+
+ de.flapdoodle.embed
+ de.flapdoodle.embed.mongo
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-exercise/src/main/java/ru/otus/spring/Main.java b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-exercise/src/main/java/ru/otus/spring/Main.java
new file mode 100644
index 00000000..d67d7972
--- /dev/null
+++ b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-exercise/src/main/java/ru/otus/spring/Main.java
@@ -0,0 +1,31 @@
+package ru.otus.spring;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.ApplicationContext;
+import ru.otus.spring.domain.Person;
+import ru.otus.spring.repostory.PersonRepository;
+
+@SpringBootApplication
+public class Main {
+
+ @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
+ @Autowired
+ private PersonRepository repository;
+
+ public static void main(String[] args) throws InterruptedException {
+ ApplicationContext context = SpringApplication.run(Main.class);
+
+ PersonRepository repository = context.getBean(PersonRepository.class);
+
+ repository.save(new Person("Dostoevsky"));
+
+ Thread.sleep(3000);
+
+ System.out.println("\n\n\n----------------------------------------------\n\n");
+ System.out.println("Авторы в БД:");
+ repository.findAll().forEach(p -> System.out.println(p.getName()));
+ System.out.println("\n\n----------------------------------------------\n\n\n");
+ }
+}
diff --git a/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-exercise/src/main/java/ru/otus/spring/domain/Person.java b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-exercise/src/main/java/ru/otus/spring/domain/Person.java
new file mode 100644
index 00000000..2bdc3894
--- /dev/null
+++ b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-exercise/src/main/java/ru/otus/spring/domain/Person.java
@@ -0,0 +1,27 @@
+package ru.otus.spring.domain;
+
+public class Person {
+
+ private String id;
+ private String name;
+
+ public Person(String name) {
+ this.name = name;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-exercise/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-exercise/src/main/java/ru/otus/spring/repostory/PersonRepository.java
new file mode 100644
index 00000000..763a2288
--- /dev/null
+++ b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-exercise/src/main/java/ru/otus/spring/repostory/PersonRepository.java
@@ -0,0 +1,12 @@
+package ru.otus.spring.repostory;
+
+import org.springframework.data.repository.CrudRepository;
+import ru.otus.spring.domain.Person;
+
+import java.util.List;
+
+
+public interface PersonRepository extends CrudRepository {
+
+ List findAll();
+}
diff --git a/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-exercise/src/main/resources/application.yml b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-exercise/src/main/resources/application.yml
new file mode 100644
index 00000000..9bffd5dc
--- /dev/null
+++ b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-exercise/src/main/resources/application.yml
@@ -0,0 +1,4 @@
+spring:
+ data:
+ mongodb:
+ database: company
diff --git a/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-solution/pom.xml b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-solution/pom.xml
new file mode 100644
index 00000000..6045db5d
--- /dev/null
+++ b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-solution/pom.xml
@@ -0,0 +1,61 @@
+
+
+ 4.0.0
+
+ ru.otus
+ spring-data-mongo-solution
+ 1.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.3.4.RELEASE
+
+
+
+
+ 11
+ 11
+ 4.1.17
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb
+
+
+ de.flapdoodle.embed
+ de.flapdoodle.embed.mongo
+
+
+
+ com.github.cloudyrock.mongock
+ mongock-spring-v5
+ ${mongock.version}
+
+
+
+ com.github.cloudyrock.mongock
+ mongodb-springdata-v3-driver
+ ${mongock.version}
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-solution/src/main/java/ru/otus/spring/Main.java b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-solution/src/main/java/ru/otus/spring/Main.java
new file mode 100644
index 00000000..fb0e8a60
--- /dev/null
+++ b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-solution/src/main/java/ru/otus/spring/Main.java
@@ -0,0 +1,35 @@
+package ru.otus.spring;
+
+import com.github.cloudyrock.spring.v5.EnableMongock;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.ApplicationContext;
+import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
+import ru.otus.spring.domain.Person;
+import ru.otus.spring.repostory.PersonRepository;
+
+@EnableMongock
+@EnableMongoRepositories
+@SpringBootApplication
+public class Main {
+
+ @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
+ @Autowired
+ private PersonRepository repository;
+
+ public static void main(String[] args) throws InterruptedException {
+ ApplicationContext context = SpringApplication.run(Main.class);
+
+ PersonRepository repository = context.getBean(PersonRepository.class);
+
+ repository.save(new Person("Dostoevsky"));
+
+ Thread.sleep(3000);
+
+ System.out.println("\n\n\n----------------------------------------------\n\n");
+ System.out.println("Авторы в БД:");
+ repository.findAll().forEach(p -> System.out.println(p.getName()));
+ System.out.println("\n\n----------------------------------------------\n\n\n");
+ }
+}
diff --git a/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-solution/src/main/java/ru/otus/spring/domain/Person.java b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-solution/src/main/java/ru/otus/spring/domain/Person.java
new file mode 100644
index 00000000..12cf6355
--- /dev/null
+++ b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-solution/src/main/java/ru/otus/spring/domain/Person.java
@@ -0,0 +1,32 @@
+package ru.otus.spring.domain;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+@Document(collection = "persons")
+public class Person {
+
+ @Id
+ private String id;
+ private String name;
+
+ public Person(String name) {
+ this.name = name;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-solution/src/main/java/ru/otus/spring/mongock/changelog/DatabaseChangelog.java b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-solution/src/main/java/ru/otus/spring/mongock/changelog/DatabaseChangelog.java
new file mode 100644
index 00000000..f9226e50
--- /dev/null
+++ b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-solution/src/main/java/ru/otus/spring/mongock/changelog/DatabaseChangelog.java
@@ -0,0 +1,30 @@
+package ru.otus.spring.mongock.changelog;
+
+import com.github.cloudyrock.mongock.ChangeLog;
+import com.github.cloudyrock.mongock.ChangeSet;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoDatabase;
+import org.bson.Document;
+import ru.otus.spring.domain.Person;
+import ru.otus.spring.repostory.PersonRepository;
+
+@ChangeLog
+public class DatabaseChangelog {
+
+ @ChangeSet(order = "001", id = "dropDb", author = "stvort", runAlways = true)
+ public void dropDb(MongoDatabase db) {
+ db.drop();
+ }
+
+ @ChangeSet(order = "002", id = "insertLermontov", author = "ydvorzhetskiy")
+ public void insertLermontov(MongoDatabase db) {
+ MongoCollection myCollection = db.getCollection("persons");
+ var doc = new Document().append("name", "Lermontov");
+ myCollection.insertOne(doc);
+ }
+
+ @ChangeSet(order = "003", id = "insertPushkin", author = "stvort")
+ public void insertPushkin(PersonRepository repository) {
+ repository.save(new Person("Pushkin"));
+ }
+}
diff --git a/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-solution/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-solution/src/main/java/ru/otus/spring/repostory/PersonRepository.java
new file mode 100644
index 00000000..763a2288
--- /dev/null
+++ b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-solution/src/main/java/ru/otus/spring/repostory/PersonRepository.java
@@ -0,0 +1,12 @@
+package ru.otus.spring.repostory;
+
+import org.springframework.data.repository.CrudRepository;
+import ru.otus.spring.domain.Person;
+
+import java.util.List;
+
+
+public interface PersonRepository extends CrudRepository {
+
+ List findAll();
+}
diff --git a/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-solution/src/main/resources/application.yml b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-solution/src/main/resources/application.yml
new file mode 100644
index 00000000..dd00fa36
--- /dev/null
+++ b/2021-08/spring-13/spring-data-mongo-class-work/spring-data-mongo-solution/src/main/resources/application.yml
@@ -0,0 +1,10 @@
+spring:
+ data:
+ mongodb:
+ database: company
+
+mongock:
+ runner-type: "ApplicationRunner" # default
+ #runner-type: "InitializingBean"
+ change-logs-scan-package:
+ - ru.otus.spring.mongock.changelog
diff --git a/examples/mongo-db-demo-new-mongock/pom.xml b/examples/mongo-db-demo-new-mongock/pom.xml
index caf06c09..2a412312 100644
--- a/examples/mongo-db-demo-new-mongock/pom.xml
+++ b/examples/mongo-db-demo-new-mongock/pom.xml
@@ -6,7 +6,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.5.2
+ 2.5.5
diff --git a/examples/mongo-db-demo-new-mongock/src/main/resources/application.yml b/examples/mongo-db-demo-new-mongock/src/main/resources/application.yml
index 4d338124..08779f76 100644
--- a/examples/mongo-db-demo-new-mongock/src/main/resources/application.yml
+++ b/examples/mongo-db-demo-new-mongock/src/main/resources/application.yml
@@ -1,9 +1,20 @@
spring:
data:
mongodb:
- uri: mongodb://localhost
+ host: localhost
port: 27017
database: awesomeMongo
+
+mongock:
+ runner-type: "ApplicationRunner" # default
+ #runner-type: "InitializingBean"
+ change-logs-scan-package:
+ - ru.otus.example.mongodbdemo.changelogs
+ mongo-db:
+ write-concern:
+ journal: false
+ read-concern: local
+
logging:
level:
root: ERROR
\ No newline at end of file