diff --git a/2019-11/spring-08/orm-class-work/.gitignore b/2019-11/spring-08/demo-projects/.gitignore
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/.gitignore
rename to 2019-11/spring-08/demo-projects/.gitignore
diff --git a/2019-11/spring-08/orm-class-work/mybatis-demo/.gitignore b/2019-11/spring-08/demo-projects/mybatis-demo/.gitignore
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/mybatis-demo/.gitignore
rename to 2019-11/spring-08/demo-projects/mybatis-demo/.gitignore
diff --git a/2019-11/spring-08/orm-class-work/mybatis-demo/README.md b/2019-11/spring-08/demo-projects/mybatis-demo/README.md
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/mybatis-demo/README.md
rename to 2019-11/spring-08/demo-projects/mybatis-demo/README.md
diff --git a/2019-11/spring-08/orm-class-work/mybatis-demo/pom.xml b/2019-11/spring-08/demo-projects/mybatis-demo/pom.xml
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/mybatis-demo/pom.xml
rename to 2019-11/spring-08/demo-projects/mybatis-demo/pom.xml
diff --git a/2019-11/spring-08/orm-class-work/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/MyBatisDemoApplication.java b/2019-11/spring-08/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/MyBatisDemoApplication.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/MyBatisDemoApplication.java
rename to 2019-11/spring-08/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/MyBatisDemoApplication.java
diff --git a/2019-11/spring-08/orm-class-work/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/Avatar.java b/2019-11/spring-08/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/Avatar.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/Avatar.java
rename to 2019-11/spring-08/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/Avatar.java
diff --git a/2019-11/spring-08/orm-class-work/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/Course.java b/2019-11/spring-08/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/Course.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/Course.java
rename to 2019-11/spring-08/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/Course.java
diff --git a/2019-11/spring-08/orm-class-work/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/EMail.java b/2019-11/spring-08/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/EMail.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/EMail.java
rename to 2019-11/spring-08/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/EMail.java
diff --git a/2019-11/spring-08/orm-class-work/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/OtusStudent.java b/2019-11/spring-08/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/OtusStudent.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/OtusStudent.java
rename to 2019-11/spring-08/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/OtusStudent.java
diff --git a/2019-11/spring-08/orm-class-work/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/AvatarRepository.java b/2019-11/spring-08/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/AvatarRepository.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/AvatarRepository.java
rename to 2019-11/spring-08/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/AvatarRepository.java
diff --git a/2019-11/spring-08/orm-class-work/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/CourseRepository.java b/2019-11/spring-08/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/CourseRepository.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/CourseRepository.java
rename to 2019-11/spring-08/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/CourseRepository.java
diff --git a/2019-11/spring-08/orm-class-work/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/EmailRepository.java b/2019-11/spring-08/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/EmailRepository.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/EmailRepository.java
rename to 2019-11/spring-08/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/EmailRepository.java
diff --git a/2019-11/spring-08/orm-class-work/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/OtusStudentRepository.java b/2019-11/spring-08/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/OtusStudentRepository.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/OtusStudentRepository.java
rename to 2019-11/spring-08/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/OtusStudentRepository.java
diff --git a/2019-11/spring-08/orm-class-work/mybatis-demo/src/main/resources/schema.sql b/2019-11/spring-08/demo-projects/mybatis-demo/src/main/resources/schema.sql
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/mybatis-demo/src/main/resources/schema.sql
rename to 2019-11/spring-08/demo-projects/mybatis-demo/src/main/resources/schema.sql
diff --git a/2019-11/spring-08/orm-class-work/mybatis-demo/src/test/java/ru/otus/example/mybatisdemo/repositories/OtusStudentRepositoryTest.java b/2019-11/spring-08/demo-projects/mybatis-demo/src/test/java/ru/otus/example/mybatisdemo/repositories/OtusStudentRepositoryTest.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/mybatis-demo/src/test/java/ru/otus/example/mybatisdemo/repositories/OtusStudentRepositoryTest.java
rename to 2019-11/spring-08/demo-projects/mybatis-demo/src/test/java/ru/otus/example/mybatisdemo/repositories/OtusStudentRepositoryTest.java
diff --git a/2019-11/spring-08/orm-class-work/mybatis-demo/src/test/resources/application.yml b/2019-11/spring-08/demo-projects/mybatis-demo/src/test/resources/application.yml
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/mybatis-demo/src/test/resources/application.yml
rename to 2019-11/spring-08/demo-projects/mybatis-demo/src/test/resources/application.yml
diff --git a/2019-11/spring-08/orm-class-work/mybatis-demo/src/test/resources/data.sql b/2019-11/spring-08/demo-projects/mybatis-demo/src/test/resources/data.sql
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/mybatis-demo/src/test/resources/data.sql
rename to 2019-11/spring-08/demo-projects/mybatis-demo/src/test/resources/data.sql
diff --git a/2019-11/spring-08/demo-projects/pom.xml b/2019-11/spring-08/demo-projects/pom.xml
new file mode 100644
index 00000000..711fadf0
--- /dev/null
+++ b/2019-11/spring-08/demo-projects/pom.xml
@@ -0,0 +1,17 @@
+
+
+ 4.0.0
+
+ ru.otus
+ demo-projects
+ 1.0
+
+ pom
+
+
+ spring-jdbc-demo
+ mybatis-demo
+
+
diff --git a/2019-11/spring-08/orm-class-work/orm-demo/.gitignore b/2019-11/spring-08/demo-projects/spring-jdbc-demo/.gitignore
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/orm-demo/.gitignore
rename to 2019-11/spring-08/demo-projects/spring-jdbc-demo/.gitignore
diff --git a/2019-11/spring-08/orm-class-work/spring-jdbc-demo/README.md b/2019-11/spring-08/demo-projects/spring-jdbc-demo/README.md
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/spring-jdbc-demo/README.md
rename to 2019-11/spring-08/demo-projects/spring-jdbc-demo/README.md
diff --git a/2019-11/spring-08/orm-class-work/spring-jdbc-demo/pom.xml b/2019-11/spring-08/demo-projects/spring-jdbc-demo/pom.xml
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/spring-jdbc-demo/pom.xml
rename to 2019-11/spring-08/demo-projects/spring-jdbc-demo/pom.xml
diff --git a/2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/SpringJdbcDemoApplication.java b/2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/SpringJdbcDemoApplication.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/SpringJdbcDemoApplication.java
rename to 2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/SpringJdbcDemoApplication.java
diff --git a/2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/Avatar.java b/2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/Avatar.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/Avatar.java
rename to 2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/Avatar.java
diff --git a/2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/Course.java b/2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/Course.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/Course.java
rename to 2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/Course.java
diff --git a/2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/EMail.java b/2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/EMail.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/EMail.java
rename to 2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/EMail.java
diff --git a/2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/OtusStudent.java b/2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/OtusStudent.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/OtusStudent.java
rename to 2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/OtusStudent.java
diff --git a/2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/CourseRepositoryJdbc.java b/2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/CourseRepositoryJdbc.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/CourseRepositoryJdbc.java
rename to 2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/CourseRepositoryJdbc.java
diff --git a/2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/CourseRepositoryJdbcImpl.java b/2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/CourseRepositoryJdbcImpl.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/CourseRepositoryJdbcImpl.java
rename to 2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/CourseRepositoryJdbcImpl.java
diff --git a/2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbc.java b/2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbc.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbc.java
rename to 2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbc.java
diff --git a/2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbcImpl.java b/2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbcImpl.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbcImpl.java
rename to 2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbcImpl.java
diff --git a/2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/ext/OtusStudentResultSetExtractor.java b/2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/ext/OtusStudentResultSetExtractor.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/ext/OtusStudentResultSetExtractor.java
rename to 2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/ext/OtusStudentResultSetExtractor.java
diff --git a/2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/ext/StudentCourseRelation.java b/2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/ext/StudentCourseRelation.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/ext/StudentCourseRelation.java
rename to 2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/ext/StudentCourseRelation.java
diff --git a/2019-11/spring-08/orm-class-work/orm-demo/src/main/resources/schema.sql b/2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/resources/schema.sql
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/orm-demo/src/main/resources/schema.sql
rename to 2019-11/spring-08/demo-projects/spring-jdbc-demo/src/main/resources/schema.sql
diff --git a/2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/test/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbcImplTest.java b/2019-11/spring-08/demo-projects/spring-jdbc-demo/src/test/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbcImplTest.java
similarity index 96%
rename from 2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/test/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbcImplTest.java
rename to 2019-11/spring-08/demo-projects/spring-jdbc-demo/src/test/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbcImplTest.java
index 09ab23f9..dab99810 100644
--- a/2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/test/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbcImplTest.java
+++ b/2019-11/spring-08/demo-projects/spring-jdbc-demo/src/test/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbcImplTest.java
@@ -29,6 +29,7 @@ class OtusStudentRepositoryJdbcImplTest {
.allMatch(s -> s.getCourses() != null && s.getCourses().size() > 0)
.allMatch(s -> s.getAvatar() != null)
.allMatch(s -> s.getEmails() != null && s.getEmails().size() > 0);
+ students.forEach(System.out::println);
}
}
\ No newline at end of file
diff --git a/2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/test/resources/application.yml b/2019-11/spring-08/demo-projects/spring-jdbc-demo/src/test/resources/application.yml
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/test/resources/application.yml
rename to 2019-11/spring-08/demo-projects/spring-jdbc-demo/src/test/resources/application.yml
diff --git a/2019-11/spring-08/orm-class-work/orm-demo/src/test/resources/data.sql b/2019-11/spring-08/demo-projects/spring-jdbc-demo/src/test/resources/data.sql
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/orm-demo/src/test/resources/data.sql
rename to 2019-11/spring-08/demo-projects/spring-jdbc-demo/src/test/resources/data.sql
diff --git a/2019-11/spring-08/orm-class-work/orm-demo/README.md b/2019-11/spring-08/orm-class-work/orm-demo/README.md
deleted file mode 100644
index a1e907ee..00000000
--- a/2019-11/spring-08/orm-class-work/orm-demo/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# orm-demo
-Пример работы с БД через ORM
\ No newline at end of file
diff --git a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/models/OtusStudentV2.java b/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/models/OtusStudentV2.java
deleted file mode 100644
index e7fa06e5..00000000
--- a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/models/OtusStudentV2.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package ru.otus.example.ormdemo.models;
-
-import lombok.*;
-import org.hibernate.annotations.BatchSize;
-import org.hibernate.annotations.Fetch;
-import org.hibernate.annotations.FetchMode;
-import ru.otus.example.ormdemo.models.common.Avatar;
-import ru.otus.example.ormdemo.models.common.Course;
-import ru.otus.example.ormdemo.models.common.EMail;
-
-import javax.persistence.*;
-import java.util.List;
-
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-@Entity
-@Table(name = "otus_students")
-@NamedEntityGraph(name = "OtusStudentWithAvatarAndEmails",
- attributeNodes = {@NamedAttributeNode(value = "avatar"),
- @NamedAttributeNode(value = "emails")})
-public class OtusStudentV2 {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private long id;
-
- @Column(name = "name", nullable = false, unique = true)
- private String name;
-
- @OneToOne(targetEntity = Avatar.class, cascade = CascadeType.ALL)
- @JoinColumn(name = "avatar_id")
- private Avatar avatar;
-
- @OneToMany(targetEntity = EMail.class, cascade = CascadeType.ALL)
- @JoinColumn(name = "student_id")
- private List emails;
-
- //@Fetch(FetchMode.SUBSELECT)
- //@BatchSize(size = 5)
- @ManyToMany(targetEntity = Course.class, fetch = FetchType.LAZY)
- @JoinTable(name = "student_courses", joinColumns = @JoinColumn(name = "student_id"),
- inverseJoinColumns = @JoinColumn(name = "course_id"))
- private List courses;
-}
diff --git a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/repositories/CourseRepositoryJpa.java b/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/repositories/CourseRepositoryJpa.java
deleted file mode 100644
index dc6d0811..00000000
--- a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/repositories/CourseRepositoryJpa.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package ru.otus.example.ormdemo.repositories;
-
-import ru.otus.example.ormdemo.models.common.Course;
-
-public interface CourseRepositoryJpa {
- Course save(Course course);
-}
diff --git a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/repositories/CourseRepositoryJpaImpl.java b/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/repositories/CourseRepositoryJpaImpl.java
deleted file mode 100644
index d4ce0bd8..00000000
--- a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/repositories/CourseRepositoryJpaImpl.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package ru.otus.example.ormdemo.repositories;
-
-import ru.otus.example.ormdemo.models.common.Course;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-
-public class CourseRepositoryJpaImpl implements CourseRepositoryJpa {
-
- @PersistenceContext
- private EntityManager em;
-
- @Override
- public Course save(Course course) {
- em.persist(course);
- return course;
- }
-}
diff --git a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentV2RepositoryJpa.java b/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentV2RepositoryJpa.java
deleted file mode 100644
index 5893319f..00000000
--- a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentV2RepositoryJpa.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package ru.otus.example.ormdemo.repositories;
-
-
-import ru.otus.example.ormdemo.models.OtusStudentV2;
-
-import java.util.List;
-
-public interface OtusStudentV2RepositoryJpa {
- List findAllWithEntityGraph();
- List findAllWithJoinFetch();
-}
diff --git a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentV2RepositoryJpaImpl.java b/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentV2RepositoryJpaImpl.java
deleted file mode 100644
index df615f41..00000000
--- a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentV2RepositoryJpaImpl.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package ru.otus.example.ormdemo.repositories;
-
-import org.springframework.stereotype.Repository;
-import ru.otus.example.ormdemo.models.OtusStudentV2;
-
-import javax.persistence.EntityGraph;
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import javax.persistence.TypedQuery;
-import java.util.List;
-
-@Repository
-public class OtusStudentV2RepositoryJpaImpl implements OtusStudentV2RepositoryJpa {
-
- @PersistenceContext
- private EntityManager em;
-
- @Override
- public List findAllWithEntityGraph() {
- EntityGraph> entityGraph = em.getEntityGraph("OtusStudentWithAvatarAndEmails");
- TypedQuery query = em.createQuery("select s from OtusStudentV2 s", OtusStudentV2.class);
- query.setHint("javax.persistence.fetchgraph", entityGraph);
- return query.getResultList();
- }
-
- @Override
- public List findAllWithJoinFetch() {
- return em.createQuery("select distinct s from OtusStudentV2 s join fetch s.avatar join fetch s.emails", OtusStudentV2.class).getResultList();
- }
-}
diff --git a/2019-11/spring-08/orm-class-work/orm-demo/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentV2RepositoryJpaImplTest.java b/2019-11/spring-08/orm-class-work/orm-demo/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentV2RepositoryJpaImplTest.java
deleted file mode 100644
index 041384b3..00000000
--- a/2019-11/spring-08/orm-class-work/orm-demo/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentV2RepositoryJpaImplTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package ru.otus.example.ormdemo.repositories;
-
-import org.hibernate.SessionFactory;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
-import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
-import org.springframework.context.annotation.Import;
-import ru.otus.example.ormdemo.models.OtusStudentV2;
-
-import java.util.List;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-@DisplayName("Репозиторий v2 на основе Jpa для работы со студентами ")
-@DataJpaTest
-@Import({OtusStudentV2RepositoryJpaImpl.class})
-class OtusStudentV2RepositoryJpaImplTest {
-
- private static final int EXPECTED_NUMBER_OF_STUDENTS = 10;
-
- private static final int EXPECTED_QUERIES_COUNT = 11; // EntityGraph/join fetch
- //private static final int EXPECTED_QUERIES_COUNT = 2; // EntityGraph/join fetch + @Fetch(FetchMode.SUBSELECT)
- //private static final int EXPECTED_QUERIES_COUNT = 3; // EntityGraph/join fetch + @BatchSize(size = 5)
-
- @Autowired
- private OtusStudentV2RepositoryJpaImpl repositoryJpa;
-
- @Autowired
- private TestEntityManager em;
-
- private SessionFactory sessionFactory;
-
- @BeforeEach
- void setUp() {
- sessionFactory = em.getEntityManager().getEntityManagerFactory()
- .unwrap(SessionFactory.class);
- sessionFactory.getStatistics().setStatisticsEnabled(true);
- sessionFactory.getStatistics().clear();
- }
-
- @DisplayName(" с помощью EntityGraph должен загружать список всех студентов с полной информацией о них")
- @Test
- void usingEntityGraphShouldReturnCorrectStudentsListWithWithAllInfo() {
- System.out.println("\n\n\n\n----------------------------------------------------------------------------------------------------------");
- List students = repositoryJpa.findAllWithEntityGraph();
- assertThat(students).isNotNull().hasSize(EXPECTED_NUMBER_OF_STUDENTS)
- .allMatch(s -> !s.getName().equals(""))
- .allMatch(s -> s.getCourses() != null && s.getCourses().size() > 0)
- .allMatch(s -> s.getAvatar() != null)
- .allMatch(s -> s.getEmails() != null && s.getEmails().size() > 0);
- System.out.println("----------------------------------------------------------------------------------------------------------\n\n\n\n");
- assertThat(sessionFactory.getStatistics().getPrepareStatementCount())
- .isEqualTo(EXPECTED_QUERIES_COUNT);
-
- }
-
- @DisplayName(" с помощью 'join fetch' должен загружать список всех студентов с полной информацией о них")
- @Test
- void usingJoinFetchShouldReturnCorrectStudentsListWithWithAllInfo() {
- System.out.println("\n\n\n\n----------------------------------------------------------------------------------------------------------");
- List students = repositoryJpa.findAllWithJoinFetch();
- assertThat(students).isNotNull().hasSize(EXPECTED_NUMBER_OF_STUDENTS)
- .allMatch(s -> !s.getName().equals(""))
- .allMatch(s -> s.getCourses() != null && s.getCourses().size() > 0)
- .allMatch(s -> s.getAvatar() != null)
- .allMatch(s -> s.getEmails() != null && s.getEmails().size() > 0);
- System.out.println("----------------------------------------------------------------------------------------------------------\n\n\n\n");
- assertThat(sessionFactory.getStatistics().getPrepareStatementCount())
- .isEqualTo(EXPECTED_QUERIES_COUNT);
- }
-}
\ No newline at end of file
diff --git a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/.gitignore b/2019-11/spring-08/orm-class-work/orm-exercise/.gitignore
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/replace-orm-provider-demo/.gitignore
rename to 2019-11/spring-08/orm-class-work/orm-exercise/.gitignore
diff --git a/2019-11/spring-08/orm-class-work/orm-demo/pom.xml b/2019-11/spring-08/orm-class-work/orm-exercise/pom.xml
similarity index 94%
rename from 2019-11/spring-08/orm-class-work/orm-demo/pom.xml
rename to 2019-11/spring-08/orm-class-work/orm-exercise/pom.xml
index 213779ff..7718c072 100644
--- a/2019-11/spring-08/orm-class-work/orm-demo/pom.xml
+++ b/2019-11/spring-08/orm-class-work/orm-exercise/pom.xml
@@ -9,10 +9,9 @@
ru.otus.example
- orm-demo
+ orm-exercise
+ orm-exercise
0.0.1-SNAPSHOT
- orm-demo
- Orm demo
11
@@ -29,7 +28,7 @@
com.h2database
h2
- runtime
+ 1.4.200
diff --git a/2019-11/spring-08/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2019-11/spring-08/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
new file mode 100644
index 00000000..cbf71df2
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
@@ -0,0 +1,17 @@
+package ru.otus.example.ormdemo;
+
+import org.h2.tools.Console;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import java.sql.SQLException;
+
+@SpringBootApplication
+public class OrmDemoApplication {
+
+ public static void main(String[] args) throws SQLException {
+ SpringApplication.run(OrmDemoApplication.class, args);
+ Console.main(args);
+ }
+
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/Avatar.java b/2019-11/spring-08/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
new file mode 100644
index 00000000..52c8b747
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
@@ -0,0 +1,15 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class Avatar {
+ private long id;
+ private String photoUrl;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/Course.java b/2019-11/spring-08/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/Course.java
new file mode 100644
index 00000000..adbde731
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/Course.java
@@ -0,0 +1,15 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class Course {
+ private long id;
+ private String name;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/EMail.java b/2019-11/spring-08/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/EMail.java
new file mode 100644
index 00000000..d7ed5610
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/EMail.java
@@ -0,0 +1,15 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class EMail {
+ private long id;
+ private String email;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2019-11/spring-08/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
new file mode 100644
index 00000000..49d7bcba
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
@@ -0,0 +1,18 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.*;
+
+import javax.persistence.*;
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class OtusStudent {
+ private long id;
+ private String name;
+
+ //private Avatar avatar;
+ //private List emails;
+ //private List courses;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-exercise/src/main/resources/application.yml b/2019-11/spring-08/orm-class-work/orm-exercise/src/main/resources/application.yml
new file mode 100644
index 00000000..80d05f29
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-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: true
+
+ show-sql: true
+
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2019-11/spring-08/orm-class-work/spring-jdbc-demo/.gitignore b/2019-11/spring-08/orm-class-work/orm-solution-01/.gitignore
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/spring-jdbc-demo/.gitignore
rename to 2019-11/spring-08/orm-class-work/orm-solution-01/.gitignore
diff --git a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/pom.xml b/2019-11/spring-08/orm-class-work/orm-solution-01/pom.xml
similarity index 73%
rename from 2019-11/spring-08/orm-class-work/replace-orm-provider-demo/pom.xml
rename to 2019-11/spring-08/orm-class-work/orm-solution-01/pom.xml
index b783b3fc..3a067709 100644
--- a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/pom.xml
+++ b/2019-11/spring-08/orm-class-work/orm-solution-01/pom.xml
@@ -9,10 +9,9 @@
ru.otus.example
- replace-orm-provider-demo
+ orm-solution-01
+ orm-solution-01
0.0.1-SNAPSHOT
- replace-orm-provider-demo
- Replace ORM provider demo
11
@@ -24,28 +23,12 @@
org.springframework.boot
spring-boot-starter-data-jpa
-
-
- org.hibernate
- hibernate-entitymanager
-
-
- org.hibernate
- hibernate-core
-
-
-
-
-
- org.eclipse.persistence
- org.eclipse.persistence.jpa
- 2.7.4
com.h2database
h2
- runtime
+ 1.4.200
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2019-11/spring-08/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
new file mode 100644
index 00000000..cbf71df2
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
@@ -0,0 +1,17 @@
+package ru.otus.example.ormdemo;
+
+import org.h2.tools.Console;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import java.sql.SQLException;
+
+@SpringBootApplication
+public class OrmDemoApplication {
+
+ public static void main(String[] args) throws SQLException {
+ SpringApplication.run(OrmDemoApplication.class, args);
+ Console.main(args);
+ }
+
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/Avatar.java b/2019-11/spring-08/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
new file mode 100644
index 00000000..d9cca2ca
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
@@ -0,0 +1,17 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+public class Avatar {
+ @Id
+ private long id;
+ private String photoUrl;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/Course.java b/2019-11/spring-08/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/Course.java
new file mode 100644
index 00000000..a02a15f8
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/Course.java
@@ -0,0 +1,17 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+public class Course {
+ @Id
+ private long id;
+ private String name;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/EMail.java b/2019-11/spring-08/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/EMail.java
new file mode 100644
index 00000000..e71e8ac9
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/EMail.java
@@ -0,0 +1,17 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+public class EMail {
+ @Id
+ private long id;
+ private String email;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2019-11/spring-08/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
new file mode 100644
index 00000000..ec9dfaa5
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
@@ -0,0 +1,20 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.*;
+
+import javax.persistence.*;
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity // Указывает, что данный класс является сущностью
+public class OtusStudent {
+ @Id // Позволяет указать какое поле является идентификатором
+ private long id;
+ private String name;
+
+ //private Avatar avatar;
+ //private List emails;
+ //private List courses;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-01/src/main/resources/application.yml b/2019-11/spring-08/orm-class-work/orm-solution-01/src/main/resources/application.yml
new file mode 100644
index 00000000..80d05f29
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-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: true
+
+ show-sql: true
+
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-02/.gitignore b/2019-11/spring-08/orm-class-work/orm-solution-02/.gitignore
new file mode 100644
index 00000000..153c9335
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-02/.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/2019-11/spring-08/orm-class-work/orm-solution-02/pom.xml b/2019-11/spring-08/orm-class-work/orm-solution-02/pom.xml
new file mode 100644
index 00000000..4560b5a5
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-02/pom.xml
@@ -0,0 +1,71 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.2.1.RELEASE
+
+
+ ru.otus.example
+ orm-solution-02
+ orm-solution-02
+ 0.0.1-SNAPSHOT
+
+
+ 11
+ 11
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ com.h2database
+ h2
+ 1.4.200
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+ 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.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2019-11/spring-08/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
new file mode 100644
index 00000000..cbf71df2
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
@@ -0,0 +1,17 @@
+package ru.otus.example.ormdemo;
+
+import org.h2.tools.Console;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import java.sql.SQLException;
+
+@SpringBootApplication
+public class OrmDemoApplication {
+
+ public static void main(String[] args) throws SQLException {
+ SpringApplication.run(OrmDemoApplication.class, args);
+ Console.main(args);
+ }
+
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/Avatar.java b/2019-11/spring-08/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
new file mode 100644
index 00000000..d60a4f32
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
@@ -0,0 +1,20 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "avatars")
+public class Avatar {
+ @Id
+ private long id;
+
+ @Column(name = "photo_url")
+ private String photoUrl;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/Course.java b/2019-11/spring-08/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/Course.java
new file mode 100644
index 00000000..8a677513
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/Course.java
@@ -0,0 +1,20 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "courses")
+public class Course {
+ @Id
+ private long id;
+
+ @Column(name = "name")
+ private String name;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/EMail.java b/2019-11/spring-08/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/EMail.java
new file mode 100644
index 00000000..8f15fd87
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/EMail.java
@@ -0,0 +1,21 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "emails")
+public class EMail {
+
+ @Id
+ private long id;
+
+ @Column(name = "email")
+ private String email;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2019-11/spring-08/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
new file mode 100644
index 00000000..a509d959
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
@@ -0,0 +1,24 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.*;
+
+import javax.persistence.*;
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity // Указывает, что данный класс является сущностью
+@Table(name = "otus_students") // Задает имя таблицы, на которую будет отображаться сущность
+public class OtusStudent {
+ @Id // Позволяет указать какое поле является идентификатором
+ private long id;
+
+ // Задает имя и некоторые свойства поля таблицы, на которое будет отображаться поле сущности
+ @Column(name = "name")
+ private String name;
+
+ //private Avatar avatar;
+ //private List emails;
+ //private List courses;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-02/src/main/resources/application.yml b/2019-11/spring-08/orm-class-work/orm-solution-02/src/main/resources/application.yml
new file mode 100644
index 00000000..80d05f29
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-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: true
+
+ show-sql: true
+
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-03/.gitignore b/2019-11/spring-08/orm-class-work/orm-solution-03/.gitignore
new file mode 100644
index 00000000..153c9335
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-03/.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/2019-11/spring-08/orm-class-work/orm-solution-03/pom.xml b/2019-11/spring-08/orm-class-work/orm-solution-03/pom.xml
new file mode 100644
index 00000000..b85b1e34
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-03/pom.xml
@@ -0,0 +1,71 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.2.1.RELEASE
+
+
+ ru.otus.example
+ orm-solution-03
+ orm-solution-03
+ 0.0.1-SNAPSHOT
+
+
+ 11
+ 11
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ com.h2database
+ h2
+ 1.4.200
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+ 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.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2019-11/spring-08/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
new file mode 100644
index 00000000..cbf71df2
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
@@ -0,0 +1,17 @@
+package ru.otus.example.ormdemo;
+
+import org.h2.tools.Console;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import java.sql.SQLException;
+
+@SpringBootApplication
+public class OrmDemoApplication {
+
+ public static void main(String[] args) throws SQLException {
+ SpringApplication.run(OrmDemoApplication.class, args);
+ Console.main(args);
+ }
+
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/Avatar.java b/2019-11/spring-08/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
new file mode 100644
index 00000000..6d7bc172
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
@@ -0,0 +1,21 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "avatars")
+public class Avatar {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Column(name = "photo_url")
+ private String photoUrl;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/Course.java b/2019-11/spring-08/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/Course.java
new file mode 100644
index 00000000..8fb4b707
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/Course.java
@@ -0,0 +1,21 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "courses")
+public class Course {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Column(name = "name")
+ private String name;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/EMail.java b/2019-11/spring-08/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/EMail.java
new file mode 100644
index 00000000..9c999a97
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/EMail.java
@@ -0,0 +1,22 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "emails")
+public class EMail {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Column(name = "email")
+ private String email;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2019-11/spring-08/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
new file mode 100644
index 00000000..03720a6a
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
@@ -0,0 +1,25 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.*;
+
+import javax.persistence.*;
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity // Указывает, что данный класс является сущностью
+@Table(name = "otus_students") // Задает имя таблицы, на которую будет отображаться сущность
+public class OtusStudent {
+ @Id // Позволяет указать какое поле является идентификатором
+ @GeneratedValue(strategy = GenerationType.IDENTITY) // Позволяет указат стратегию генерации id
+ private long id;
+
+ // Задает имя и некоторые свойства поля таблицы, на которое будет отображаться поле сущности
+ @Column(name = "name")
+ private String name;
+
+ //private Avatar avatar;
+ //private List emails;
+ //private List courses;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-03/src/main/resources/application.yml b/2019-11/spring-08/orm-class-work/orm-solution-03/src/main/resources/application.yml
new file mode 100644
index 00000000..80d05f29
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-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: true
+
+ show-sql: true
+
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-04/.gitignore b/2019-11/spring-08/orm-class-work/orm-solution-04/.gitignore
new file mode 100644
index 00000000..153c9335
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-04/.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/2019-11/spring-08/orm-class-work/orm-solution-04/pom.xml b/2019-11/spring-08/orm-class-work/orm-solution-04/pom.xml
new file mode 100644
index 00000000..38e25f7f
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-04/pom.xml
@@ -0,0 +1,71 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.2.1.RELEASE
+
+
+ ru.otus.example
+ orm-solution-04
+ orm-solution-04
+ 0.0.1-SNAPSHOT
+
+
+ 11
+ 11
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ com.h2database
+ h2
+ 1.4.200
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+ 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.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2019-11/spring-08/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
new file mode 100644
index 00000000..cbf71df2
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
@@ -0,0 +1,17 @@
+package ru.otus.example.ormdemo;
+
+import org.h2.tools.Console;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import java.sql.SQLException;
+
+@SpringBootApplication
+public class OrmDemoApplication {
+
+ public static void main(String[] args) throws SQLException {
+ SpringApplication.run(OrmDemoApplication.class, args);
+ Console.main(args);
+ }
+
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/Avatar.java b/2019-11/spring-08/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
new file mode 100644
index 00000000..6d7bc172
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
@@ -0,0 +1,21 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "avatars")
+public class Avatar {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Column(name = "photo_url")
+ private String photoUrl;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/Course.java b/2019-11/spring-08/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/Course.java
new file mode 100644
index 00000000..8fb4b707
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/Course.java
@@ -0,0 +1,21 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "courses")
+public class Course {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Column(name = "name")
+ private String name;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/EMail.java b/2019-11/spring-08/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/EMail.java
new file mode 100644
index 00000000..9c999a97
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/EMail.java
@@ -0,0 +1,22 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "emails")
+public class EMail {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Column(name = "email")
+ private String email;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2019-11/spring-08/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
new file mode 100644
index 00000000..44eef5ed
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
@@ -0,0 +1,30 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.*;
+
+import javax.persistence.*;
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity // Указывает, что данный класс является сущностью
+@Table(name = "otus_students") // Задает имя таблицы, на которую будет отображаться сущность
+public class OtusStudent {
+ @Id // Позволяет указать какое поле является идентификатором
+ @GeneratedValue(strategy = GenerationType.IDENTITY) // Стратегия генерации идентификаторов
+ private long id;
+
+ // Задает имя и некоторые свойства поля таблицы, на которое будет отображаться поле сущности
+ @Column(name = "name", nullable = false, unique = true)
+ private String name;
+
+ // Указывает на связь между таблицами "один к одному"
+ @OneToOne(targetEntity = Avatar.class, cascade = CascadeType.ALL)
+ // Задает поле, по которому происходит объединение с таблицей для хранения связанной сущности
+ @JoinColumn(name = "avatar_id")
+ private Avatar avatar;
+
+ //private List emails;
+ //private List courses;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-04/src/main/resources/application.yml b/2019-11/spring-08/orm-class-work/orm-solution-04/src/main/resources/application.yml
new file mode 100644
index 00000000..80d05f29
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-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: true
+
+ show-sql: true
+
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-05/.gitignore b/2019-11/spring-08/orm-class-work/orm-solution-05/.gitignore
new file mode 100644
index 00000000..153c9335
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-05/.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/2019-11/spring-08/orm-class-work/orm-solution-05/pom.xml b/2019-11/spring-08/orm-class-work/orm-solution-05/pom.xml
new file mode 100644
index 00000000..b7b06e5a
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-05/pom.xml
@@ -0,0 +1,71 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.2.1.RELEASE
+
+
+ ru.otus.example
+ orm-solution-05
+ orm-solution-05
+ 0.0.1-SNAPSHOT
+
+
+ 11
+ 11
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ com.h2database
+ h2
+ 1.4.200
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+ 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.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2019-11/spring-08/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
new file mode 100644
index 00000000..cbf71df2
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
@@ -0,0 +1,17 @@
+package ru.otus.example.ormdemo;
+
+import org.h2.tools.Console;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import java.sql.SQLException;
+
+@SpringBootApplication
+public class OrmDemoApplication {
+
+ public static void main(String[] args) throws SQLException {
+ SpringApplication.run(OrmDemoApplication.class, args);
+ Console.main(args);
+ }
+
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/Avatar.java b/2019-11/spring-08/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
new file mode 100644
index 00000000..6d7bc172
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
@@ -0,0 +1,21 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "avatars")
+public class Avatar {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Column(name = "photo_url")
+ private String photoUrl;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/Course.java b/2019-11/spring-08/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/Course.java
new file mode 100644
index 00000000..8fb4b707
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/Course.java
@@ -0,0 +1,21 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "courses")
+public class Course {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Column(name = "name")
+ private String name;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/EMail.java b/2019-11/spring-08/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/EMail.java
new file mode 100644
index 00000000..9c999a97
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/EMail.java
@@ -0,0 +1,22 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "emails")
+public class EMail {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Column(name = "email")
+ private String email;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2019-11/spring-08/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
new file mode 100644
index 00000000..c14e85a5
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
@@ -0,0 +1,34 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.*;
+
+import javax.persistence.*;
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity // Указывает, что данный класс является сущностью
+@Table(name = "otus_students") // Задает имя таблицы, на которую будет отображаться сущность
+public class OtusStudent {
+ @Id // Позволяет указать какое поле является идентификатором
+ @GeneratedValue(strategy = GenerationType.IDENTITY) // Стратегия генерации идентификаторов
+ private long id;
+
+ // Задает имя и некоторые свойства поля таблицы, на которое будет отображаться поле сущности
+ @Column(name = "name", nullable = false, unique = true)
+ private String name;
+
+ // Указывает на связь между таблицами "один к одному"
+ @OneToOne(targetEntity = Avatar.class, cascade = CascadeType.ALL)
+ // Задает поле, по которому происходит объединение с таблицей для хранения связанной сущности
+ @JoinColumn(name = "avatar_id")
+ private Avatar avatar;
+
+ // Указывает на связь между таблицами "один ко многим"
+ @OneToMany(targetEntity = EMail.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+ @JoinColumn(name = "student_id")
+ private List emails;
+
+ //private List courses;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-05/src/main/resources/application.yml b/2019-11/spring-08/orm-class-work/orm-solution-05/src/main/resources/application.yml
new file mode 100644
index 00000000..80d05f29
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-05/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: true
+
+ show-sql: true
+
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-final/.gitignore b/2019-11/spring-08/orm-class-work/orm-solution-final/.gitignore
new file mode 100644
index 00000000..153c9335
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-final/.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/2019-11/spring-08/orm-class-work/orm-solution-final/pom.xml b/2019-11/spring-08/orm-class-work/orm-solution-final/pom.xml
new file mode 100644
index 00000000..6d23588c
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-final/pom.xml
@@ -0,0 +1,71 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.2.1.RELEASE
+
+
+ ru.otus.example
+ orm-solution-final
+ orm-solution-final
+ 0.0.1-SNAPSHOT
+
+
+ 11
+ 11
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ com.h2database
+ h2
+ 1.4.200
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+ 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.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2019-11/spring-08/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
new file mode 100644
index 00000000..cbf71df2
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
@@ -0,0 +1,17 @@
+package ru.otus.example.ormdemo;
+
+import org.h2.tools.Console;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import java.sql.SQLException;
+
+@SpringBootApplication
+public class OrmDemoApplication {
+
+ public static void main(String[] args) throws SQLException {
+ SpringApplication.run(OrmDemoApplication.class, args);
+ Console.main(args);
+ }
+
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/Avatar.java b/2019-11/spring-08/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
new file mode 100644
index 00000000..6d7bc172
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
@@ -0,0 +1,21 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "avatars")
+public class Avatar {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Column(name = "photo_url")
+ private String photoUrl;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/Course.java b/2019-11/spring-08/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/Course.java
new file mode 100644
index 00000000..8fb4b707
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/Course.java
@@ -0,0 +1,21 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "courses")
+public class Course {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Column(name = "name")
+ private String name;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/EMail.java b/2019-11/spring-08/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/EMail.java
new file mode 100644
index 00000000..9c999a97
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/EMail.java
@@ -0,0 +1,22 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "emails")
+public class EMail {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Column(name = "email")
+ private String email;
+}
diff --git a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2019-11/spring-08/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
similarity index 93%
rename from 2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
rename to 2019-11/spring-08/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
index bd7f4852..0ec1e721 100644
--- a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
+++ b/2019-11/spring-08/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
@@ -1,9 +1,6 @@
package ru.otus.example.ormdemo.models;
import lombok.*;
-import ru.otus.example.ormdemo.models.common.Avatar;
-import ru.otus.example.ormdemo.models.common.Course;
-import ru.otus.example.ormdemo.models.common.EMail;
import javax.persistence.*;
import java.util.List;
diff --git a/2019-11/spring-08/orm-class-work/orm-solution-final/src/main/resources/application.yml b/2019-11/spring-08/orm-class-work/orm-solution-final/src/main/resources/application.yml
new file mode 100644
index 00000000..80d05f29
--- /dev/null
+++ b/2019-11/spring-08/orm-class-work/orm-solution-final/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: true
+
+ show-sql: true
+
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2019-11/spring-08/orm-class-work/pom.xml b/2019-11/spring-08/orm-class-work/pom.xml
index f398c0f4..3226fdcc 100644
--- a/2019-11/spring-08/orm-class-work/pom.xml
+++ b/2019-11/spring-08/orm-class-work/pom.xml
@@ -11,9 +11,12 @@
pom
- spring-jdbc-demo
- orm-demo
- replace-orm-provider-demo
- mybatis-demo
+ orm-exercise
+ orm-solution-01
+ orm-solution-02
+ orm-solution-03
+ orm-solution-04
+ orm-solution-05
+ orm-solution-final
diff --git a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/README.md b/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/README.md
deleted file mode 100644
index f5eceb6d..00000000
--- a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# replace-orm-provider-demo
-Пример замены ORM провайдера
\ No newline at end of file
diff --git a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/ReplaceOrmProviderDemoApplication.java b/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/ReplaceOrmProviderDemoApplication.java
deleted file mode 100644
index 97fee71e..00000000
--- a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/ReplaceOrmProviderDemoApplication.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package ru.otus.example.replaceormproviderdemo;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.annotation.Import;
-import ru.otus.example.replaceormproviderdemo.config.EclipseLinkJpaConfiguration;
-
-@SpringBootApplication
-@Import(EclipseLinkJpaConfiguration.class)
-public class ReplaceOrmProviderDemoApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(ReplaceOrmProviderDemoApplication.class, args);
- }
-
-}
diff --git a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/config/EclipseLinkJpaConfiguration.java b/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/config/EclipseLinkJpaConfiguration.java
deleted file mode 100644
index 6e14ede9..00000000
--- a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/config/EclipseLinkJpaConfiguration.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package ru.otus.example.replaceormproviderdemo.config;
-
-import org.eclipse.persistence.config.PersistenceUnitProperties;
-import org.springframework.beans.factory.ObjectProvider;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration;
-import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
-import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
-import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
-import org.springframework.transaction.jta.JtaTransactionManager;
-
-import javax.sql.DataSource;
-import java.util.HashMap;
-import java.util.Map;
-
-@Configuration
-public class EclipseLinkJpaConfiguration extends JpaBaseConfiguration {
- @Autowired
- protected EclipseLinkJpaConfiguration(DataSource dataSource, JpaProperties properties,
- ObjectProvider jtaTransactionManager) {
- super(dataSource, properties, jtaTransactionManager);
- }
-
- @Override
- protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
- return new EclipseLinkJpaVendorAdapter();
- }
-
- @Override
- protected Map getVendorProperties() {
- HashMap map = new HashMap<>();
- map.put(PersistenceUnitProperties.WEAVING, "false");
- return map;
- }
-}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-exercise/src/main/java/ru/otus/spring/Main.java b/2019-11/spring-09/jpql-class-work/jpql-demo-exercise/src/main/java/ru/otus/spring/Main.java
deleted file mode 100644
index 2b71abac..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-exercise/src/main/java/ru/otus/spring/Main.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package ru.otus.spring;
-
-import org.h2.tools.Console;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.ApplicationContext;
-import ru.otus.spring.repostory.PersonRepository;
-import ru.otus.spring.domain.Person;
-
-@SpringBootApplication
-public class Main {
-
- public static void main(String[] args) throws Exception {
-
- ApplicationContext context = SpringApplication.run(Main.class);
- PersonRepository repository = context.getBean(PersonRepository.class);
-
- Person nullPerson = repository.getById(1);
- System.out.println(nullPerson);
-
- Console.main(args);
- }
-}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-exercise/src/main/java/ru/otus/spring/domain/Person.java b/2019-11/spring-09/jpql-class-work/jpql-demo-exercise/src/main/java/ru/otus/spring/domain/Person.java
deleted file mode 100644
index 5393049e..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-exercise/src/main/java/ru/otus/spring/domain/Person.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package ru.otus.spring.domain;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-
-@Entity
-public class Person {
-
- @Id
- @GeneratedValue
- private long id;
- private String name;
-
- public Person() {
- }
-
- public Person(String name) {
- this.name = name;
- }
-
- public long getId() {
- return id;
- }
-
- public void setId(long 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/2019-11/spring-09/jpql-class-work/jpql-demo-exercise/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2019-11/spring-09/jpql-class-work/jpql-demo-exercise/src/main/java/ru/otus/spring/repostory/PersonRepository.java
deleted file mode 100644
index 6d7188cc..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-exercise/src/main/java/ru/otus/spring/repostory/PersonRepository.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package ru.otus.spring.repostory;
-
-import ru.otus.spring.domain.Person;
-
-import java.util.List;
-
-public interface PersonRepository {
-
- //void insert(Person p);
-
- Person getById(long id);
-
- //Person getFirst();
-
- //List getAll();
-
- //Person getByName(String name);
-}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-exercise/src/main/java/ru/otus/spring/repostory/PersonRepositoryJpa.java b/2019-11/spring-09/jpql-class-work/jpql-demo-exercise/src/main/java/ru/otus/spring/repostory/PersonRepositoryJpa.java
deleted file mode 100644
index e66b6e62..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-exercise/src/main/java/ru/otus/spring/repostory/PersonRepositoryJpa.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package ru.otus.spring.repostory;
-
-import org.springframework.stereotype.Repository;
-import org.springframework.transaction.annotation.Transactional;
-import ru.otus.spring.domain.Person;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import javax.persistence.TypedQuery;
-import java.util.List;
-
-@SuppressWarnings("JpaQlInspection")
-@Repository
-@Transactional
-public class PersonRepositoryJpa implements PersonRepository {
-
- @PersistenceContext
- private EntityManager em;
-
- @Override
- public Person getById(long id) {
- return em.find(Person.class, id);
- }
-}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-1/pom.xml b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-1/pom.xml
deleted file mode 100644
index a03a55c4..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-1/pom.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
- 4.0.0
-
- ru.otus
- jpql-demo-solution-step-1
- 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-starter-data-jpa
-
-
- com.h2database
- h2
-
-
-
- org.springframework.boot
- spring-boot-starter-test
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
-
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-1/src/main/java/ru/otus/spring/Main.java b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-1/src/main/java/ru/otus/spring/Main.java
deleted file mode 100644
index 4eb671d7..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-1/src/main/java/ru/otus/spring/Main.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package ru.otus.spring;
-
-import org.h2.tools.Console;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.ApplicationContext;
-import ru.otus.spring.repostory.PersonRepository;
-import ru.otus.spring.domain.Person;
-
-@SpringBootApplication
-public class Main {
-
- public static void main(String[] args) throws Exception {
-
- ApplicationContext context = SpringApplication.run(Main.class);
- PersonRepository repository = context.getBean(PersonRepository.class);
-
- repository.insert(new Person("Вася"));
- Person vasya = repository.getById(1);
- System.out.println(vasya);
-
- Console.main(args);
- }
-}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-1/src/main/java/ru/otus/spring/domain/Person.java b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-1/src/main/java/ru/otus/spring/domain/Person.java
deleted file mode 100644
index 5af7b810..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-1/src/main/java/ru/otus/spring/domain/Person.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package ru.otus.spring.domain;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-
-@Entity
-public class Person {
-
- @Id
- @GeneratedValue
- private long id;
- private String name;
-
- public Person() {
- }
-
- public Person(String name) {
- this.name = name;
- }
-
- public long getId() {
- return id;
- }
-
- public void setId(long 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/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-1/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-1/src/main/java/ru/otus/spring/repostory/PersonRepository.java
deleted file mode 100644
index 3a890f95..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-1/src/main/java/ru/otus/spring/repostory/PersonRepository.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package ru.otus.spring.repostory;
-
-import ru.otus.spring.domain.Person;
-
-import java.util.List;
-
-public interface PersonRepository {
-
- void insert(Person p);
-
- Person getById(long id);
-
- //Person getFirst();
-
- //List getAll();
-
- //Person getByName(String name);
-}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-1/src/main/java/ru/otus/spring/repostory/PersonRepositoryJpa.java b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-1/src/main/java/ru/otus/spring/repostory/PersonRepositoryJpa.java
deleted file mode 100644
index 6cd0f2ce..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-1/src/main/java/ru/otus/spring/repostory/PersonRepositoryJpa.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package ru.otus.spring.repostory;
-
-import org.springframework.stereotype.Repository;
-import org.springframework.transaction.annotation.Transactional;
-import ru.otus.spring.domain.Person;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import javax.persistence.TypedQuery;
-import java.util.List;
-
-@SuppressWarnings("JpaQlInspection")
-@Repository
-@Transactional
-public class PersonRepositoryJpa implements PersonRepository {
-
- @PersistenceContext
- private EntityManager em;
-
- @Override
- public void insert(Person p) {
- em.persist(p);
- }
-
- @Override
- public Person getById(long id) {
- return em.find(Person.class, id);
- }
-}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-2/pom.xml b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-2/pom.xml
deleted file mode 100644
index bd8de534..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-2/pom.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
- 4.0.0
-
- ru.otus
- jpql-demo-solution-step-2
- 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-starter-data-jpa
-
-
- com.h2database
- h2
-
-
-
- org.springframework.boot
- spring-boot-starter-test
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
-
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-2/src/main/java/ru/otus/spring/Main.java b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-2/src/main/java/ru/otus/spring/Main.java
deleted file mode 100644
index d6ca73f3..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-2/src/main/java/ru/otus/spring/Main.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package ru.otus.spring;
-
-import org.h2.tools.Console;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.ApplicationContext;
-import ru.otus.spring.repostory.PersonRepository;
-import ru.otus.spring.domain.Person;
-
-import java.util.List;
-
-@SpringBootApplication
-public class Main {
-
- public static void main(String[] args) throws Exception {
-
- ApplicationContext context = SpringApplication.run(Main.class);
- PersonRepository repository = context.getBean(PersonRepository.class);
-
- repository.insert(new Person("Вася"));
- repository.insert(new Person("Юля"));
- Person vasya = repository.getFirst();
- System.out.println(vasya);
-
- List vasyaAndJulia = repository.getAll();
- System.out.println(vasyaAndJulia);
-
-
- Console.main(args);
- }
-}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-2/src/main/java/ru/otus/spring/domain/Person.java b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-2/src/main/java/ru/otus/spring/domain/Person.java
deleted file mode 100644
index 5af7b810..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-2/src/main/java/ru/otus/spring/domain/Person.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package ru.otus.spring.domain;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-
-@Entity
-public class Person {
-
- @Id
- @GeneratedValue
- private long id;
- private String name;
-
- public Person() {
- }
-
- public Person(String name) {
- this.name = name;
- }
-
- public long getId() {
- return id;
- }
-
- public void setId(long 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/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-2/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-2/src/main/java/ru/otus/spring/repostory/PersonRepository.java
deleted file mode 100644
index 7a7dc11c..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-2/src/main/java/ru/otus/spring/repostory/PersonRepository.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package ru.otus.spring.repostory;
-
-import ru.otus.spring.domain.Person;
-
-import java.util.List;
-
-public interface PersonRepository {
-
- void insert(Person p);
-
- Person getById(long id);
-
- Person getFirst();
-
- List getAll();
-
- //Person getByName(String name);
-}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-2/src/main/java/ru/otus/spring/repostory/PersonRepositoryJpa.java b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-2/src/main/java/ru/otus/spring/repostory/PersonRepositoryJpa.java
deleted file mode 100644
index 1c5db78d..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-2/src/main/java/ru/otus/spring/repostory/PersonRepositoryJpa.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package ru.otus.spring.repostory;
-
-import org.springframework.stereotype.Repository;
-import org.springframework.transaction.annotation.Transactional;
-import ru.otus.spring.domain.Person;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import javax.persistence.TypedQuery;
-import java.util.List;
-
-@SuppressWarnings("JpaQlInspection")
-@Repository
-@Transactional
-public class PersonRepositoryJpa implements PersonRepository {
-
- @PersistenceContext
- private EntityManager em;
-
- @Override
- public void insert(Person p) {
- em.persist(p);
- }
-
- @Override
- public Person getById(long id) {
- return em.find(Person.class, id);
- }
-
- @Override
- public Person getFirst() {
- TypedQuery query = em.createQuery(
- "select p from Person p where p.id = 1",
- Person.class);
- return query.getSingleResult();
- }
-
- @Override
- public List getAll() {
- TypedQuery query = em.createQuery(
- "select p from Person p",
- Person.class);
- return query.getResultList();
- }
-}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-3/pom.xml b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-3/pom.xml
deleted file mode 100644
index 3a8973e5..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-3/pom.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
- 4.0.0
-
- ru.otus
- jpql-demo-solution-step-3
- 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-starter-data-jpa
-
-
- com.h2database
- h2
-
-
-
- org.springframework.boot
- spring-boot-starter-test
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
-
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-3/src/main/java/ru/otus/spring/Main.java b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-3/src/main/java/ru/otus/spring/Main.java
deleted file mode 100644
index 3e498e43..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-3/src/main/java/ru/otus/spring/Main.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package ru.otus.spring;
-
-import org.h2.tools.Console;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.ApplicationContext;
-import ru.otus.spring.repostory.PersonRepository;
-import ru.otus.spring.domain.Person;
-
-@SpringBootApplication
-public class Main {
-
- public static void main(String[] args) throws Exception {
-
- ApplicationContext context = SpringApplication.run(Main.class);
- PersonRepository repository = context.getBean(PersonRepository.class);
-
- Person julia = new Person("Юля");
- repository.insert(julia);
- Person juliaFromDB = repository.getByName(julia.getName());
- System.out.println(juliaFromDB);
-
-
-
- Console.main(args);
- }
-}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-3/src/main/java/ru/otus/spring/domain/Person.java b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-3/src/main/java/ru/otus/spring/domain/Person.java
deleted file mode 100644
index 5af7b810..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-3/src/main/java/ru/otus/spring/domain/Person.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package ru.otus.spring.domain;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-
-@Entity
-public class Person {
-
- @Id
- @GeneratedValue
- private long id;
- private String name;
-
- public Person() {
- }
-
- public Person(String name) {
- this.name = name;
- }
-
- public long getId() {
- return id;
- }
-
- public void setId(long 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/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-3/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-3/src/main/java/ru/otus/spring/repostory/PersonRepository.java
deleted file mode 100644
index d3ac6371..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-3/src/main/java/ru/otus/spring/repostory/PersonRepository.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package ru.otus.spring.repostory;
-
-import ru.otus.spring.domain.Person;
-
-import java.util.List;
-
-public interface PersonRepository {
-
- void insert(Person p);
-
- Person getById(long id);
-
- Person getFirst();
-
- List getAll();
-
- Person getByName(String name);
-}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-3/src/main/java/ru/otus/spring/repostory/PersonRepositoryJpa.java b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-3/src/main/java/ru/otus/spring/repostory/PersonRepositoryJpa.java
deleted file mode 100644
index 46990ebe..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-3/src/main/java/ru/otus/spring/repostory/PersonRepositoryJpa.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package ru.otus.spring.repostory;
-
-import org.springframework.stereotype.Repository;
-import org.springframework.transaction.annotation.Transactional;
-import ru.otus.spring.domain.Person;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import javax.persistence.TypedQuery;
-import java.util.List;
-
-@SuppressWarnings("JpaQlInspection")
-@Repository
-@Transactional
-public class PersonRepositoryJpa implements PersonRepository {
-
- @PersistenceContext
- private EntityManager em;
-
- @Override
- public void insert(Person p) {
- em.persist(p);
- }
-
- @Override
- public Person getById(long id) {
- return em.find(Person.class, id);
- }
-
- @Override
- public Person getFirst() {
- TypedQuery query = em.createQuery(
- "select p from Person p where p.id = 1",
- Person.class);
- return query.getSingleResult();
- }
-
- @Override
- public List getAll() {
- TypedQuery query = em.createQuery(
- "select p from Person p",
- Person.class);
- return query.getResultList();
- }
-
- @Override
- public Person getByName(String name) {
- TypedQuery query = em.createQuery(
- "select p from Person p where p.name = :name",
- Person.class);
- query.setParameter("name", name);
- return query.getSingleResult();
- }
-}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/.gitignore b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/.gitignore
deleted file mode 100644
index e62c33c2..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.idea/
-*.iml
-
-target/
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/src/main/java/ru/otus/spring/Main.java b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/src/main/java/ru/otus/spring/Main.java
deleted file mode 100644
index b97f0345..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/src/main/java/ru/otus/spring/Main.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package ru.otus.spring;
-
-import org.h2.tools.Console;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.ApplicationContext;
-import ru.otus.spring.repostory.PersonRepository;
-import ru.otus.spring.domain.Person;
-
-@SpringBootApplication
-public class Main {
-
- public static void main(String[] args) throws Exception {
-
- ApplicationContext context = SpringApplication.run(Main.class);
- PersonRepository repository = context.getBean(PersonRepository.class);
-
- Person nullPerson = repository.getById(1);
-
- Console.main(args);
- }
-}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/src/main/java/ru/otus/spring/domain/Person.java b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/src/main/java/ru/otus/spring/domain/Person.java
deleted file mode 100644
index 5af7b810..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/src/main/java/ru/otus/spring/domain/Person.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package ru.otus.spring.domain;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-
-@Entity
-public class Person {
-
- @Id
- @GeneratedValue
- private long id;
- private String name;
-
- public Person() {
- }
-
- public Person(String name) {
- this.name = name;
- }
-
- public long getId() {
- return id;
- }
-
- public void setId(long 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/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/src/main/java/ru/otus/spring/repostory/PersonRepository.java
deleted file mode 100644
index d3ac6371..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/src/main/java/ru/otus/spring/repostory/PersonRepository.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package ru.otus.spring.repostory;
-
-import ru.otus.spring.domain.Person;
-
-import java.util.List;
-
-public interface PersonRepository {
-
- void insert(Person p);
-
- Person getById(long id);
-
- Person getFirst();
-
- List getAll();
-
- Person getByName(String name);
-}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/src/main/java/ru/otus/spring/repostory/PersonRepositoryJpa.java b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/src/main/java/ru/otus/spring/repostory/PersonRepositoryJpa.java
deleted file mode 100644
index 46990ebe..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/src/main/java/ru/otus/spring/repostory/PersonRepositoryJpa.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package ru.otus.spring.repostory;
-
-import org.springframework.stereotype.Repository;
-import org.springframework.transaction.annotation.Transactional;
-import ru.otus.spring.domain.Person;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import javax.persistence.TypedQuery;
-import java.util.List;
-
-@SuppressWarnings("JpaQlInspection")
-@Repository
-@Transactional
-public class PersonRepositoryJpa implements PersonRepository {
-
- @PersistenceContext
- private EntityManager em;
-
- @Override
- public void insert(Person p) {
- em.persist(p);
- }
-
- @Override
- public Person getById(long id) {
- return em.find(Person.class, id);
- }
-
- @Override
- public Person getFirst() {
- TypedQuery query = em.createQuery(
- "select p from Person p where p.id = 1",
- Person.class);
- return query.getSingleResult();
- }
-
- @Override
- public List getAll() {
- TypedQuery query = em.createQuery(
- "select p from Person p",
- Person.class);
- return query.getResultList();
- }
-
- @Override
- public Person getByName(String name) {
- TypedQuery query = em.createQuery(
- "select p from Person p where p.name = :name",
- Person.class);
- query.setParameter("name", name);
- return query.getSingleResult();
- }
-}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/src/test/java/ru/otus/spring/domain/PersonTest.java b/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/src/test/java/ru/otus/spring/domain/PersonTest.java
deleted file mode 100644
index 9c646520..00000000
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/src/test/java/ru/otus/spring/domain/PersonTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package ru.otus.spring.domain;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
-import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-@DataJpaTest
-public class PersonTest {
-
- @Autowired
- private TestEntityManager em;
-
- @Test
- public void saveAndGet() {
- Person person = new Person("Ivan");
- Person fromDb = em.persistAndFlush(person);
- assertThat(fromDb.getId()).isNotZero();
- assertThat(fromDb.getName()).isEqualTo(person.getName());
- }
-}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-exercise/.gitignore b/2019-11/spring-09/jpql-class-work/jpql-exercise/.gitignore
similarity index 100%
rename from 2019-11/spring-09/jpql-class-work/jpql-demo-exercise/.gitignore
rename to 2019-11/spring-09/jpql-class-work/jpql-exercise/.gitignore
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/pom.xml b/2019-11/spring-09/jpql-class-work/jpql-exercise/pom.xml
similarity index 66%
rename from 2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/pom.xml
rename to 2019-11/spring-09/jpql-class-work/jpql-exercise/pom.xml
index 1d55a432..f3ca4c59 100644
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-final/pom.xml
+++ b/2019-11/spring-09/jpql-class-work/jpql-exercise/pom.xml
@@ -5,7 +5,7 @@
4.0.0
ru.otus
- jpql-demo-solution-step-final
+ jpql-exercise
1.0-SNAPSHOT
@@ -20,10 +20,6 @@
-
- org.springframework.boot
- spring-boot-starter
-
org.springframework.boot
spring-boot-starter-data-jpa
@@ -32,11 +28,34 @@
com.h2database
h2
+ runtime
+
+
+
+ org.projectlombok
+ lombok
+ true
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
diff --git a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
rename to 2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
diff --git a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/models/common/Avatar.java b/2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
similarity index 89%
rename from 2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/models/common/Avatar.java
rename to 2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
index 2ed2b5f8..e54749c2 100644
--- a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/models/common/Avatar.java
+++ b/2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
@@ -1,4 +1,4 @@
-package ru.otus.example.ormdemo.models.common;
+package ru.otus.example.ormdemo.models;
import lombok.AllArgsConstructor;
import lombok.Data;
diff --git a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/models/common/Course.java b/2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/models/Course.java
similarity index 89%
rename from 2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/models/common/Course.java
rename to 2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/models/Course.java
index 6ce8b993..cfb3c968 100644
--- a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/models/common/Course.java
+++ b/2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/models/Course.java
@@ -1,4 +1,4 @@
-package ru.otus.example.ormdemo.models.common;
+package ru.otus.example.ormdemo.models;
import lombok.AllArgsConstructor;
import lombok.Data;
diff --git a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/models/common/EMail.java b/2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/models/EMail.java
similarity index 89%
rename from 2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/models/common/EMail.java
rename to 2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/models/EMail.java
index 1bc8cf74..7e2d6dde 100644
--- a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/models/common/EMail.java
+++ b/2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/models/EMail.java
@@ -1,4 +1,4 @@
-package ru.otus.example.ormdemo.models.common;
+package ru.otus.example.ormdemo.models;
import lombok.AllArgsConstructor;
import lombok.Data;
diff --git a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/models/OtusStudent.java b/2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
similarity index 86%
rename from 2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/models/OtusStudent.java
rename to 2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
index 534d051e..f3822503 100644
--- a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/models/OtusStudent.java
+++ b/2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
@@ -1,8 +1,6 @@
-package ru.otus.example.replaceormproviderdemo.models;
+package ru.otus.example.ormdemo.models;
import lombok.*;
-import org.eclipse.persistence.annotations.BatchFetch;
-import org.eclipse.persistence.annotations.BatchFetchType;
import javax.persistence.*;
import java.util.List;
@@ -33,8 +31,7 @@ public class OtusStudent {
private List emails;
// Указывает на связь между таблицами "многие ко многим"
- @BatchFetch(value = BatchFetchType.IN)
- @ManyToMany(targetEntity = Course.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
+ @ManyToMany(targetEntity = Course.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
// Задает таблицу связей между таблицами для хранения родительской и связанной сущностью
@JoinTable(name = "student_courses", joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id"))
diff --git a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpa.java b/2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpa.java
similarity index 71%
rename from 2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpa.java
rename to 2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpa.java
index ba9eedda..dc773e5a 100644
--- a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpa.java
+++ b/2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpa.java
@@ -7,8 +7,12 @@ import java.util.List;
import java.util.Optional;
public interface OtusStudentRepositoryJpa {
- Optional findById(long id);
- List findAll();
OtusStudent save(OtusStudent student);
+ Optional findById(long id);
+ List findAll();
+ List findByName(String name);
+
+ void updateNameById(long id, String name);
+ void deleteById(long id);
}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImpl.java b/2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImpl.java
new file mode 100644
index 00000000..0603a405
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImpl.java
@@ -0,0 +1,49 @@
+package ru.otus.example.ormdemo.repositories;
+
+import org.springframework.stereotype.Repository;
+import ru.otus.example.ormdemo.models.OtusStudent;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+import javax.persistence.TypedQuery;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+@Repository
+public class OtusStudentRepositoryJpaImpl implements OtusStudentRepositoryJpa {
+
+ @PersistenceContext
+ private EntityManager em;
+
+ @Override
+ public OtusStudent save(OtusStudent student) {
+ return null;
+ }
+
+ @Override
+ public Optional findById(long id) {
+ return Optional.empty();
+ }
+
+ @Override
+ public List findAll() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List findByName(String name) {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public void updateNameById(long id, String name) {
+
+ }
+
+ @Override
+ public void deleteById(long id) {
+ }
+
+}
diff --git a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/resources/schema.sql b/2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/resources/schema.sql
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/resources/schema.sql
rename to 2019-11/spring-09/jpql-class-work/jpql-exercise/src/main/resources/schema.sql
diff --git a/2019-11/spring-08/orm-class-work/orm-demo/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java b/2019-11/spring-09/jpql-class-work/jpql-exercise/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java
similarity index 68%
rename from 2019-11/spring-08/orm-class-work/orm-demo/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java
rename to 2019-11/spring-09/jpql-class-work/jpql-exercise/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java
index 7c9ca9f3..9cad9ee7 100644
--- a/2019-11/spring-08/orm-class-work/orm-demo/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java
+++ b/2019-11/spring-09/jpql-class-work/jpql-exercise/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java
@@ -9,21 +9,23 @@ import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.context.annotation.Import;
import ru.otus.example.ormdemo.models.OtusStudent;
-import ru.otus.example.ormdemo.models.common.Avatar;
-import ru.otus.example.ormdemo.models.common.Course;
-import ru.otus.example.ormdemo.models.common.EMail;
+import ru.otus.example.ormdemo.models.Avatar;
+import ru.otus.example.ormdemo.models.Course;
+import ru.otus.example.ormdemo.models.EMail;
import java.util.Collections;
+import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@DisplayName("Репозиторий на основе Jpa для работы со студентами ")
@DataJpaTest
-@Import({OtusStudentRepositoryJpaImpl.class, CourseRepositoryJpaImpl.class})
+@Import(OtusStudentRepositoryJpaImpl.class)
class OtusStudentRepositoryJpaImplTest {
private static final int EXPECTED_NUMBER_OF_STUDENTS = 10;
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;
@@ -35,13 +37,10 @@ class OtusStudentRepositoryJpaImplTest {
@Autowired
private OtusStudentRepositoryJpaImpl repositoryJpa;
- @Autowired
- private CourseRepositoryJpaImpl courseRepositoryJpa;
-
@Autowired
private TestEntityManager em;
- @DisplayName(" должен загружать информацию о нужном студенте")
+ @DisplayName(" должен загружать информацию о нужном студенте по его id")
@Test
void shouldFindExpectedStudentById() {
val optionalActualStudent = repositoryJpa.findById(FIRST_STUDENT_ID);
@@ -78,7 +77,6 @@ class OtusStudentRepositoryJpaImplTest {
val course = new Course(0, COURSE_NAME);
val courses = Collections.singletonList(course);
- //courseRepositoryJpa.save(course);
val vasya = new OtusStudent(0, STUDENT_NAME, avatar, emails, courses);
@@ -91,4 +89,38 @@ class OtusStudentRepositoryJpaImplTest {
.matches(s -> s.getAvatar() != null)
.matches(s -> s.getEmails() != null && s.getEmails().size() > 0);
}
+
+ @DisplayName(" должен загружать информацию о нужном студенте по его имени")
+ @Test
+ void shouldFindExpectedStudentByName() {
+ val firstStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
+ List students = repositoryJpa.findByName(FIRST_STUDENT_NAME);
+ assertThat(students).containsOnlyOnce(firstStudent);
+ }
+
+ @DisplayName(" должен изменять имя заданного студента по его id")
+ @Test
+ void shouldUpdateStudentNameById() {
+ val firstStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
+ String oldName = firstStudent.getName();
+ em.detach(firstStudent);
+
+ repositoryJpa.updateNameById(FIRST_STUDENT_ID, STUDENT_NAME);
+ val updatedStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
+
+ assertThat(updatedStudent.getName()).isNotEqualTo(oldName).isEqualTo(STUDENT_NAME);
+ }
+
+ @DisplayName(" должен удалять заданного студента по его id")
+ @Test
+ void shouldDeleteStudentNameById() {
+ val firstStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
+ assertThat(firstStudent).isNotNull();
+ em.detach(firstStudent);
+
+ repositoryJpa.deleteById(FIRST_STUDENT_ID);
+ val deletedStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
+
+ assertThat(deletedStudent).isNull();
+ }
}
\ No newline at end of file
diff --git a/2019-11/spring-08/orm-class-work/orm-demo/src/test/resources/application.yml b/2019-11/spring-09/jpql-class-work/jpql-exercise/src/test/resources/application.yml
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/orm-demo/src/test/resources/application.yml
rename to 2019-11/spring-09/jpql-class-work/jpql-exercise/src/test/resources/application.yml
diff --git a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/test/resources/data.sql b/2019-11/spring-09/jpql-class-work/jpql-exercise/src/test/resources/data.sql
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/test/resources/data.sql
rename to 2019-11/spring-09/jpql-class-work/jpql-exercise/src/test/resources/data.sql
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-1/.gitignore b/2019-11/spring-09/jpql-class-work/jpql-solution-01/.gitignore
similarity index 100%
rename from 2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-1/.gitignore
rename to 2019-11/spring-09/jpql-class-work/jpql-solution-01/.gitignore
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-exercise/pom.xml b/2019-11/spring-09/jpql-class-work/jpql-solution-01/pom.xml
similarity index 66%
rename from 2019-11/spring-09/jpql-class-work/jpql-demo-exercise/pom.xml
rename to 2019-11/spring-09/jpql-class-work/jpql-solution-01/pom.xml
index 8913efa2..004c59c2 100644
--- a/2019-11/spring-09/jpql-class-work/jpql-demo-exercise/pom.xml
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-01/pom.xml
@@ -5,7 +5,7 @@
4.0.0
ru.otus
- jpql-demo-exercise
+ jpql-solution-01
1.0-SNAPSHOT
@@ -20,22 +20,42 @@
-
- org.springframework.boot
- spring-boot-starter
-
org.springframework.boot
spring-boot-starter-data-jpa
+
com.h2database
h2
+ runtime
+
+
+
+ org.projectlombok
+ lombok
+ true
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
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
new file mode 100644
index 00000000..8d4b413c
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
@@ -0,0 +1,13 @@
+package ru.otus.example.ormdemo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class OrmDemoApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(OrmDemoApplication.class, args);
+ }
+
+}
diff --git a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/models/Avatar.java b/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
similarity index 87%
rename from 2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/models/Avatar.java
rename to 2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
index 1a619456..e54749c2 100644
--- a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/models/Avatar.java
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
@@ -1,4 +1,4 @@
-package ru.otus.example.replaceormproviderdemo.models;
+package ru.otus.example.ormdemo.models;
import lombok.AllArgsConstructor;
import lombok.Data;
diff --git a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/models/Course.java b/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/models/Course.java
similarity index 87%
rename from 2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/models/Course.java
rename to 2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/models/Course.java
index caecc0c5..cfb3c968 100644
--- a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/models/Course.java
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/models/Course.java
@@ -1,4 +1,4 @@
-package ru.otus.example.replaceormproviderdemo.models;
+package ru.otus.example.ormdemo.models;
import lombok.AllArgsConstructor;
import lombok.Data;
diff --git a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/models/EMail.java b/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/models/EMail.java
similarity index 87%
rename from 2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/models/EMail.java
rename to 2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/models/EMail.java
index 8c69afe8..7e2d6dde 100644
--- a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/models/EMail.java
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/models/EMail.java
@@ -1,4 +1,4 @@
-package ru.otus.example.replaceormproviderdemo.models;
+package ru.otus.example.ormdemo.models;
import lombok.AllArgsConstructor;
import lombok.Data;
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
new file mode 100644
index 00000000..f3822503
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
@@ -0,0 +1,39 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.*;
+
+import javax.persistence.*;
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity // Указывает, что данный класс является сущностью
+@Table(name = "otus_students") // Задает имя таблицы, на которую будет отображаться сущность
+public class OtusStudent {
+ @Id // Позволяет указать какое поле является идентификатором
+ @GeneratedValue(strategy = GenerationType.IDENTITY) // Стратегия генерации идентификаторов
+ private long id;
+
+ // Задает имя и некоторые свойства поля таблицы, на которое будет отображаться поле сущности
+ @Column(name = "name", nullable = false, unique = true)
+ private String name;
+
+ // Указывает на связь между таблицами "один к одному"
+ @OneToOne(targetEntity = Avatar.class, cascade = CascadeType.ALL)
+ // Задает поле, по которому происходит объединение с таблицей для хранения связанной сущности
+ @JoinColumn(name = "avatar_id")
+ private Avatar avatar;
+
+ // Указывает на связь между таблицами "один ко многим"
+ @OneToMany(targetEntity = EMail.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+ @JoinColumn(name = "student_id")
+ private List emails;
+
+ // Указывает на связь между таблицами "многие ко многим"
+ @ManyToMany(targetEntity = Course.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
+ // Задает таблицу связей между таблицами для хранения родительской и связанной сущностью
+ @JoinTable(name = "student_courses", joinColumns = @JoinColumn(name = "student_id"),
+ inverseJoinColumns = @JoinColumn(name = "course_id"))
+ private List courses;
+}
diff --git a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/repositories/OtusStudentRepositoryJpa.java b/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpa.java
similarity index 50%
rename from 2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/repositories/OtusStudentRepositoryJpa.java
rename to 2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpa.java
index ed2eaf3d..dc773e5a 100644
--- a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/repositories/OtusStudentRepositoryJpa.java
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpa.java
@@ -1,17 +1,18 @@
-package ru.otus.example.replaceormproviderdemo.repositories;
+package ru.otus.example.ormdemo.repositories;
-import ru.otus.example.replaceormproviderdemo.models.OtusStudent;
+import ru.otus.example.ormdemo.models.OtusStudent;
import java.util.List;
import java.util.Optional;
public interface OtusStudentRepositoryJpa {
- Optional findById(long id);
- List findAll();
-
- List findAllWithJoinFetch();
-
OtusStudent save(OtusStudent student);
+ Optional findById(long id);
+ List findAll();
+ List findByName(String name);
+
+ void updateNameById(long id, String name);
+ void deleteById(long id);
}
diff --git a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImpl.java b/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImpl.java
similarity index 68%
rename from 2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImpl.java
rename to 2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImpl.java
index 5d4760cc..6a11279c 100644
--- a/2019-11/spring-08/orm-class-work/orm-demo/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImpl.java
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImpl.java
@@ -5,6 +5,9 @@ import ru.otus.example.ormdemo.models.OtusStudent;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+import javax.persistence.TypedQuery;
+import java.util.Collections;
import java.util.List;
import java.util.Optional;
@@ -14,16 +17,6 @@ public class OtusStudentRepositoryJpaImpl implements OtusStudentRepositoryJpa {
@PersistenceContext
private EntityManager em;
- @Override
- public Optional findById(long id) {
- return Optional.ofNullable(em.find(OtusStudent.class, id));
- }
-
- @Override
- public List findAll() {
- return em.createQuery("select s from OtusStudent s", OtusStudent.class).getResultList();
- }
-
@Override
public OtusStudent save(OtusStudent student) {
if (student.getId() <= 0) {
@@ -33,4 +26,30 @@ public class OtusStudentRepositoryJpaImpl implements OtusStudentRepositoryJpa {
return em.merge(student);
}
}
+
+ @Override
+ public Optional findById(long id) {
+ return Optional.ofNullable(em.find(OtusStudent.class, id));
+ }
+
+ @Override
+ public List findAll() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List findByName(String name) {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public void updateNameById(long id, String name) {
+
+ }
+
+ @Override
+ public void deleteById(long id) {
+
+ }
+
}
diff --git a/2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/resources/schema.sql b/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/resources/schema.sql
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/main/resources/schema.sql
rename to 2019-11/spring-09/jpql-class-work/jpql-solution-01/src/main/resources/schema.sql
diff --git a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/test/java/ru/otus/example/replaceormproviderdemo/repositories/OtusStudentRepositoryJpaImplTest.java b/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java
similarity index 60%
rename from 2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/test/java/ru/otus/example/replaceormproviderdemo/repositories/OtusStudentRepositoryJpaImplTest.java
rename to 2019-11/spring-09/jpql-class-work/jpql-solution-01/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java
index 2f9b2c1e..9cad9ee7 100644
--- a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/test/java/ru/otus/example/replaceormproviderdemo/repositories/OtusStudentRepositoryJpaImplTest.java
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java
@@ -1,16 +1,17 @@
-package ru.otus.example.replaceormproviderdemo.repositories;
+package ru.otus.example.ormdemo.repositories;
import lombok.val;
+import org.hibernate.SessionFactory;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.context.annotation.Import;
-import ru.otus.example.replaceormproviderdemo.models.OtusStudent;
-import ru.otus.example.replaceormproviderdemo.models.Avatar;
-import ru.otus.example.replaceormproviderdemo.models.Course;
-import ru.otus.example.replaceormproviderdemo.models.EMail;
+import ru.otus.example.ormdemo.models.OtusStudent;
+import ru.otus.example.ormdemo.models.Avatar;
+import ru.otus.example.ormdemo.models.Course;
+import ru.otus.example.ormdemo.models.EMail;
import java.util.Collections;
import java.util.List;
@@ -19,11 +20,14 @@ import static org.assertj.core.api.Assertions.assertThat;
@DisplayName("Репозиторий на основе Jpa для работы со студентами ")
@DataJpaTest
-@Import({OtusStudentRepositoryJpaImpl.class})
+@Import(OtusStudentRepositoryJpaImpl.class)
class OtusStudentRepositoryJpaImplTest {
private static final int EXPECTED_NUMBER_OF_STUDENTS = 10;
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 String STUDENT_AVATAR_URL = "где-то там";
private static final String STUDENT_EMAIL = "any@mail.com";
@@ -36,7 +40,7 @@ class OtusStudentRepositoryJpaImplTest {
@Autowired
private TestEntityManager em;
- @DisplayName(" должен загружать информацию о нужном студенте")
+ @DisplayName(" должен загружать информацию о нужном студенте по его id")
@Test
void shouldFindExpectedStudentById() {
val optionalActualStudent = repositoryJpa.findById(FIRST_STUDENT_ID);
@@ -48,6 +52,11 @@ class OtusStudentRepositoryJpaImplTest {
@DisplayName("должен загружать список всех студентов с полной информацией о них")
@Test
void shouldReturnCorrectStudentsListWithAllInfo() {
+ SessionFactory sessionFactory = em.getEntityManager().getEntityManagerFactory()
+ .unwrap(SessionFactory.class);
+ sessionFactory.getStatistics().setStatisticsEnabled(true);
+
+
System.out.println("\n\n\n\n----------------------------------------------------------------------------------------------------------");
val students = repositoryJpa.findAll();
assertThat(students).isNotNull().hasSize(EXPECTED_NUMBER_OF_STUDENTS)
@@ -56,22 +65,9 @@ class OtusStudentRepositoryJpaImplTest {
.allMatch(s -> s.getAvatar() != null)
.allMatch(s -> s.getEmails() != null && s.getEmails().size() > 0);
System.out.println("----------------------------------------------------------------------------------------------------------\n\n\n\n");
+ assertThat(sessionFactory.getStatistics().getPrepareStatementCount()).isEqualTo(EXPECTED_QUERIES_COUNT);
}
- @DisplayName(" с помощью 'join fetch' должен загружать список всех студентов с полной информацией о них")
- @Test
- void usingJoinFetchShouldReturnCorrectStudentsListWithWithAllInfo() {
- System.out.println("\n\n\n\n----------------------------------------------------------------------------------------------------------");
- List students = repositoryJpa.findAllWithJoinFetch();
- assertThat(students).isNotNull().hasSize(EXPECTED_NUMBER_OF_STUDENTS)
- .allMatch(s -> !s.getName().equals(""))
- .allMatch(s -> s.getCourses() != null && s.getCourses().size() > 0)
- .allMatch(s -> s.getAvatar() != null)
- .allMatch(s -> s.getEmails() != null && s.getEmails().size() > 0);
- System.out.println("----------------------------------------------------------------------------------------------------------\n\n\n\n");
- }
-
-
@DisplayName(" должен корректно сохранять всю информацию о студенте")
@Test
void shouldSaveAllStudentInfo() {
@@ -81,6 +77,8 @@ class OtusStudentRepositoryJpaImplTest {
val course = new Course(0, COURSE_NAME);
val courses = Collections.singletonList(course);
+
+
val vasya = new OtusStudent(0, STUDENT_NAME, avatar, emails, courses);
repositoryJpa.save(vasya);
assertThat(vasya.getId()).isGreaterThan(0);
@@ -91,4 +89,38 @@ class OtusStudentRepositoryJpaImplTest {
.matches(s -> s.getAvatar() != null)
.matches(s -> s.getEmails() != null && s.getEmails().size() > 0);
}
+
+ @DisplayName(" должен загружать информацию о нужном студенте по его имени")
+ @Test
+ void shouldFindExpectedStudentByName() {
+ val firstStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
+ List students = repositoryJpa.findByName(FIRST_STUDENT_NAME);
+ assertThat(students).containsOnlyOnce(firstStudent);
+ }
+
+ @DisplayName(" должен изменять имя заданного студента по его id")
+ @Test
+ void shouldUpdateStudentNameById() {
+ val firstStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
+ String oldName = firstStudent.getName();
+ em.detach(firstStudent);
+
+ repositoryJpa.updateNameById(FIRST_STUDENT_ID, STUDENT_NAME);
+ val updatedStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
+
+ assertThat(updatedStudent.getName()).isNotEqualTo(oldName).isEqualTo(STUDENT_NAME);
+ }
+
+ @DisplayName(" должен удалять заданного студента по его id")
+ @Test
+ void shouldDeleteStudentNameById() {
+ val firstStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
+ assertThat(firstStudent).isNotNull();
+ em.detach(firstStudent);
+
+ repositoryJpa.deleteById(FIRST_STUDENT_ID);
+ val deletedStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
+
+ assertThat(deletedStudent).isNull();
+ }
}
\ No newline at end of file
diff --git a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/test/resources/application.yml b/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/test/resources/application.yml
similarity index 92%
rename from 2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/test/resources/application.yml
rename to 2019-11/spring-09/jpql-class-work/jpql-solution-01/src/test/resources/application.yml
index b98cd926..d2b811a4 100644
--- a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/test/resources/application.yml
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/test/resources/application.yml
@@ -4,7 +4,6 @@ spring:
initialization-mode: always
jpa:
- show-sql: false
generate-ddl: false
#generate-ddl: true
hibernate:
diff --git a/2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/test/resources/data.sql b/2019-11/spring-09/jpql-class-work/jpql-solution-01/src/test/resources/data.sql
similarity index 100%
rename from 2019-11/spring-08/orm-class-work/spring-jdbc-demo/src/test/resources/data.sql
rename to 2019-11/spring-09/jpql-class-work/jpql-solution-01/src/test/resources/data.sql
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-2/.gitignore b/2019-11/spring-09/jpql-class-work/jpql-solution-02/.gitignore
similarity index 100%
rename from 2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-2/.gitignore
rename to 2019-11/spring-09/jpql-class-work/jpql-solution-02/.gitignore
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-02/pom.xml b/2019-11/spring-09/jpql-class-work/jpql-solution-02/pom.xml
new file mode 100644
index 00000000..6e0370b6
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-02/pom.xml
@@ -0,0 +1,70 @@
+
+
+ 4.0.0
+
+ ru.otus
+ jpql-solution-02
+ 1.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.2.1.RELEASE
+
+
+
+ 11
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ com.h2database
+ h2
+ runtime
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+ 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.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
new file mode 100644
index 00000000..8d4b413c
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
@@ -0,0 +1,13 @@
+package ru.otus.example.ormdemo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class OrmDemoApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(OrmDemoApplication.class, args);
+ }
+
+}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/models/Avatar.java b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
new file mode 100644
index 00000000..e54749c2
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
@@ -0,0 +1,21 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "avatars")
+public class Avatar {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Column(name = "photo_url", nullable = false, unique = true)
+ private String photoUrl;
+}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/models/Course.java b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/models/Course.java
new file mode 100644
index 00000000..cfb3c968
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/models/Course.java
@@ -0,0 +1,21 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "courses")
+public class Course {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Column(name = "name", nullable = false, unique = true)
+ private String name;
+}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/models/EMail.java b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/models/EMail.java
new file mode 100644
index 00000000..7e2d6dde
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/models/EMail.java
@@ -0,0 +1,22 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "emails")
+public class EMail {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Column(name = "email", nullable = false, unique = true)
+ private String email;
+}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
new file mode 100644
index 00000000..f3822503
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
@@ -0,0 +1,39 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.*;
+
+import javax.persistence.*;
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity // Указывает, что данный класс является сущностью
+@Table(name = "otus_students") // Задает имя таблицы, на которую будет отображаться сущность
+public class OtusStudent {
+ @Id // Позволяет указать какое поле является идентификатором
+ @GeneratedValue(strategy = GenerationType.IDENTITY) // Стратегия генерации идентификаторов
+ private long id;
+
+ // Задает имя и некоторые свойства поля таблицы, на которое будет отображаться поле сущности
+ @Column(name = "name", nullable = false, unique = true)
+ private String name;
+
+ // Указывает на связь между таблицами "один к одному"
+ @OneToOne(targetEntity = Avatar.class, cascade = CascadeType.ALL)
+ // Задает поле, по которому происходит объединение с таблицей для хранения связанной сущности
+ @JoinColumn(name = "avatar_id")
+ private Avatar avatar;
+
+ // Указывает на связь между таблицами "один ко многим"
+ @OneToMany(targetEntity = EMail.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+ @JoinColumn(name = "student_id")
+ private List emails;
+
+ // Указывает на связь между таблицами "многие ко многим"
+ @ManyToMany(targetEntity = Course.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
+ // Задает таблицу связей между таблицами для хранения родительской и связанной сущностью
+ @JoinTable(name = "student_courses", joinColumns = @JoinColumn(name = "student_id"),
+ inverseJoinColumns = @JoinColumn(name = "course_id"))
+ private List courses;
+}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpa.java b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpa.java
new file mode 100644
index 00000000..dc773e5a
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpa.java
@@ -0,0 +1,18 @@
+package ru.otus.example.ormdemo.repositories;
+
+
+import ru.otus.example.ormdemo.models.OtusStudent;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface OtusStudentRepositoryJpa {
+ OtusStudent save(OtusStudent student);
+ Optional findById(long id);
+
+ List findAll();
+ List findByName(String name);
+
+ void updateNameById(long id, String name);
+ void deleteById(long id);
+}
diff --git a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/repositories/OtusStudentRepositoryJpaImpl.java b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImpl.java
similarity index 60%
rename from 2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/repositories/OtusStudentRepositoryJpaImpl.java
rename to 2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImpl.java
index 196c40a4..8266c9ec 100644
--- a/2019-11/spring-08/orm-class-work/replace-orm-provider-demo/src/main/java/ru/otus/example/replaceormproviderdemo/repositories/OtusStudentRepositoryJpaImpl.java
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImpl.java
@@ -1,11 +1,11 @@
-package ru.otus.example.replaceormproviderdemo.repositories;
+package ru.otus.example.ormdemo.repositories;
-import org.eclipse.persistence.config.QueryHints;
import org.springframework.stereotype.Repository;
-import ru.otus.example.replaceormproviderdemo.models.OtusStudent;
+import ru.otus.example.ormdemo.models.OtusStudent;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
import javax.persistence.TypedQuery;
import java.util.List;
import java.util.Optional;
@@ -13,11 +13,19 @@ import java.util.Optional;
@Repository
public class OtusStudentRepositoryJpaImpl implements OtusStudentRepositoryJpa {
- private static final int DEFAULT_BATCH_SIZE = 5;
-
@PersistenceContext
private EntityManager em;
+ @Override
+ public OtusStudent save(OtusStudent student) {
+ if (student.getId() <= 0) {
+ em.persist(student);
+ return student;
+ } else {
+ return em.merge(student);
+ }
+ }
+
@Override
public Optional findById(long id) {
return Optional.ofNullable(em.find(OtusStudent.class, id));
@@ -25,25 +33,28 @@ public class OtusStudentRepositoryJpaImpl implements OtusStudentRepositoryJpa {
@Override
public List findAll() {
- return em.createQuery("select s from OtusStudent s", OtusStudent.class).getResultList();
+ return em.createQuery("select s from OtusStudent s", OtusStudent.class)
+ .getResultList();
}
@Override
- public List findAllWithJoinFetch() {
- TypedQuery query = em.createQuery("select distinct s from OtusStudent s join fetch s.avatar join fetch s.emails", OtusStudent.class);
- query.setHint(QueryHints.BATCH_SIZE, DEFAULT_BATCH_SIZE);
+ public List findByName(String name) {
+ 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) {
+
+ }
@Override
- public OtusStudent save(OtusStudent student) {
- if (student.getId() <= 0) {
- em.persist(student);
- //em.flush();
- return student;
- } else {
- return em.merge(student);
- }
+ public void deleteById(long id) {
+
}
+
}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/resources/schema.sql b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/resources/schema.sql
new file mode 100644
index 00000000..43a684bb
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/main/resources/schema.sql
@@ -0,0 +1,31 @@
+create table avatars(
+ id bigserial,
+ photo_url varchar(8000),
+ primary key (id)
+);
+
+create table courses(
+ id bigserial,
+ name varchar(255),
+ primary key (id)
+);
+
+create table otus_students(
+ id bigserial,
+ name varchar(255),
+ avatar_id bigint references avatars (id),
+ primary key (id)
+);
+
+create table emails(
+ id bigserial,
+ student_id bigint references otus_students(id) on delete cascade,
+ email varchar(255),
+ primary key (id)
+);
+
+create table student_courses(
+ student_id bigint references otus_students(id) on delete cascade,
+ course_id bigint references courses(id),
+ primary key (student_id, course_id)
+);
\ No newline at end of file
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java
new file mode 100644
index 00000000..9cad9ee7
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java
@@ -0,0 +1,126 @@
+package ru.otus.example.ormdemo.repositories;
+
+import lombok.val;
+import org.hibernate.SessionFactory;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
+import org.springframework.context.annotation.Import;
+import ru.otus.example.ormdemo.models.OtusStudent;
+import ru.otus.example.ormdemo.models.Avatar;
+import ru.otus.example.ormdemo.models.Course;
+import ru.otus.example.ormdemo.models.EMail;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@DisplayName("Репозиторий на основе Jpa для работы со студентами ")
+@DataJpaTest
+@Import(OtusStudentRepositoryJpaImpl.class)
+class OtusStudentRepositoryJpaImplTest {
+
+ private static final int EXPECTED_NUMBER_OF_STUDENTS = 10;
+ 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 String STUDENT_AVATAR_URL = "где-то там";
+ private static final String STUDENT_EMAIL = "any@mail.com";
+ private static final String COURSE_NAME = "Spring";
+ private static final String STUDENT_NAME = "Вася";
+
+ @Autowired
+ private OtusStudentRepositoryJpaImpl repositoryJpa;
+
+ @Autowired
+ private TestEntityManager em;
+
+ @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()
+ .isEqualToComparingFieldByField(expectedStudent);
+ }
+
+ @DisplayName("должен загружать список всех студентов с полной информацией о них")
+ @Test
+ void shouldReturnCorrectStudentsListWithAllInfo() {
+ SessionFactory sessionFactory = em.getEntityManager().getEntityManagerFactory()
+ .unwrap(SessionFactory.class);
+ sessionFactory.getStatistics().setStatisticsEnabled(true);
+
+
+ System.out.println("\n\n\n\n----------------------------------------------------------------------------------------------------------");
+ val students = repositoryJpa.findAll();
+ assertThat(students).isNotNull().hasSize(EXPECTED_NUMBER_OF_STUDENTS)
+ .allMatch(s -> !s.getName().equals(""))
+ .allMatch(s -> s.getCourses() != null && s.getCourses().size() > 0)
+ .allMatch(s -> s.getAvatar() != null)
+ .allMatch(s -> s.getEmails() != null && s.getEmails().size() > 0);
+ System.out.println("----------------------------------------------------------------------------------------------------------\n\n\n\n");
+ assertThat(sessionFactory.getStatistics().getPrepareStatementCount()).isEqualTo(EXPECTED_QUERIES_COUNT);
+ }
+
+ @DisplayName(" должен корректно сохранять всю информацию о студенте")
+ @Test
+ void shouldSaveAllStudentInfo() {
+ val avatar = new Avatar(0, STUDENT_AVATAR_URL);
+ val email = new EMail(0, STUDENT_EMAIL);
+ val emails = Collections.singletonList(email);
+
+ val course = new Course(0, COURSE_NAME);
+ val courses = Collections.singletonList(course);
+
+
+ val vasya = new OtusStudent(0, STUDENT_NAME, avatar, emails, courses);
+ repositoryJpa.save(vasya);
+ assertThat(vasya.getId()).isGreaterThan(0);
+
+ val actualStudent = em.find(OtusStudent.class, vasya.getId());
+ assertThat(actualStudent).isNotNull().matches(s -> !s.getName().equals(""))
+ .matches(s -> s.getCourses() != null && s.getCourses().size() > 0 && s.getCourses().get(0).getId() > 0)
+ .matches(s -> s.getAvatar() != null)
+ .matches(s -> s.getEmails() != null && s.getEmails().size() > 0);
+ }
+
+ @DisplayName(" должен загружать информацию о нужном студенте по его имени")
+ @Test
+ void shouldFindExpectedStudentByName() {
+ val firstStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
+ List students = repositoryJpa.findByName(FIRST_STUDENT_NAME);
+ assertThat(students).containsOnlyOnce(firstStudent);
+ }
+
+ @DisplayName(" должен изменять имя заданного студента по его id")
+ @Test
+ void shouldUpdateStudentNameById() {
+ val firstStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
+ String oldName = firstStudent.getName();
+ em.detach(firstStudent);
+
+ repositoryJpa.updateNameById(FIRST_STUDENT_ID, STUDENT_NAME);
+ val updatedStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
+
+ assertThat(updatedStudent.getName()).isNotEqualTo(oldName).isEqualTo(STUDENT_NAME);
+ }
+
+ @DisplayName(" должен удалять заданного студента по его id")
+ @Test
+ void shouldDeleteStudentNameById() {
+ val firstStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
+ assertThat(firstStudent).isNotNull();
+ em.detach(firstStudent);
+
+ repositoryJpa.deleteById(FIRST_STUDENT_ID);
+ val deletedStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
+
+ assertThat(deletedStudent).isNull();
+ }
+}
\ No newline at end of file
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/test/resources/application.yml b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/test/resources/application.yml
new file mode 100644
index 00000000..d2b811a4
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/test/resources/application.yml
@@ -0,0 +1,17 @@
+spring:
+ datasource:
+ url: jdbc:h2:mem:testdb
+ initialization-mode: always
+
+ jpa:
+ generate-ddl: false
+ #generate-ddl: true
+ hibernate:
+ ddl-auto: none
+ #ddl-auto: create-drop
+
+ #show-sql: true
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/test/resources/data.sql b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/test/resources/data.sql
new file mode 100644
index 00000000..a8db6b85
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-02/src/test/resources/data.sql
@@ -0,0 +1,29 @@
+insert into avatars(photo_url)
+values ('photoUrl_01'), ('photoUrl_02'), ('photoUrl_03'), ('photoUrl_04'), ('photoUrl_05'),
+ ('photoUrl_06'), ('photoUrl_07'), ('photoUrl_08'), ('photoUrl_09'), ('photoUrl_10');
+
+insert into courses(name)
+values ('course_name_01'), ('course_name_02'), ('course_name_03'), ('course_name_04'), ('course_name_05'),
+ ('course_name_06'), ('course_name_07'), ('course_name_08'), ('course_name_09'), ('course_name_10'), ('not_used_11');
+
+insert into otus_students(name, avatar_id)
+values ('student_01', 1), ('student_02', 2), ('student_03', 3), ('student_04', 4), ('student_05', 5),
+ ('student_06', 6), ('student_07', 7), ('student_08', 8), ('student_09', 9), ('student_10', 10);
+
+
+insert into emails(email, student_id)
+values ('email_01', 1), ('email_02', 1), ('email_03', 2), ('email_04', 2), ('email_05', 3), ('email_06', 4),
+ ('email_07', 5), ('email_08', 6), ('email_09', 7), ('email_10', 8), ('email_11', 9), ('email_12', 10);
+
+
+insert into student_courses(student_id, course_id)
+values (1, 1), (1, 2), (1, 3),
+ (2, 2), (2, 4), (2, 5),
+ (3, 3), (3, 6), (3, 7),
+ (4, 4), (4, 8), (4, 9),
+ (5, 5), (5, 10), (5, 1),
+ (6, 6), (6, 2), (6, 3),
+ (7, 7), (7, 4), (7, 5),
+ (8, 8), (8, 6), (8, 7),
+ (9, 9), (9, 8), (9, 10),
+ (10, 10), (10, 1), (10, 2);
diff --git a/2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-3/.gitignore b/2019-11/spring-09/jpql-class-work/jpql-solution-final/.gitignore
similarity index 100%
rename from 2019-11/spring-09/jpql-class-work/jpql-demo-solution-step-3/.gitignore
rename to 2019-11/spring-09/jpql-class-work/jpql-solution-final/.gitignore
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-final/pom.xml b/2019-11/spring-09/jpql-class-work/jpql-solution-final/pom.xml
new file mode 100644
index 00000000..a046b278
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-final/pom.xml
@@ -0,0 +1,70 @@
+
+
+ 4.0.0
+
+ ru.otus
+ jpql-solution-final
+ 1.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.2.1.RELEASE
+
+
+
+ 11
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ com.h2database
+ h2
+ runtime
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+ 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.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
new file mode 100644
index 00000000..8d4b413c
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java
@@ -0,0 +1,13 @@
+package ru.otus.example.ormdemo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class OrmDemoApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(OrmDemoApplication.class, args);
+ }
+
+}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/models/Avatar.java b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
new file mode 100644
index 00000000..e54749c2
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/models/Avatar.java
@@ -0,0 +1,21 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "avatars")
+public class Avatar {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Column(name = "photo_url", nullable = false, unique = true)
+ private String photoUrl;
+}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/models/Course.java b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/models/Course.java
new file mode 100644
index 00000000..cfb3c968
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/models/Course.java
@@ -0,0 +1,21 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "courses")
+public class Course {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Column(name = "name", nullable = false, unique = true)
+ private String name;
+}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/models/EMail.java b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/models/EMail.java
new file mode 100644
index 00000000..7e2d6dde
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/models/EMail.java
@@ -0,0 +1,22 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "emails")
+public class EMail {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Column(name = "email", nullable = false, unique = true)
+ private String email;
+}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
new file mode 100644
index 00000000..f3822503
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java
@@ -0,0 +1,39 @@
+package ru.otus.example.ormdemo.models;
+
+import lombok.*;
+
+import javax.persistence.*;
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity // Указывает, что данный класс является сущностью
+@Table(name = "otus_students") // Задает имя таблицы, на которую будет отображаться сущность
+public class OtusStudent {
+ @Id // Позволяет указать какое поле является идентификатором
+ @GeneratedValue(strategy = GenerationType.IDENTITY) // Стратегия генерации идентификаторов
+ private long id;
+
+ // Задает имя и некоторые свойства поля таблицы, на которое будет отображаться поле сущности
+ @Column(name = "name", nullable = false, unique = true)
+ private String name;
+
+ // Указывает на связь между таблицами "один к одному"
+ @OneToOne(targetEntity = Avatar.class, cascade = CascadeType.ALL)
+ // Задает поле, по которому происходит объединение с таблицей для хранения связанной сущности
+ @JoinColumn(name = "avatar_id")
+ private Avatar avatar;
+
+ // Указывает на связь между таблицами "один ко многим"
+ @OneToMany(targetEntity = EMail.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+ @JoinColumn(name = "student_id")
+ private List emails;
+
+ // Указывает на связь между таблицами "многие ко многим"
+ @ManyToMany(targetEntity = Course.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
+ // Задает таблицу связей между таблицами для хранения родительской и связанной сущностью
+ @JoinTable(name = "student_courses", joinColumns = @JoinColumn(name = "student_id"),
+ inverseJoinColumns = @JoinColumn(name = "course_id"))
+ private List courses;
+}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpa.java b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpa.java
new file mode 100644
index 00000000..dc773e5a
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpa.java
@@ -0,0 +1,18 @@
+package ru.otus.example.ormdemo.repositories;
+
+
+import ru.otus.example.ormdemo.models.OtusStudent;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface OtusStudentRepositoryJpa {
+ OtusStudent save(OtusStudent student);
+ Optional findById(long id);
+
+ List findAll();
+ List findByName(String name);
+
+ void updateNameById(long id, String name);
+ void deleteById(long id);
+}
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImpl.java b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImpl.java
new file mode 100644
index 00000000..014ae6ab
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImpl.java
@@ -0,0 +1,69 @@
+package ru.otus.example.ormdemo.repositories;
+
+import org.springframework.stereotype.Repository;
+import ru.otus.example.ormdemo.models.OtusStudent;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+import javax.persistence.TypedQuery;
+import java.util.List;
+import java.util.Optional;
+
+@Repository
+public class OtusStudentRepositoryJpaImpl implements OtusStudentRepositoryJpa {
+
+ @PersistenceContext
+ private EntityManager em;
+
+ @Override
+ public OtusStudent save(OtusStudent student) {
+ if (student.getId() <= 0) {
+ em.persist(student);
+ return student;
+ } else {
+ return em.merge(student);
+ }
+ }
+
+ @Override
+ public Optional findById(long id) {
+ return Optional.ofNullable(em.find(OtusStudent.class, id));
+ }
+
+ @Override
+ public List findAll() {
+ return em.createQuery("select s from OtusStudent s", OtusStudent.class)
+ .getResultList();
+ }
+
+ @Override
+ public List findByName(String name) {
+ 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/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/resources/schema.sql b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/resources/schema.sql
new file mode 100644
index 00000000..43a684bb
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/main/resources/schema.sql
@@ -0,0 +1,31 @@
+create table avatars(
+ id bigserial,
+ photo_url varchar(8000),
+ primary key (id)
+);
+
+create table courses(
+ id bigserial,
+ name varchar(255),
+ primary key (id)
+);
+
+create table otus_students(
+ id bigserial,
+ name varchar(255),
+ avatar_id bigint references avatars (id),
+ primary key (id)
+);
+
+create table emails(
+ id bigserial,
+ student_id bigint references otus_students(id) on delete cascade,
+ email varchar(255),
+ primary key (id)
+);
+
+create table student_courses(
+ student_id bigint references otus_students(id) on delete cascade,
+ course_id bigint references courses(id),
+ primary key (student_id, course_id)
+);
\ No newline at end of file
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java
new file mode 100644
index 00000000..9cad9ee7
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaImplTest.java
@@ -0,0 +1,126 @@
+package ru.otus.example.ormdemo.repositories;
+
+import lombok.val;
+import org.hibernate.SessionFactory;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
+import org.springframework.context.annotation.Import;
+import ru.otus.example.ormdemo.models.OtusStudent;
+import ru.otus.example.ormdemo.models.Avatar;
+import ru.otus.example.ormdemo.models.Course;
+import ru.otus.example.ormdemo.models.EMail;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@DisplayName("Репозиторий на основе Jpa для работы со студентами ")
+@DataJpaTest
+@Import(OtusStudentRepositoryJpaImpl.class)
+class OtusStudentRepositoryJpaImplTest {
+
+ private static final int EXPECTED_NUMBER_OF_STUDENTS = 10;
+ 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 String STUDENT_AVATAR_URL = "где-то там";
+ private static final String STUDENT_EMAIL = "any@mail.com";
+ private static final String COURSE_NAME = "Spring";
+ private static final String STUDENT_NAME = "Вася";
+
+ @Autowired
+ private OtusStudentRepositoryJpaImpl repositoryJpa;
+
+ @Autowired
+ private TestEntityManager em;
+
+ @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()
+ .isEqualToComparingFieldByField(expectedStudent);
+ }
+
+ @DisplayName("должен загружать список всех студентов с полной информацией о них")
+ @Test
+ void shouldReturnCorrectStudentsListWithAllInfo() {
+ SessionFactory sessionFactory = em.getEntityManager().getEntityManagerFactory()
+ .unwrap(SessionFactory.class);
+ sessionFactory.getStatistics().setStatisticsEnabled(true);
+
+
+ System.out.println("\n\n\n\n----------------------------------------------------------------------------------------------------------");
+ val students = repositoryJpa.findAll();
+ assertThat(students).isNotNull().hasSize(EXPECTED_NUMBER_OF_STUDENTS)
+ .allMatch(s -> !s.getName().equals(""))
+ .allMatch(s -> s.getCourses() != null && s.getCourses().size() > 0)
+ .allMatch(s -> s.getAvatar() != null)
+ .allMatch(s -> s.getEmails() != null && s.getEmails().size() > 0);
+ System.out.println("----------------------------------------------------------------------------------------------------------\n\n\n\n");
+ assertThat(sessionFactory.getStatistics().getPrepareStatementCount()).isEqualTo(EXPECTED_QUERIES_COUNT);
+ }
+
+ @DisplayName(" должен корректно сохранять всю информацию о студенте")
+ @Test
+ void shouldSaveAllStudentInfo() {
+ val avatar = new Avatar(0, STUDENT_AVATAR_URL);
+ val email = new EMail(0, STUDENT_EMAIL);
+ val emails = Collections.singletonList(email);
+
+ val course = new Course(0, COURSE_NAME);
+ val courses = Collections.singletonList(course);
+
+
+ val vasya = new OtusStudent(0, STUDENT_NAME, avatar, emails, courses);
+ repositoryJpa.save(vasya);
+ assertThat(vasya.getId()).isGreaterThan(0);
+
+ val actualStudent = em.find(OtusStudent.class, vasya.getId());
+ assertThat(actualStudent).isNotNull().matches(s -> !s.getName().equals(""))
+ .matches(s -> s.getCourses() != null && s.getCourses().size() > 0 && s.getCourses().get(0).getId() > 0)
+ .matches(s -> s.getAvatar() != null)
+ .matches(s -> s.getEmails() != null && s.getEmails().size() > 0);
+ }
+
+ @DisplayName(" должен загружать информацию о нужном студенте по его имени")
+ @Test
+ void shouldFindExpectedStudentByName() {
+ val firstStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
+ List students = repositoryJpa.findByName(FIRST_STUDENT_NAME);
+ assertThat(students).containsOnlyOnce(firstStudent);
+ }
+
+ @DisplayName(" должен изменять имя заданного студента по его id")
+ @Test
+ void shouldUpdateStudentNameById() {
+ val firstStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
+ String oldName = firstStudent.getName();
+ em.detach(firstStudent);
+
+ repositoryJpa.updateNameById(FIRST_STUDENT_ID, STUDENT_NAME);
+ val updatedStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
+
+ assertThat(updatedStudent.getName()).isNotEqualTo(oldName).isEqualTo(STUDENT_NAME);
+ }
+
+ @DisplayName(" должен удалять заданного студента по его id")
+ @Test
+ void shouldDeleteStudentNameById() {
+ val firstStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
+ assertThat(firstStudent).isNotNull();
+ em.detach(firstStudent);
+
+ repositoryJpa.deleteById(FIRST_STUDENT_ID);
+ val deletedStudent = em.find(OtusStudent.class, FIRST_STUDENT_ID);
+
+ assertThat(deletedStudent).isNull();
+ }
+}
\ No newline at end of file
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/test/resources/application.yml b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/test/resources/application.yml
new file mode 100644
index 00000000..d2b811a4
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/test/resources/application.yml
@@ -0,0 +1,17 @@
+spring:
+ datasource:
+ url: jdbc:h2:mem:testdb
+ initialization-mode: always
+
+ jpa:
+ generate-ddl: false
+ #generate-ddl: true
+ hibernate:
+ ddl-auto: none
+ #ddl-auto: create-drop
+
+ #show-sql: true
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/test/resources/data.sql b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/test/resources/data.sql
new file mode 100644
index 00000000..a8db6b85
--- /dev/null
+++ b/2019-11/spring-09/jpql-class-work/jpql-solution-final/src/test/resources/data.sql
@@ -0,0 +1,29 @@
+insert into avatars(photo_url)
+values ('photoUrl_01'), ('photoUrl_02'), ('photoUrl_03'), ('photoUrl_04'), ('photoUrl_05'),
+ ('photoUrl_06'), ('photoUrl_07'), ('photoUrl_08'), ('photoUrl_09'), ('photoUrl_10');
+
+insert into courses(name)
+values ('course_name_01'), ('course_name_02'), ('course_name_03'), ('course_name_04'), ('course_name_05'),
+ ('course_name_06'), ('course_name_07'), ('course_name_08'), ('course_name_09'), ('course_name_10'), ('not_used_11');
+
+insert into otus_students(name, avatar_id)
+values ('student_01', 1), ('student_02', 2), ('student_03', 3), ('student_04', 4), ('student_05', 5),
+ ('student_06', 6), ('student_07', 7), ('student_08', 8), ('student_09', 9), ('student_10', 10);
+
+
+insert into emails(email, student_id)
+values ('email_01', 1), ('email_02', 1), ('email_03', 2), ('email_04', 2), ('email_05', 3), ('email_06', 4),
+ ('email_07', 5), ('email_08', 6), ('email_09', 7), ('email_10', 8), ('email_11', 9), ('email_12', 10);
+
+
+insert into student_courses(student_id, course_id)
+values (1, 1), (1, 2), (1, 3),
+ (2, 2), (2, 4), (2, 5),
+ (3, 3), (3, 6), (3, 7),
+ (4, 4), (4, 8), (4, 9),
+ (5, 5), (5, 10), (5, 1),
+ (6, 6), (6, 2), (6, 3),
+ (7, 7), (7, 4), (7, 5),
+ (8, 8), (8, 6), (8, 7),
+ (9, 9), (9, 8), (9, 10),
+ (10, 10), (10, 1), (10, 2);
diff --git a/2019-11/spring-09/jpql-class-work/pom.xml b/2019-11/spring-09/jpql-class-work/pom.xml
index 6e46f913..00de54bf 100644
--- a/2019-11/spring-09/jpql-class-work/pom.xml
+++ b/2019-11/spring-09/jpql-class-work/pom.xml
@@ -11,11 +11,9 @@
pom
- jpql-demo-exercise
- jpql-demo-solution-step-1
- jpql-demo-solution-step-2
- jpql-demo-solution-step-3
- jpql-demo-solution-step-4
- jpql-demo-solution-step-final
+ jpql-exercise
+ jpql-solution-01
+ jpql-solution-02
+ jpql-solution-final