diff --git a/2020-02/spring-16/spring-mvc-view-classwork/spring-mvc-view-solution/pom.xml b/2020-02/spring-16/spring-mvc-view-classwork/spring-mvc-view-solution/pom.xml
index 436a2a0a..4f560553 100644
--- a/2020-02/spring-16/spring-mvc-view-classwork/spring-mvc-view-solution/pom.xml
+++ b/2020-02/spring-16/spring-mvc-view-classwork/spring-mvc-view-solution/pom.xml
@@ -30,6 +30,11 @@
spring-boot-starter-web
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
org.springframework.boot
spring-boot-starter-thymeleaf
diff --git a/2020-02/spring-16/spring-mvc-view-classwork/spring-mvc-view-solution/src/test/java/ru/otus/spring/rest/PersonControllerTest.java b/2020-02/spring-16/spring-mvc-view-classwork/spring-mvc-view-solution/src/test/java/ru/otus/spring/rest/PersonControllerTest.java
new file mode 100644
index 00000000..71f42162
--- /dev/null
+++ b/2020-02/spring-16/spring-mvc-view-classwork/spring-mvc-view-solution/src/test/java/ru/otus/spring/rest/PersonControllerTest.java
@@ -0,0 +1,17 @@
+package ru.otus.spring.rest;
+
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+@WebMvcTest
+@ExtendWith(SpringExtension.class)
+class PersonControllerTest {
+
+ @org.junit.jupiter.api.Test
+ void listPage() {
+ }
+}
\ No newline at end of file
diff --git a/2020-05/spring-09-jpql/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2020-05/spring-09-jpql/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
index f3822503..891e945a 100644
--- a/2020-05/spring-09-jpql/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
+++ b/2020-05/spring-09-jpql/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
@@ -1,6 +1,8 @@
package ru.otus.example.ormdemo.models;
import lombok.*;
+import org.hibernate.annotations.Fetch;
+import org.hibernate.annotations.FetchMode;
import javax.persistence.*;
import java.util.List;
@@ -10,6 +12,8 @@ import java.util.List;
@AllArgsConstructor
@Entity // Указывает, что данный класс является сущностью
@Table(name = "otus_students") // Задает имя таблицы, на которую будет отображаться сущность
+@NamedEntityGraph(name = "otus-student-avatars-entity-graph",
+ attributeNodes = {@NamedAttributeNode("avatar")})
public class OtusStudent {
@Id // Позволяет указать какое поле является идентификатором
@GeneratedValue(strategy = GenerationType.IDENTITY) // Стратегия генерации идентификаторов
@@ -30,6 +34,7 @@ public class OtusStudent {
@JoinColumn(name = "student_id")
private List emails;
+ @Fetch(FetchMode.SUBSELECT)
// Указывает на связь между таблицами "многие ко многим"
@ManyToMany(targetEntity = Course.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
// Задает таблицу связей между таблицами для хранения родительской и связанной сущностью
diff --git a/2020-05/spring-09-jpql/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImpl.java b/2020-05/spring-09-jpql/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImpl.java
index 5baca1e7..442d6e24 100644
--- a/2020-05/spring-09-jpql/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImpl.java
+++ b/2020-05/spring-09-jpql/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImpl.java
@@ -4,10 +4,7 @@ import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import ru.otus.example.ormdemo.models.OtusStudent;
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import javax.persistence.Query;
-import javax.persistence.TypedQuery;
+import javax.persistence.*;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
@@ -26,31 +23,55 @@ public class OtusStudentRepositoryJpaImpl implements OtusStudentRepositoryJpa {
@Override
public OtusStudent save(OtusStudent student) {
- return null;
+ if (student.getId() == 0) {
+ Query query = em.createQuery("insert into OtusStudent (name) " +
+ "select :name from OtusStudent s");
+ query.setParameter("name", student.getName());
+ query.executeUpdate();
+ return student;
+ } else {
+ return em.merge(student);
+ }
}
@Override
- public Optional findById(long id) {
- return Optional.empty();
+ public Optional findById (long id) {
+ return Optional.ofNullable(em.find(OtusStudent.class, id));
}
@Override
public List findAll() {
- return Collections.emptyList();
+ EntityGraph> entityGraph = em.getEntityGraph("otus-student-avatars-entity-graph");
+ TypedQuery query = em.createQuery("select s from OtusStudent s join fetch s.emails", OtusStudent.class);
+ query.setHint("javax.persistence.fetchgraph", entityGraph);
+ return query.getResultList();
}
@Override
public List findByName(String name) {
- return Collections.emptyList();
+ TypedQuery query = em.createQuery
+ ("select s from OtusStudent s where s.name = :name", OtusStudent.class);
+ query.setParameter("name", name);
+ return query.getResultList();
}
@Override
public void updateNameById(long id, String name) {
-
+ Query query = em.createQuery("update OtusStudent s " +
+ "set s.name = :name " +
+ "where s.id = :id");
+ query.setParameter("name", name);
+ query.setParameter("id", id);
+ query.executeUpdate();
}
@Override
public void deleteById(long id) {
+ Query query = em.createQuery("delete " +
+ "from OtusStudent s " +
+ "where s.id = :id");
+ query.setParameter("id", id);
+ query.executeUpdate();
}
}
diff --git a/2020-05/spring-09-jpql/jpql-class-work/jpql-exercise/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java b/2020-05/spring-09-jpql/jpql-class-work/jpql-exercise/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java
index 9cad9ee7..818a1fe8 100644
--- a/2020-05/spring-09-jpql/jpql-class-work/jpql-exercise/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java
+++ b/2020-05/spring-09-jpql/jpql-class-work/jpql-exercise/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java
@@ -27,7 +27,7 @@ class OtusStudentRepositoryJpaImplTest {
private static final long FIRST_STUDENT_ID = 1L;
private static final String FIRST_STUDENT_NAME = "student_01";
- private static final int EXPECTED_QUERIES_COUNT = 31;
+ private static final int EXPECTED_QUERIES_COUNT = 2;
private static final String STUDENT_AVATAR_URL = "где-то там";
private static final String STUDENT_EMAIL = "any@mail.com";
@@ -43,6 +43,7 @@ class OtusStudentRepositoryJpaImplTest {
@DisplayName(" должен загружать информацию о нужном студенте по его id")
@Test
void shouldFindExpectedStudentById() {
+
val optionalActualStudent = repositoryJpa.findById(FIRST_STUDENT_ID);
val expectedStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
assertThat(optionalActualStudent).isPresent().get()
diff --git a/2020-05/spring-09-jpql/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2020-05/spring-09-jpql/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
index ecdbf955..44bbbb98 100644
--- a/2020-05/spring-09-jpql/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
+++ b/2020-05/spring-09-jpql/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
@@ -37,8 +37,6 @@ public class OtusStudent {
@JoinColumn(name = "student_id")
private List emails;
- @Fetch(FetchMode.SELECT)
- @BatchSize(size = 5)
// Указывает на связь между таблицами "многие ко многим"
@ManyToMany(targetEntity = Course.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
// Задает таблицу связей между таблицами для хранения родительской и связанной сущностью
diff --git a/2020-05/spring-09-jpql/jpql-class-work/jpql-solution-final/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java b/2020-05/spring-09-jpql/jpql-class-work/jpql-solution-final/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java
index e2992ba0..a8e57fe3 100644
--- a/2020-05/spring-09-jpql/jpql-class-work/jpql-solution-final/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java
+++ b/2020-05/spring-09-jpql/jpql-class-work/jpql-solution-final/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java
@@ -47,6 +47,8 @@ class OtusStudentRepositoryJpaImplTest {
System.out.println("\n\n\n\n----------------------------------------------------------------------------------------------------------");
val students = repositoryJpa.findAll();
+ val student = repositoryJpa.findById(1L);
+
assertThat(students).isNotNull().hasSize(EXPECTED_NUMBER_OF_STUDENTS)
.allMatch(s -> !s.getName().equals(""))
.allMatch(s -> s.getCourses() != null && s.getCourses().size() > 0)
diff --git a/2020-05/spring-09-jpql/jpql-demo/src/test/java/ru/otus/example/jpql_demo/repositories/EmployeeRepositoryImplTest.java b/2020-05/spring-09-jpql/jpql-demo/src/test/java/ru/otus/example/jpql_demo/repositories/EmployeeRepositoryImplTest.java
index bf6c0b26..7f4055c8 100644
--- a/2020-05/spring-09-jpql/jpql-demo/src/test/java/ru/otus/example/jpql_demo/repositories/EmployeeRepositoryImplTest.java
+++ b/2020-05/spring-09-jpql/jpql-demo/src/test/java/ru/otus/example/jpql_demo/repositories/EmployeeRepositoryImplTest.java
@@ -257,6 +257,7 @@ class EmployeeRepositoryImplTest {
BigDecimal newSalary = oldSalary.multiply(new BigDecimal(2));
em.detach(employee3);
employeeRepository.doubleEmployeesSalary(oldSalary);
+ //em.refresh(employee3);
employee3 = em.find(Employee.class, THIRD_EMPLOYEE_ID);
assertThat(employee3.getSalary()).isEqualTo(newSalary);
@@ -271,7 +272,7 @@ class EmployeeRepositoryImplTest {
assertThat(employee8).isNotNull();
employeeRepository.deleteEmployeesWithoutDepartment();
- em.clear();
+ em.flush();
employee2 = em.find(Employee.class, SECOND_EMPLOYEE_ID);
employee8 = em.find(Employee.class, EIGTH_EMPLOYEE_ID);
diff --git a/examples/mongo-db-demo-new-mongock/.gitignore b/examples/mongo-db-demo-new-mongock/.gitignore
new file mode 100644
index 00000000..153c9335
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/.gitignore
@@ -0,0 +1,29 @@
+HELP.md
+/target/
+!.mvn/wrapper/maven-wrapper.jar
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+/build/
+
+### VS Code ###
+.vscode/
diff --git a/examples/mongo-db-demo-new-mongock/README.md b/examples/mongo-db-demo-new-mongock/README.md
new file mode 100644
index 00000000..84065306
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/README.md
@@ -0,0 +1,7 @@
+## Пример работы с MongoDB
+
+В примере демонстрируется:
+* *два подхода к хранению вложенных сущностей*
+* *инициализация базы данными с помощью инструмента миграций Mongock*
+* *использование AbstractMongoEventListener для выполнения каскадных операций*
+* *работа с массивами с помощью агрегаций и Criteria api*
diff --git a/examples/mongo-db-demo-new-mongock/pom.xml b/examples/mongo-db-demo-new-mongock/pom.xml
new file mode 100644
index 00000000..3cb9852b
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/pom.xml
@@ -0,0 +1,130 @@
+
+
+ 4.0.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.3.1.RELEASE
+
+
+
+ ru.otus.example
+ mongo-db-demo
+ 0.0.1-SNAPSHOT
+ mongo-db-demo
+ Demo project for MongoDB
+
+
+ 11
+ 11
+ 11
+ 4.1.2.BETA
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb
+
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+
+ com.github.cloudyrock.mongock
+ mongock-spring-v5
+ ${mongock.version}
+
+
+
+ com.github.cloudyrock.mongock
+ mongodb-springdata-v3-driver
+ ${mongock.version}
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit-jupiter.version}
+ test
+
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${junit-jupiter.version}
+ test
+
+
+
+ org.junit.jupiter
+ junit-jupiter-params
+ ${junit-jupiter.version}
+ test
+
+
+
+ org.mockito
+ mockito-core
+ ${mockito.version}
+ test
+
+
+
+ org.mockito
+ mockito-junit-jupiter
+ ${mockito.version}
+ test
+
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+
+ de.flapdoodle.embed
+ de.flapdoodle.embed.mongo
+ test
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
+ spring-milestones
+ Spring Milestones
+ https://repo.spring.io/milestone
+
+
+
+
diff --git a/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/MongoDbDemoApplication.java b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/MongoDbDemoApplication.java
new file mode 100644
index 00000000..4b26baf5
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/MongoDbDemoApplication.java
@@ -0,0 +1,16 @@
+package ru.otus.example.mongodbdemo;
+
+import com.github.cloudyrock.spring.v5.EnableMongock;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+
+@EnableMongock
+@SpringBootApplication
+@EnableConfigurationProperties
+public class MongoDbDemoApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MongoDbDemoApplication.class, args);
+ }
+}
diff --git a/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/changelogs/InitMongoDBDataChangeLog.java b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/changelogs/InitMongoDBDataChangeLog.java
new file mode 100644
index 00000000..d8cd7f29
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/changelogs/InitMongoDBDataChangeLog.java
@@ -0,0 +1,43 @@
+package ru.otus.example.mongodbdemo.changelogs;
+
+import com.github.cloudyrock.mongock.ChangeLog;
+import com.github.cloudyrock.mongock.ChangeSet;
+import com.mongodb.client.MongoDatabase;
+import lombok.val;
+import ru.otus.example.mongodbdemo.model.Knowledge;
+import ru.otus.example.mongodbdemo.model.Student;
+import ru.otus.example.mongodbdemo.model.Teacher;
+import ru.otus.example.mongodbdemo.repositories.KnowledgeRepository;
+import ru.otus.example.mongodbdemo.repositories.StudentRepository;
+import ru.otus.example.mongodbdemo.repositories.TeacherRepository;
+
+@ChangeLog(order = "001")
+public class InitMongoDBDataChangeLog {
+
+ private Knowledge springDataKnowledge;
+ private Knowledge mongockKnowledge;
+ private Knowledge aggregationApiKnowledge;
+
+ @ChangeSet(order = "000", id = "dropDB", author = "stvort", runAlways = true)
+ public void dropDB(MongoDatabase database){
+ database.drop();
+ }
+
+ @ChangeSet(order = "001", id = "initKnowledges", author = "stvort", runAlways = true)
+ public void initKnowledges(KnowledgeRepository repository){
+ springDataKnowledge = repository.save(new Knowledge("Spring Data"));
+ mongockKnowledge = repository.save(new Knowledge("Mongock"));
+ aggregationApiKnowledge = repository.save(new Knowledge("AggregationApi"));
+ }
+
+ @ChangeSet(order = "002", id = "initStudents", author = "stvort", runAlways = true)
+ public void initStudents(StudentRepository repository){
+ repository.save(new Student("Student #1", springDataKnowledge, mongockKnowledge));
+ }
+
+ @ChangeSet(order = "003", id = "Teacher", author = "stvort", runAlways = true)
+ public void initTeachers(TeacherRepository repository){
+ val teacher = new Teacher("Teacher #1", springDataKnowledge, mongockKnowledge, aggregationApiKnowledge);
+ repository.save(teacher);
+ }
+}
diff --git a/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/events/MongoKnowledgeCascadeDeleteEventsListener.java b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/events/MongoKnowledgeCascadeDeleteEventsListener.java
new file mode 100644
index 00000000..08f6c601
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/events/MongoKnowledgeCascadeDeleteEventsListener.java
@@ -0,0 +1,24 @@
+package ru.otus.example.mongodbdemo.events;
+
+import lombok.RequiredArgsConstructor;
+import lombok.val;
+import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
+import org.springframework.data.mongodb.core.mapping.event.AfterDeleteEvent;
+import org.springframework.stereotype.Component;
+import ru.otus.example.mongodbdemo.model.Knowledge;
+import ru.otus.example.mongodbdemo.repositories.StudentRepository;
+
+@Component
+@RequiredArgsConstructor
+public class MongoKnowledgeCascadeDeleteEventsListener extends AbstractMongoEventListener {
+
+ private final StudentRepository studentRepository;
+
+ @Override
+ public void onAfterDelete(AfterDeleteEvent event) {
+ super.onAfterDelete(event);
+ val source = event.getSource();
+ val id = source.get("_id").toString();
+ studentRepository.removeExperienceArrayElementsById(id);
+ }
+}
diff --git a/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/events/MongoStudentCascadeSaveEventsListener.java b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/events/MongoStudentCascadeSaveEventsListener.java
new file mode 100644
index 00000000..89ff7d97
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/events/MongoStudentCascadeSaveEventsListener.java
@@ -0,0 +1,27 @@
+package ru.otus.example.mongodbdemo.events;
+
+import lombok.RequiredArgsConstructor;
+import lombok.val;
+import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
+import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
+import org.springframework.stereotype.Component;
+import ru.otus.example.mongodbdemo.model.Student;
+import ru.otus.example.mongodbdemo.repositories.KnowledgeRepository;
+
+import java.util.Objects;
+
+@Component
+@RequiredArgsConstructor
+public class MongoStudentCascadeSaveEventsListener extends AbstractMongoEventListener {
+
+ private final KnowledgeRepository knowledgeRepository;
+
+ @Override
+ public void onBeforeConvert(BeforeConvertEvent event) {
+ super.onBeforeConvert(event);
+ val student = event.getSource();
+ if (student.getExperience() != null) {
+ student.getExperience().stream().filter(e -> Objects.isNull(e.getId())).forEach(knowledgeRepository::save);
+ }
+ }
+}
diff --git a/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/model/Knowledge.java b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/model/Knowledge.java
new file mode 100644
index 00000000..04583a57
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/model/Knowledge.java
@@ -0,0 +1,21 @@
+package ru.otus.example.mongodbdemo.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Document
+public class Knowledge {
+ @Id
+ private String id;
+ private String name;
+
+ public Knowledge(String name) {
+ this.name = name;
+ }
+}
diff --git a/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/model/Student.java b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/model/Student.java
new file mode 100644
index 00000000..bf228359
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/model/Student.java
@@ -0,0 +1,29 @@
+package ru.otus.example.mongodbdemo.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.DBRef;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.util.Arrays;
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Document
+public class Student {
+ @Id
+ private String id;
+ private String name;
+
+ @DBRef
+ private List experience;
+
+ public Student(String name, Knowledge... experience) {
+ this.name = name;
+ this.experience = Arrays.asList(experience);
+ }
+}
diff --git a/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/model/Teacher.java b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/model/Teacher.java
new file mode 100644
index 00000000..aa8e1166
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/model/Teacher.java
@@ -0,0 +1,28 @@
+package ru.otus.example.mongodbdemo.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.util.Arrays;
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Document
+public class Teacher {
+ @Id
+ private String id;
+ private String name;
+
+ private List experience;
+
+ public Teacher(String name, Knowledge... experience) {
+ this.name = name;
+ this.experience = Arrays.asList(experience);
+
+ }
+}
diff --git a/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/KnowledgeRepository.java b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/KnowledgeRepository.java
new file mode 100644
index 00000000..c8605cb4
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/KnowledgeRepository.java
@@ -0,0 +1,7 @@
+package ru.otus.example.mongodbdemo.repositories;
+
+import org.springframework.data.mongodb.repository.MongoRepository;
+import ru.otus.example.mongodbdemo.model.Knowledge;
+
+public interface KnowledgeRepository extends MongoRepository {
+}
diff --git a/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/StudentRepository.java b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/StudentRepository.java
new file mode 100644
index 00000000..bc603fe5
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/StudentRepository.java
@@ -0,0 +1,8 @@
+package ru.otus.example.mongodbdemo.repositories;
+
+import org.springframework.data.mongodb.repository.MongoRepository;
+import ru.otus.example.mongodbdemo.model.Student;
+
+
+public interface StudentRepository extends MongoRepository, StudentRepositoryCustom {
+}
diff --git a/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/StudentRepositoryCustom.java b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/StudentRepositoryCustom.java
new file mode 100644
index 00000000..8b902bbf
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/StudentRepositoryCustom.java
@@ -0,0 +1,12 @@
+package ru.otus.example.mongodbdemo.repositories;
+
+import ru.otus.example.mongodbdemo.model.Knowledge;
+
+import java.util.List;
+
+public interface StudentRepositoryCustom {
+ List getStudentExperienceById(String studentId);
+
+ long getExperienceArrayLengthByStudentId(String id);
+ void removeExperienceArrayElementsById(String id);
+}
diff --git a/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/StudentRepositoryCustomImpl.java b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/StudentRepositoryCustomImpl.java
new file mode 100644
index 00000000..91fb3536
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/StudentRepositoryCustomImpl.java
@@ -0,0 +1,69 @@
+package ru.otus.example.mongodbdemo.repositories;
+
+import lombok.Data;
+import lombok.RequiredArgsConstructor;
+import lombok.val;
+import org.bson.Document;
+import org.bson.types.ObjectId;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.aggregation.Aggregation;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.core.query.Update;
+import ru.otus.example.mongodbdemo.model.Knowledge;
+import ru.otus.example.mongodbdemo.model.Student;
+import ru.otus.example.mongodbdemo.utils.RawResultPrinter;
+
+
+import java.util.List;
+
+import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
+import static org.springframework.data.mongodb.core.aggregation.ObjectOperators.ObjectToArray.valueOfToArray;
+import static org.springframework.data.mongodb.core.query.Criteria.where;
+
+@RequiredArgsConstructor
+public class StudentRepositoryCustomImpl implements StudentRepositoryCustom {
+
+ @Data
+ private class ArraySizeProjection {
+ private int size;
+ }
+
+ private final MongoTemplate mongoTemplate;
+ private final RawResultPrinter rawResultPrinter;
+
+ @Override
+ public List getStudentExperienceById(String studentId) {
+ Aggregation aggregation = newAggregation(
+ match(Criteria.where("id").is(studentId))
+ , unwind("experience")
+ , project().andExclude("_id").and(valueOfToArray("experience")).as("experience_map")
+ , project().and("experience_map").arrayElementAt(1).as("experience_id_map")
+ , project().and("experience_id_map.v").as("experience_id")
+ , lookup("knowledge", "experience_id", "_id", "experience")
+ , project().and("experience._id").as("_id").and("experience.name").as("name")
+ );
+
+ Document rawResults = mongoTemplate.aggregate(aggregation, Student.class, Knowledge.class).getRawResults();
+ rawResultPrinter.prettyPrintRawResult(rawResults);
+ return mongoTemplate.aggregate(aggregation, Student.class, Knowledge.class).getMappedResults();
+ }
+
+ @Override
+ public long getExperienceArrayLengthByStudentId(String studentId) {
+ val aggregation = Aggregation.newAggregation(
+ match(where("id").is(studentId)),
+ project().andExclude("_id").and("experience").size().as("size"));
+
+ val arraySizeProjection = mongoTemplate.aggregate(aggregation, Student.class, ArraySizeProjection.class).getUniqueMappedResult();
+ return arraySizeProjection == null ? 0 : arraySizeProjection.getSize();
+ }
+
+ @Override
+ public void removeExperienceArrayElementsById(String id) {
+ val query = Query.query(Criteria.where("$id").is(new ObjectId(id)));
+ val update = new Update().pull("experience", query);
+ mongoTemplate.updateMulti(new Query(), update, Student.class);
+ }
+
+}
diff --git a/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/TeacherRepository.java b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/TeacherRepository.java
new file mode 100644
index 00000000..b75c5200
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/TeacherRepository.java
@@ -0,0 +1,7 @@
+package ru.otus.example.mongodbdemo.repositories;
+
+import org.springframework.data.mongodb.repository.MongoRepository;
+import ru.otus.example.mongodbdemo.model.Teacher;
+
+public interface TeacherRepository extends MongoRepository, TeacherRepositoryCustom {
+}
diff --git a/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/TeacherRepositoryCustom.java b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/TeacherRepositoryCustom.java
new file mode 100644
index 00000000..adfd9acb
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/TeacherRepositoryCustom.java
@@ -0,0 +1,9 @@
+package ru.otus.example.mongodbdemo.repositories;
+
+import ru.otus.example.mongodbdemo.model.Knowledge;
+
+import java.util.List;
+
+public interface TeacherRepositoryCustom {
+ List getTeacherExperienceById(String teacherId);
+}
diff --git a/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/TeacherRepositoryCustomImpl.java b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/TeacherRepositoryCustomImpl.java
new file mode 100644
index 00000000..d529928d
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/repositories/TeacherRepositoryCustomImpl.java
@@ -0,0 +1,28 @@
+package ru.otus.example.mongodbdemo.repositories;
+
+import lombok.RequiredArgsConstructor;
+import lombok.val;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import ru.otus.example.mongodbdemo.model.Knowledge;
+import ru.otus.example.mongodbdemo.model.Teacher;
+
+import java.util.List;
+
+import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
+
+@RequiredArgsConstructor
+public class TeacherRepositoryCustomImpl implements TeacherRepositoryCustom {
+
+ private final MongoTemplate mongoTemplate;
+
+ @Override
+ public List getTeacherExperienceById(String teacherId) {
+ val aggregation = newAggregation(
+ match(Criteria.where("id").is(teacherId))
+ , unwind("experience")
+ , project().andExclude("_id").and("experience.id").as("_id").and("experience.name").as("name")
+ );
+ return mongoTemplate.aggregate(aggregation, Teacher.class, Knowledge.class).getMappedResults();
+ }
+}
diff --git a/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/utils/RawResultPrinter.java b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/utils/RawResultPrinter.java
new file mode 100644
index 00000000..e033d42d
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/utils/RawResultPrinter.java
@@ -0,0 +1,8 @@
+package ru.otus.example.mongodbdemo.utils;
+
+import org.bson.Document;
+
+public interface RawResultPrinter {
+ @SuppressWarnings("unchecked")
+ void prettyPrintRawResult(Document document);
+}
diff --git a/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/utils/RawResultPrinterImpl.java b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/utils/RawResultPrinterImpl.java
new file mode 100644
index 00000000..1fcd9a7c
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/main/java/ru/otus/example/mongodbdemo/utils/RawResultPrinterImpl.java
@@ -0,0 +1,18 @@
+package ru.otus.example.mongodbdemo.utils;
+
+import org.bson.Document;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Component
+public class RawResultPrinterImpl implements RawResultPrinter {
+ @SuppressWarnings("unchecked")
+ @Override
+ public void prettyPrintRawResult(Document document) {
+ List results = (List) document.get("results");
+ String resultsAsString = results.stream().map(Document::toString).collect(Collectors.joining("\n"));
+ System.out.println(resultsAsString);
+ }
+}
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
new file mode 100644
index 00000000..4d338124
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/main/resources/application.yml
@@ -0,0 +1,9 @@
+spring:
+ data:
+ mongodb:
+ uri: mongodb://localhost
+ port: 27017
+ database: awesomeMongo
+logging:
+ level:
+ root: ERROR
\ No newline at end of file
diff --git a/examples/mongo-db-demo-new-mongock/src/test/java/ru/otus/example/mongodbdemo/repositories/AbstractRepositoryTest.java b/examples/mongo-db-demo-new-mongock/src/test/java/ru/otus/example/mongodbdemo/repositories/AbstractRepositoryTest.java
new file mode 100644
index 00000000..f1342168
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/test/java/ru/otus/example/mongodbdemo/repositories/AbstractRepositoryTest.java
@@ -0,0 +1,14 @@
+package ru.otus.example.mongodbdemo.repositories;
+
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Import;
+import ru.otus.example.mongodbdemo.utils.RawResultPrinterImpl;
+
+@DataMongoTest
+@EnableConfigurationProperties
+@ComponentScan({"ru.otus.example.mongodbdemo.config", "ru.otus.example.mongodbdemo.repositories"})
+@Import(RawResultPrinterImpl.class)
+public abstract class AbstractRepositoryTest {
+}
diff --git a/examples/mongo-db-demo-new-mongock/src/test/java/ru/otus/example/mongodbdemo/repositories/TeacherRepositoryTest.java b/examples/mongo-db-demo-new-mongock/src/test/java/ru/otus/example/mongodbdemo/repositories/TeacherRepositoryTest.java
new file mode 100644
index 00000000..f6fd8713
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/test/java/ru/otus/example/mongodbdemo/repositories/TeacherRepositoryTest.java
@@ -0,0 +1,29 @@
+package ru.otus.example.mongodbdemo.repositories;
+
+import lombok.val;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import ru.otus.example.mongodbdemo.model.Knowledge;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@DisplayName("TeacherRepository должен ")
+class TeacherRepositoryTest extends AbstractRepositoryTest {
+
+ @Autowired
+ private TeacherRepository teacherRepository;
+
+ @DisplayName(" возвращать корректный список знаний преподавателя")
+ @Test
+ void shouldReturnCorrectKnowledgeList(){
+ val teachers = teacherRepository.findAll();
+ val teacher = teachers.get(0);
+ val experience = teacher.getExperience();
+ assertThat(experience).isNotNull().hasSize(3);
+
+ val actualExperience = teacherRepository.getTeacherExperienceById(teacher.getId());
+ assertThat(actualExperience).containsExactlyInAnyOrder(experience.toArray(new Knowledge[0]));
+
+ }
+}
diff --git a/examples/mongo-db-demo-new-mongock/src/test/java/ru/otus/example/mongodbdemo/repositories/plain/KnowledgeRepositoryWithoutListenerTest.java b/examples/mongo-db-demo-new-mongock/src/test/java/ru/otus/example/mongodbdemo/repositories/plain/KnowledgeRepositoryWithoutListenerTest.java
new file mode 100644
index 00000000..c68d61d6
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/test/java/ru/otus/example/mongodbdemo/repositories/plain/KnowledgeRepositoryWithoutListenerTest.java
@@ -0,0 +1,58 @@
+package ru.otus.example.mongodbdemo.repositories.plain;
+
+import lombok.val;
+import org.assertj.core.api.AbstractObjectAssert;
+import org.assertj.core.api.AbstractOptionalAssert;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import ru.otus.example.mongodbdemo.model.Knowledge;
+import ru.otus.example.mongodbdemo.model.Student;
+import ru.otus.example.mongodbdemo.repositories.AbstractRepositoryTest;
+import ru.otus.example.mongodbdemo.repositories.KnowledgeRepository;
+import ru.otus.example.mongodbdemo.repositories.StudentRepository;
+
+import java.util.List;
+import java.util.function.Function;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+@DisplayName("KnowledgeRepository при отсутствии listener-ов в контексте ")
+class KnowledgeRepositoryWithoutListenerTest extends AbstractRepositoryTest {
+
+ @Autowired
+ private KnowledgeRepository knowledgeRepository;
+
+ @Autowired
+ private StudentRepository studentRepository;
+
+ @DisplayName("при удалении Knowledge не должен удалять его из опыта студента")
+ @Test
+ void shouldLeaveKnowledgeInStudentExperienceWhenRemovingKnowledge() {
+
+ // Загрузка студента и его первого знания
+ val students = studentRepository.findAll();
+ val student = students.get(0);
+ val experience = student.getExperience();
+ val firstKnowledge = experience.get(0);
+
+ // Удаление знания из коллекции знаний
+ knowledgeRepository.delete(firstKnowledge);
+
+ // Загружаем студента заново и проверяем, что знание действительно удалено (размер стал меньше на 1)
+ val expectedExperienceArrayLength = experience.size() - 1;
+ val actualStudentOptional = studentRepository.findById(student.getId());
+ assertThat(actualStudentOptional)
+ .isNotEmpty().get()
+ .matches(s -> s.getExperience() != null && s.getExperience().size() == expectedExperienceArrayLength);
+
+
+ // Загружаем размер массива с помощью аггрегаций и проверяем, что на самом деле размер массива в БД не изменился
+ val actualExperienceArrayLength = studentRepository.getExperienceArrayLengthByStudentId(student.getId());
+ assertThat(actualExperienceArrayLength).isNotEqualTo(expectedExperienceArrayLength);
+
+
+
+ }
+}
diff --git a/examples/mongo-db-demo-new-mongock/src/test/java/ru/otus/example/mongodbdemo/repositories/plain/StudentRepositoryWithoutListenerTest.java b/examples/mongo-db-demo-new-mongock/src/test/java/ru/otus/example/mongodbdemo/repositories/plain/StudentRepositoryWithoutListenerTest.java
new file mode 100644
index 00000000..c688bcee
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/test/java/ru/otus/example/mongodbdemo/repositories/plain/StudentRepositoryWithoutListenerTest.java
@@ -0,0 +1,27 @@
+package ru.otus.example.mongodbdemo.repositories.plain;
+
+import lombok.val;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mapping.MappingException;
+import ru.otus.example.mongodbdemo.model.Knowledge;
+import ru.otus.example.mongodbdemo.model.Student;
+import ru.otus.example.mongodbdemo.repositories.AbstractRepositoryTest;
+import ru.otus.example.mongodbdemo.repositories.StudentRepository;
+
+import static org.assertj.core.api.Assertions.*;
+
+@DisplayName("StudentRepository при отсутствии listener-ов в контексте ")
+class StudentRepositoryWithoutListenerTest extends AbstractRepositoryTest {
+
+ @Autowired
+ private StudentRepository studentRepository;
+
+ @DisplayName("должен кидать MappingException во время сохранения студента с отсутствующими в БД знаниями")
+ @Test
+ void shouldThrowMappingExceptionWhenSaveStudentWithNewKnowledge(){
+ val student = new Student("Student #2", new Knowledge("Knowledge #3"));
+ assertThatThrownBy(() -> studentRepository.save(student)).isInstanceOf(MappingException.class);
+ }
+}
\ No newline at end of file
diff --git a/examples/mongo-db-demo-new-mongock/src/test/java/ru/otus/example/mongodbdemo/repositories/withlisteners/KnowledgeRepositoryWithListenerTest.java b/examples/mongo-db-demo-new-mongock/src/test/java/ru/otus/example/mongodbdemo/repositories/withlisteners/KnowledgeRepositoryWithListenerTest.java
new file mode 100644
index 00000000..743f3599
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/test/java/ru/otus/example/mongodbdemo/repositories/withlisteners/KnowledgeRepositoryWithListenerTest.java
@@ -0,0 +1,49 @@
+package ru.otus.example.mongodbdemo.repositories.withlisteners;
+
+import lombok.val;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.ComponentScan;
+import ru.otus.example.mongodbdemo.repositories.AbstractRepositoryTest;
+import ru.otus.example.mongodbdemo.repositories.KnowledgeRepository;
+import ru.otus.example.mongodbdemo.repositories.StudentRepository;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@DisplayName("KnowledgeRepository при наличии listener-ов в контексте ")
+@ComponentScan("ru.otus.example.mongodbdemo.events")
+class KnowledgeRepositoryWithListenerTest extends AbstractRepositoryTest {
+
+ @Autowired
+ private KnowledgeRepository knowledgeRepository;
+
+ @Autowired
+ private StudentRepository studentRepository;
+
+ @DisplayName("при удалении Knowledge должен удалить его из опыта студента")
+ @Test
+ void shouldRemoveKnowledgeFromStudentExperienceWhenRemovingKnowledge() {
+
+ // Загрузка студента и его первого знания
+ val students = studentRepository.findAll();
+ val student = students.get(0);
+ val experience = student.getExperience();
+ val firstKnowledge = experience.get(0);
+
+ // Удаление знания из коллекции знаний
+ knowledgeRepository.delete(firstKnowledge);
+
+ // Загружаем студента заново и проверяем, что знание действительно удалено (размер стал меньше на 1)
+ val expectedExperienceArrayLength = experience.size() - 1;
+ val actualStudentOptional = studentRepository.findById(student.getId());
+ assertThat(actualStudentOptional)
+ .isNotEmpty().get()
+ .matches(s -> s.getExperience() != null && s.getExperience().size() == expectedExperienceArrayLength);
+
+ // Загружаем размер массива с помощью аггрегаций и проверяем, что размер массива в БД тоже изменился
+ val actualExperienceArrayLength = studentRepository.getExperienceArrayLengthByStudentId(student.getId());
+ assertThat(actualExperienceArrayLength).isEqualTo(expectedExperienceArrayLength);
+
+ }
+}
diff --git a/examples/mongo-db-demo-new-mongock/src/test/java/ru/otus/example/mongodbdemo/repositories/withlisteners/StudentRepositoryWithListenersTest.java b/examples/mongo-db-demo-new-mongock/src/test/java/ru/otus/example/mongodbdemo/repositories/withlisteners/StudentRepositoryWithListenersTest.java
new file mode 100644
index 00000000..f70740c8
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/test/java/ru/otus/example/mongodbdemo/repositories/withlisteners/StudentRepositoryWithListenersTest.java
@@ -0,0 +1,41 @@
+package ru.otus.example.mongodbdemo.repositories.withlisteners;
+
+import lombok.val;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.ComponentScan;
+import ru.otus.example.mongodbdemo.model.Knowledge;
+import ru.otus.example.mongodbdemo.model.Student;
+import ru.otus.example.mongodbdemo.repositories.AbstractRepositoryTest;
+import ru.otus.example.mongodbdemo.repositories.StudentRepository;
+
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@DisplayName("StudentRepository при наличии listener-ов в контексте ")
+@ComponentScan("ru.otus.example.mongodbdemo.events")
+class StudentRepositoryWithListenersTest extends AbstractRepositoryTest {
+
+ @Autowired
+ private StudentRepository studentRepository;
+
+ @DisplayName("должен корректно сохранять студента с отсутствующими в БД знаниями")
+ @Test
+ void shouldCorrectSaveStudentWithNewKnowledge(){
+ val student = new Student("Student #2", new Knowledge("Knowledge #3"));
+ val actual = studentRepository.save(student);
+ assertThat(actual.getId()).isNotNull();
+ assertThat(actual.getName()).isEqualTo(student.getName());
+ }
+
+ @DisplayName("должен возвращать корректный список знаний студента")
+ @Test
+ void shouldReturnCorrectStudentKnowledgeList(){
+ val student = studentRepository.findAll().get(0);
+ List knowledgeList = studentRepository.getStudentExperienceById(student.getId());
+ assertThat(knowledgeList).containsExactlyInAnyOrderElementsOf(student.getExperience());
+ }
+
+}
diff --git a/examples/mongo-db-demo-new-mongock/src/test/resources/application.yml b/examples/mongo-db-demo-new-mongock/src/test/resources/application.yml
new file mode 100644
index 00000000..737c0712
--- /dev/null
+++ b/examples/mongo-db-demo-new-mongock/src/test/resources/application.yml
@@ -0,0 +1,18 @@
+spring:
+ data:
+ mongodb:
+ port: 0
+ database: test
+ #uri: mongodb://localhost
+ #port: 27017
+ #database: awesomeMongo
+
+
+
+ mongock:
+ change-logs-scan-package:
+ - ru.otus.example.mongodbdemo.changelogs
+
+logging:
+ level:
+ root: ERROR
\ No newline at end of file
diff --git a/examples/mongo-db-demo/pom.xml b/examples/mongo-db-demo/pom.xml
index 76744a32..9c301b94 100644
--- a/examples/mongo-db-demo/pom.xml
+++ b/examples/mongo-db-demo/pom.xml
@@ -6,7 +6,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.2.1.RELEASE
+ 2.2.6.RELEASE
@@ -20,7 +20,7 @@
11
11
11
- 2.0.2
+ 3.2.8