diff --git a/S300-SBoot-JPA-ORM/.idea/.gitignore b/S300-SBoot-JPA-ORM/.idea/.gitignore new file mode 100644 index 0000000..4aa91ea --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/S300-SBoot-JPA-ORM/.idea/.name b/S300-SBoot-JPA-ORM/.idea/.name new file mode 100644 index 0000000..54d8eec --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/.name @@ -0,0 +1 @@ +spring-boot-basic \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/codeStyles/Project.xml b/S300-SBoot-JPA-ORM/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..c2621b8 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/codeStyles/Project.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/codeStyles/codeStyleConfig.xml b/S300-SBoot-JPA-ORM/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..df5f35d --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/compiler.xml b/S300-SBoot-JPA-ORM/.idea/compiler.xml new file mode 100644 index 0000000..3ddd90a --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/compiler.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/dataSources.xml b/S300-SBoot-JPA-ORM/.idea/dataSources.xml new file mode 100644 index 0000000..96b0e73 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/dataSources.xml @@ -0,0 +1,11 @@ + + + + + postgresql + true + org.postgresql.Driver + jdbc:postgresql://localhost:5432/postgres + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/encodings.xml b/S300-SBoot-JPA-ORM/.idea/encodings.xml new file mode 100644 index 0000000..4140949 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/jarRepositories.xml b/S300-SBoot-JPA-ORM/.idea/jarRepositories.xml new file mode 100644 index 0000000..a468a99 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__antlr_antlr_2_7_7.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__antlr_antlr_2_7_7.xml new file mode 100644 index 0000000..536821c --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__antlr_antlr_2_7_7.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_2_4.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_2_4.xml new file mode 100644 index 0000000..4fb416b --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_2_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__ch_qos_logback_logback_core_1_2_4.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__ch_qos_logback_logback_core_1_2_4.xml new file mode 100644 index 0000000..eaa1d2c --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__ch_qos_logback_logback_core_1_2_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_classmate_1_5_1.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_classmate_1_5_1.xml new file mode 100644 index 0000000..3b35db3 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_classmate_1_5_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_12_4.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_12_4.xml new file mode 100644 index 0000000..ee37165 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_12_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_12_4.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_12_4.xml new file mode 100644 index 0000000..000575c --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_12_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_12_4.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_12_4.xml new file mode 100644 index 0000000..f28c2fe --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_12_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_12_4.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_12_4.xml new file mode 100644 index 0000000..378fcdd --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_12_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_12_4.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_12_4.xml new file mode 100644 index 0000000..0b38ca4 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_12_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_12_4.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_12_4.xml new file mode 100644 index 0000000..d2469df --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_12_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_jayway_jsonpath_json_path_2_5_0.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_jayway_jsonpath_json_path_2_5_0.xml new file mode 100644 index 0000000..2995696 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_jayway_jsonpath_json_path_2_5_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_sun_activation_jakarta_activation_1_2_2.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_sun_activation_jakarta_activation_1_2_2.xml new file mode 100644 index 0000000..b761c86 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_sun_activation_jakarta_activation_1_2_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_sun_istack_istack_commons_runtime_3_0_12.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_sun_istack_istack_commons_runtime_3_0_12.xml new file mode 100644 index 0000000..9af2b23 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_sun_istack_istack_commons_runtime_3_0_12.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_vaadin_external_google_android_json_0_0_20131108_vaadin1.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_vaadin_external_google_android_json_0_0_20131108_vaadin1.xml new file mode 100644 index 0000000..c987dd2 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_vaadin_external_google_android_json_0_0_20131108_vaadin1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_zaxxer_HikariCP_4_0_3.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_zaxxer_HikariCP_4_0_3.xml new file mode 100644 index 0000000..dbe58c5 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__com_zaxxer_HikariCP_4_0_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__jakarta_activation_jakarta_activation_api_1_2_2.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__jakarta_activation_jakarta_activation_api_1_2_2.xml new file mode 100644 index 0000000..be8b4b3 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__jakarta_activation_jakarta_activation_api_1_2_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__jakarta_annotation_jakarta_annotation_api_1_3_5.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__jakarta_annotation_jakarta_annotation_api_1_3_5.xml new file mode 100644 index 0000000..5ddce8f --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__jakarta_annotation_jakarta_annotation_api_1_3_5.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__jakarta_persistence_jakarta_persistence_api_2_2_3.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__jakarta_persistence_jakarta_persistence_api_2_2_3.xml new file mode 100644 index 0000000..913d3a6 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__jakarta_persistence_jakarta_persistence_api_2_2_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__jakarta_transaction_jakarta_transaction_api_1_3_3.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__jakarta_transaction_jakarta_transaction_api_1_3_3.xml new file mode 100644 index 0000000..85df205 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__jakarta_transaction_jakarta_transaction_api_1_3_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__jakarta_xml_bind_jakarta_xml_bind_api_2_3_3.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__jakarta_xml_bind_jakarta_xml_bind_api_2_3_3.xml new file mode 100644 index 0000000..2810cb2 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__jakarta_xml_bind_jakarta_xml_bind_api_2_3_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__mysql_mysql_connector_java_8_0_26.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__mysql_mysql_connector_java_8_0_26.xml new file mode 100644 index 0000000..520ad76 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__mysql_mysql_connector_java_8_0_26.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__net_bytebuddy_byte_buddy_1_10_22.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__net_bytebuddy_byte_buddy_1_10_22.xml new file mode 100644 index 0000000..77723ca --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__net_bytebuddy_byte_buddy_1_10_22.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__net_bytebuddy_byte_buddy_agent_1_10_22.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__net_bytebuddy_byte_buddy_agent_1_10_22.xml new file mode 100644 index 0000000..db39ab4 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__net_bytebuddy_byte_buddy_agent_1_10_22.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__net_minidev_accessors_smart_2_4_7.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__net_minidev_accessors_smart_2_4_7.xml new file mode 100644 index 0000000..3e45701 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__net_minidev_accessors_smart_2_4_7.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__net_minidev_json_smart_2_4_7.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__net_minidev_json_smart_2_4_7.xml new file mode 100644 index 0000000..0702e19 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__net_minidev_json_smart_2_4_7.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apache_commons_commons_lang3_3_12_0.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apache_commons_commons_lang3_3_12_0.xml new file mode 100644 index 0000000..15427c5 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apache_commons_commons_lang3_3_12_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_14_1.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_14_1.xml new file mode 100644 index 0000000..708458f --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_14_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apache_logging_log4j_log4j_to_slf4j_2_14_1.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apache_logging_log4j_log4j_to_slf4j_2_14_1.xml new file mode 100644 index 0000000..470a4e3 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apache_logging_log4j_log4j_to_slf4j_2_14_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_50.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_50.xml new file mode 100644 index 0000000..315a01a --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_50.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_el_9_0_50.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_el_9_0_50.xml new file mode 100644 index 0000000..efe2661 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_el_9_0_50.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_50.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_50.xml new file mode 100644 index 0000000..a70ed2e --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_50.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_1_0.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_1_0.xml new file mode 100644 index 0000000..e6ecab0 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_1_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_aspectj_aspectjweaver_1_9_7.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_aspectj_aspectjweaver_1_9_7.xml new file mode 100644 index 0000000..ff596e3 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_aspectj_aspectjweaver_1_9_7.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_assertj_assertj_core_3_19_0.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_assertj_assertj_core_3_19_0.xml new file mode 100644 index 0000000..34941e9 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_assertj_assertj_core_3_19_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_checkerframework_checker_qual_3_5_0.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_checkerframework_checker_qual_3_5_0.xml new file mode 100644 index 0000000..b41c4fe --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_checkerframework_checker_qual_3_5_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_dom4j_dom4j_2_1_3.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_dom4j_dom4j_2_1_3.xml new file mode 100644 index 0000000..c400430 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_dom4j_dom4j_2_1_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_glassfish_jaxb_jaxb_runtime_2_3_4.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_glassfish_jaxb_jaxb_runtime_2_3_4.xml new file mode 100644 index 0000000..fd6a9bf --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_glassfish_jaxb_jaxb_runtime_2_3_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_glassfish_jaxb_txw2_2_3_4.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_glassfish_jaxb_txw2_2_3_4.xml new file mode 100644 index 0000000..f5ba177 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_glassfish_jaxb_txw2_2_3_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_hamcrest_hamcrest_2_2.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_hamcrest_hamcrest_2_2.xml new file mode 100644 index 0000000..130329b --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_hamcrest_hamcrest_2_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_hibernate_common_hibernate_commons_annotations_5_1_2_Final.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_hibernate_common_hibernate_commons_annotations_5_1_2_Final.xml new file mode 100644 index 0000000..73228ef --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_hibernate_common_hibernate_commons_annotations_5_1_2_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_hibernate_hibernate_core_5_4_32_Final.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_hibernate_hibernate_core_5_4_32_Final.xml new file mode 100644 index 0000000..82e8efe --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_hibernate_hibernate_core_5_4_32_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_javassist_javassist_3_27_0_GA.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_javassist_javassist_3_27_0_GA.xml new file mode 100644 index 0000000..eb801fc --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_javassist_javassist_3_27_0_GA.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_jboss_jandex_2_2_3_Final.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_jboss_jandex_2_2_3_Final.xml new file mode 100644 index 0000000..9cc5eeb --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_jboss_jandex_2_2_3_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_jboss_logging_jboss_logging_3_4_2_Final.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_jboss_logging_jboss_logging_3_4_2_Final.xml new file mode 100644 index 0000000..42b1c0e --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_jboss_logging_jboss_logging_3_4_2_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_7_2.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_7_2.xml new file mode 100644 index 0000000..85b487a --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_7_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_7_2.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_7_2.xml new file mode 100644 index 0000000..b693012 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_7_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_7_2.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_7_2.xml new file mode 100644 index 0000000..c74eb1a --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_7_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_7_2.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_7_2.xml new file mode 100644 index 0000000..cfd0b6f --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_7_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_7_2.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_7_2.xml new file mode 100644 index 0000000..d70ccaa --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_7_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_7_2.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_7_2.xml new file mode 100644 index 0000000..1744b10 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_7_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_mapstruct_mapstruct_1_4_2_Final.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_mapstruct_mapstruct_1_4_2_Final.xml new file mode 100644 index 0000000..dc4063a --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_mapstruct_mapstruct_1_4_2_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_mapstruct_mapstruct_processor_1_4_2_Final.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_mapstruct_mapstruct_processor_1_4_2_Final.xml new file mode 100644 index 0000000..27dd97d --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_mapstruct_mapstruct_processor_1_4_2_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_mockito_mockito_core_3_9_0.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_mockito_mockito_core_3_9_0.xml new file mode 100644 index 0000000..4e68823 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_mockito_mockito_core_3_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_mockito_mockito_junit_jupiter_3_9_0.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_mockito_mockito_junit_jupiter_3_9_0.xml new file mode 100644 index 0000000..e47ac06 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_mockito_mockito_junit_jupiter_3_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_objenesis_objenesis_3_2.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_objenesis_objenesis_3_2.xml new file mode 100644 index 0000000..6b24b4f --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_objenesis_objenesis_3_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_opentest4j_opentest4j_1_2_0.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_opentest4j_opentest4j_1_2_0.xml new file mode 100644 index 0000000..718b32e --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_opentest4j_opentest4j_1_2_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_ow2_asm_asm_9_1.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_ow2_asm_asm_9_1.xml new file mode 100644 index 0000000..c8c7d46 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_ow2_asm_asm_9_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_postgresql_postgresql_42_2_23.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_postgresql_postgresql_42_2_23.xml new file mode 100644 index 0000000..215d391 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_postgresql_postgresql_42_2_23.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_projectlombok_lombok_1_18_20.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_projectlombok_lombok_1_18_20.xml new file mode 100644 index 0000000..7b4ef61 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_projectlombok_lombok_1_18_20.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_skyscreamer_jsonassert_1_5_0.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_skyscreamer_jsonassert_1_5_0.xml new file mode 100644 index 0000000..69c5c8a --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_skyscreamer_jsonassert_1_5_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_slf4j_jul_to_slf4j_1_7_32.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_slf4j_jul_to_slf4j_1_7_32.xml new file mode 100644 index 0000000..4460fd3 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_slf4j_jul_to_slf4j_1_7_32.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_32.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_32.xml new file mode 100644 index 0000000..75b9f50 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_32.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_5_3.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_5_3.xml new file mode 100644 index 0000000..bbe224e --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_5_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_2_5_3.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_2_5_3.xml new file mode 100644 index 0000000..4014df0 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_2_5_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_2_5_3.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_2_5_3.xml new file mode 100644 index 0000000..2e6a648 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_2_5_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_aop_2_5_3.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_aop_2_5_3.xml new file mode 100644 index 0000000..452e2e4 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_aop_2_5_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_jpa_2_5_3.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_jpa_2_5_3.xml new file mode 100644 index 0000000..d59f864 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_jpa_2_5_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_jdbc_2_5_3.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_jdbc_2_5_3.xml new file mode 100644 index 0000000..91f127d --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_jdbc_2_5_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_5_3.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_5_3.xml new file mode 100644 index 0000000..b398592 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_5_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_logging_2_5_3.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_logging_2_5_3.xml new file mode 100644 index 0000000..b5c21a2 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_logging_2_5_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_test_2_5_3.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_test_2_5_3.xml new file mode 100644 index 0000000..04da179 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_test_2_5_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_2_5_3.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_2_5_3.xml new file mode 100644 index 0000000..7b7b8f6 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_2_5_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_5_3.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_5_3.xml new file mode 100644 index 0000000..3edbf52 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_5_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_5_3.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_5_3.xml new file mode 100644 index 0000000..8d5f328 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_5_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_autoconfigure_2_5_3.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_autoconfigure_2_5_3.xml new file mode 100644 index 0000000..60b4c7a --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_autoconfigure_2_5_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_5_3.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_5_3.xml new file mode 100644 index 0000000..7cac8c4 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_5_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_data_spring_data_jpa_2_5_3.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_data_spring_data_jpa_2_5_3.xml new file mode 100644 index 0000000..55b50dc --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_data_spring_data_jpa_2_5_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_aop_5_3_9.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_aop_5_3_9.xml new file mode 100644 index 0000000..a444650 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_aop_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_aspects_5_3_9.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_aspects_5_3_9.xml new file mode 100644 index 0000000..b6aee10 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_aspects_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_beans_5_3_9.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_beans_5_3_9.xml new file mode 100644 index 0000000..990971e --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_beans_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_context_5_3_9.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_context_5_3_9.xml new file mode 100644 index 0000000..98bd36a --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_context_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_core_5_3_9.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_core_5_3_9.xml new file mode 100644 index 0000000..0140c8b --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_core_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_expression_5_3_9.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_expression_5_3_9.xml new file mode 100644 index 0000000..99e5928 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_expression_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_jcl_5_3_9.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_jcl_5_3_9.xml new file mode 100644 index 0000000..e1b465e --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_jcl_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_jdbc_5_3_9.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_jdbc_5_3_9.xml new file mode 100644 index 0000000..b20e4d2 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_jdbc_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_orm_5_3_9.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_orm_5_3_9.xml new file mode 100644 index 0000000..98e3093 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_orm_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_test_5_3_9.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_test_5_3_9.xml new file mode 100644 index 0000000..2491913 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_test_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_tx_5_3_9.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_tx_5_3_9.xml new file mode 100644 index 0000000..3903748 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_tx_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_web_5_3_9.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_web_5_3_9.xml new file mode 100644 index 0000000..4645262 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_web_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_webmvc_5_3_9.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_webmvc_5_3_9.xml new file mode 100644 index 0000000..de40cc4 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_springframework_spring_webmvc_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_xmlunit_xmlunit_core_2_8_2.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_xmlunit_xmlunit_core_2_8_2.xml new file mode 100644 index 0000000..240445a --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_xmlunit_xmlunit_core_2_8_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_yaml_snakeyaml_1_28.xml b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_yaml_snakeyaml_1_28.xml new file mode 100644 index 0000000..e13f0e1 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/libraries/Maven__org_yaml_snakeyaml_1_28.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/misc.xml b/S300-SBoot-JPA-ORM/.idea/misc.xml new file mode 100644 index 0000000..3007f2e --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/misc.xml @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/modules.xml b/S300-SBoot-JPA-ORM/.idea/modules.xml new file mode 100644 index 0000000..42b47d8 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/uiDesigner.xml b/S300-SBoot-JPA-ORM/.idea/uiDesigner.xml new file mode 100644 index 0000000..b93ac08 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/.idea/vcs.xml b/S300-SBoot-JPA-ORM/.idea/vcs.xml new file mode 100644 index 0000000..2e3f692 --- /dev/null +++ b/S300-SBoot-JPA-ORM/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/S300-SBoot-JPA-ORM/src/main/resources/application.yml b/S300-SBoot-JPA-ORM/src/main/resources/application.yml index 8eaaf25..2b1a6a7 100644 --- a/S300-SBoot-JPA-ORM/src/main/resources/application.yml +++ b/S300-SBoot-JPA-ORM/src/main/resources/application.yml @@ -17,8 +17,8 @@ spring: debug: enabled datasource: - username: "knits-orm" - password: "jpa-tutorial" + username: "postgres" + password: "postgres" jpa: database: postgresql diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo01/Office.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo01/Office.java index db7e3e5..31bf385 100644 --- a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo01/Office.java +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo01/Office.java @@ -17,4 +17,5 @@ public class Office { private String street; + } diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo02/sharedpk/Employee.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo02/sharedpk/Employee.java new file mode 100644 index 0000000..b87c709 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo02/sharedpk/Employee.java @@ -0,0 +1,24 @@ +package com.knits.jpa.orm.d01.one.to.one.demo02.sharedpk; + + +import lombok.Data; + +import javax.persistence.*; + +@Entity +@Table(name = "employee") +@Data +public class Employee { + + @Id + private Long id; + + private String firstName; + + private String lastName; + + @OneToOne + @MapsId + private Office office; + +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo02/sharedpk/EmployeeRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo02/sharedpk/EmployeeRepository.java new file mode 100644 index 0000000..02804db --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo02/sharedpk/EmployeeRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d01.one.to.one.demo02.sharedpk; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface EmployeeRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo02/sharedpk/Office.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo02/sharedpk/Office.java new file mode 100644 index 0000000..b31ba90 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo02/sharedpk/Office.java @@ -0,0 +1,19 @@ +package com.knits.jpa.orm.d01.one.to.one.demo02.sharedpk; + +import lombok.Data; + +import javax.persistence.*; + +@Entity +@Data +public class Office { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String city; + + private String street; +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo02/sharedpk/OfficeRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo02/sharedpk/OfficeRepository.java new file mode 100644 index 0000000..9d971fa --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo02/sharedpk/OfficeRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d01.one.to.one.demo02.sharedpk; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface OfficeRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo02/sharedpk/TestJpaDemo02.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo02/sharedpk/TestJpaDemo02.java new file mode 100644 index 0000000..0099436 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo02/sharedpk/TestJpaDemo02.java @@ -0,0 +1,138 @@ +package com.knits.jpa.orm.d01.one.to.one.demo02.sharedpk; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.TestPropertySource; + +import java.util.List; +import java.util.Optional; + +@DataJpaTest +@EntityScan("com.knits.jpa.orm.d01.one.to.one.demo02.*") //otherwise finds all other entities in subpackages +@EnableJpaRepositories("com.knits.jpa.orm.d01.one.to.one.demo02.*") //otherwise doesnt create jpa repositories instances +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@TestPropertySource(properties = { + "spring.jpa.hibernate.ddl-auto=create", + "spring.datasource.url=jdbc:postgresql://localhost:5432/JPA-ORM-02" +}) +//to clean and fill the DB before each test +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +public class TestJpaDemo02 { + + @Autowired + private EmployeeRepository employeeRepository; + + @Autowired + private OfficeRepository officeRepository; + + @BeforeEach // fill data before each test than IDs same all time. + @Rollback(value = false) + public void initDatabase(){ + + Office office = new Office(); + office.setCity("A Mock City"); + office.setStreet("A Mock Street"); + + Employee employee = new Employee(); + employee.setFirstName("Anton"); + employee.setLastName("Mezhenin"); + employee.setOffice(office); + + officeRepository.save(office); + employeeRepository.save(employee); + + } + + @Test + @Rollback(value = false) + public void getEmployee(){ + + Employee employee = employeeRepository.findById(1L).get(); + + Assertions.assertThat(employee.getId()).isEqualTo(1L); + } + + @Test + @Rollback(value = false) + public void getEmployeeWithSameOfficeId(){ + + Employee employee = employeeRepository.findById(1L).get(); + + Assertions.assertThat(employee.getOffice().getId()).isEqualTo(1L); + } + + @Test + @Rollback(value = false) + public void getListOfEmployees(){ + + List employees = employeeRepository.findAll(); + + Assertions.assertThat(employees.size()).isGreaterThan(0); + + } + + @Test + @Rollback(value = false) + public void updateEmployeeTest(){ + + Employee employee = employeeRepository.findById(1L).get(); + + employee.setLastName("Great"); + + Employee employeeUpdated = employeeRepository.save(employee); + + Assertions.assertThat(employeeUpdated.getLastName()).isEqualTo("Great"); + + } + + @Test + @Rollback(value = false) + public void deleteEmployee(){ + + Employee employee = employeeRepository.findById(1L).get(); + + employeeRepository.delete(employee); + + Employee employee1 = null; + + Optional optionalEmployee = employeeRepository.findById(1L); + + if(optionalEmployee.isPresent()){ + employee1 = optionalEmployee.get(); + } + + Assertions.assertThat(employee1).isNull(); + } + + @Test + @Rollback(value = false) + //firstly have to delete employee and after office + public void deleteEmployeeAndOffice(){ + + Employee employee = employeeRepository.findById(1L).get(); + + employeeRepository.delete(employee); + + Office office = officeRepository.findById(1L).get(); + + officeRepository.delete(office); + + Office office1 = null; + + Optional optionalOffice = officeRepository.findById(1L); + + if(optionalOffice.isPresent()){ + office1 = optionalOffice.get(); + } + + Assertions.assertThat(office1).isNull(); + } +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo03/linktable/Employee.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo03/linktable/Employee.java new file mode 100644 index 0000000..a6ce7cf --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo03/linktable/Employee.java @@ -0,0 +1,33 @@ +package com.knits.jpa.orm.d01.one.to.one.demo03.linktable; + +import lombok.Data; +import org.hibernate.annotations.Cascade; + +import javax.persistence.*; + +@Entity +@Table(name = "employee") +@Data +public class Employee { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String firstName; + + private String lastName; + + @OneToOne + @JoinTable(name = "EMPLOYEE_OFFICE_JOIN_TABLE", + joinColumns = { + @JoinColumn(name = "EMPLOYEE_FK", referencedColumnName = "id") + }, + inverseJoinColumns = { + @JoinColumn(name = "OFFICE_FK", referencedColumnName = "id", unique = true) + } + ) + private Office office; + +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo03/linktable/EmployeeRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo03/linktable/EmployeeRepository.java new file mode 100644 index 0000000..f92a389 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo03/linktable/EmployeeRepository.java @@ -0,0 +1,9 @@ +package com.knits.jpa.orm.d01.one.to.one.demo03.linktable; + + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface EmployeeRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo03/linktable/Office.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo03/linktable/Office.java new file mode 100644 index 0000000..07245e7 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo03/linktable/Office.java @@ -0,0 +1,19 @@ +package com.knits.jpa.orm.d01.one.to.one.demo03.linktable; + +import lombok.Data; + +import javax.persistence.*; + +@Entity +@Data +public class Office { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String city; + + private String street; +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo03/linktable/OfficeRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo03/linktable/OfficeRepository.java new file mode 100644 index 0000000..a7f106c --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo03/linktable/OfficeRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d01.one.to.one.demo03.linktable; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface OfficeRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo03/linktable/TestJpaDemo03.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo03/linktable/TestJpaDemo03.java new file mode 100644 index 0000000..61f6646 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo03/linktable/TestJpaDemo03.java @@ -0,0 +1,139 @@ +package com.knits.jpa.orm.d01.one.to.one.demo03.linktable; + + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.TestPropertySource; + +import java.util.List; +import java.util.Optional; + +@DataJpaTest +@EntityScan("com.knits.jpa.orm.d01.one.to.one.demo03.*") //otherwise finds all other entities in subpackages +@EnableJpaRepositories("com.knits.jpa.orm.d01.one.to.one.demo03.*") //otherwise doesnt create jpa repositories instances +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@TestPropertySource(properties = { + "spring.jpa.hibernate.ddl-auto=create", + "spring.datasource.url=jdbc:postgresql://localhost:5432/JPA-ORM-03" +}) +//to clean and fill the DB before each test +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +public class TestJpaDemo03 { + + @Autowired + private EmployeeRepository employeeRepository; + + @Autowired + private OfficeRepository officeRepository; + + @BeforeEach + @Rollback(value = false) + public void initDatabase(){ + + Office office = new Office(); + office.setCity("A Mock City"); + office.setStreet("A Mock Street"); + + Employee employee = new Employee(); + employee.setFirstName("Anton"); + employee.setLastName("Mezhenin"); + employee.setOffice(office); + + officeRepository.save(office); + employeeRepository.save(employee); + + } + + @Test + @Rollback(value = false) + public void getEmployee(){ + + Employee employee = employeeRepository.findById(52L).get(); + + Assertions.assertThat(employee.getId()).isEqualTo(52L); + } + + @Test + @Rollback(value = false) + public void getEmployeeWithOfficeId(){ + + Employee employee = employeeRepository.findById(52L).get(); + + Assertions.assertThat(employee.getOffice().getId()).isEqualTo(1L); + } + + @Test + public void getListOfEmployees(){ + + List employees = employeeRepository.findAll(); + + Assertions.assertThat(employees.size()).isGreaterThan(0); + + } + + @Test + @Rollback(value = false) + public void updateEmployee(){ + + Employee employee = employeeRepository.findById(52L).get(); + + employee.setLastName("Great"); + + Employee employeeUpdated = employeeRepository.save(employee); + + Assertions.assertThat(employeeUpdated.getLastName()).isEqualTo("Great"); + + } + + @Test + @Rollback(value = false) + //can delete data from Employee and join table without conflicts. Office exists + public void deleteEmployee(){ + + Employee employee = employeeRepository.findById(52L).get(); + + employeeRepository.delete(employee); + + Employee employee1 = null; + + Optional optionalEmployee = employeeRepository.findById(52L); + + if(optionalEmployee.isPresent()){ + employee1 = optionalEmployee.get(); + } + + Assertions.assertThat(employee1).isNull(); + } + + @Test + @Rollback(value = false) + //Firstly have to delete employee and after delete office + public void deleteOffice(){ + + Employee employee = employeeRepository.findById(52L).get(); + + employeeRepository.delete(employee); + + Office office = officeRepository.findById(1L).get(); + + officeRepository.delete(office); + + Office office1 = null; + + Optional optionalOffice = officeRepository.findById(1L); + + if(optionalOffice.isPresent()){ + office1 = optionalOffice.get(); + } + + Assertions.assertThat(office1).isNull(); + } +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo04/bidirectionaljointable/Employee.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo04/bidirectionaljointable/Employee.java new file mode 100644 index 0000000..fc79f41 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo04/bidirectionaljointable/Employee.java @@ -0,0 +1,32 @@ +package com.knits.jpa.orm.d01.one.to.one.demo04.bidirectionaljointable; + +import lombok.Data; + +import javax.persistence.*; + +@Entity +@Table(name = "employee") +@Data +public class Employee { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String firstName; + + private String lastName; + + @OneToOne + @JoinTable(name = "EMPLOYEE_OFFICE_JOIN_TABLE", + joinColumns = { + @JoinColumn(name = "EMPLOYEE_FK", referencedColumnName = "id") + }, + inverseJoinColumns = { + @JoinColumn(name = "OFFICE_FK", referencedColumnName = "id", unique = true) + } + ) + private Office office; + +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo04/bidirectionaljointable/EmployeeRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo04/bidirectionaljointable/EmployeeRepository.java new file mode 100644 index 0000000..2a55439 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo04/bidirectionaljointable/EmployeeRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d01.one.to.one.demo04.bidirectionaljointable; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface EmployeeRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo04/bidirectionaljointable/Office.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo04/bidirectionaljointable/Office.java new file mode 100644 index 0000000..80737d0 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo04/bidirectionaljointable/Office.java @@ -0,0 +1,22 @@ +package com.knits.jpa.orm.d01.one.to.one.demo04.bidirectionaljointable; + +import lombok.Data; + +import javax.persistence.*; + +@Entity +@Data +public class Office { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String city; + + private String street; + + @OneToOne(mappedBy = "office") + private Employee employee; + +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo04/bidirectionaljointable/OfficeRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo04/bidirectionaljointable/OfficeRepository.java new file mode 100644 index 0000000..e6a614f --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo04/bidirectionaljointable/OfficeRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d01.one.to.one.demo04.bidirectionaljointable; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface OfficeRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo04/bidirectionaljointable/TestJpaDemo04.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo04/bidirectionaljointable/TestJpaDemo04.java new file mode 100644 index 0000000..3eb1a03 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo04/bidirectionaljointable/TestJpaDemo04.java @@ -0,0 +1,141 @@ +package com.knits.jpa.orm.d01.one.to.one.demo04.bidirectionaljointable; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.TestPropertySource; + +import java.util.List; +import java.util.Optional; + +@DataJpaTest +@EntityScan("com.knits.jpa.orm.d01.one.to.one.demo04.*") //otherwise finds all other entities in subpackages +@EnableJpaRepositories("com.knits.jpa.orm.d01.one.to.one.demo04.*") //otherwise doesnt create jpa repositories instances +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@TestPropertySource(properties = { + "spring.jpa.hibernate.ddl-auto=create", + "spring.datasource.url=jdbc:postgresql://localhost:5432/JPA-ORM-04" +}) +//to clean and fill the DB before each test +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +public class TestJpaDemo04 { + + @Autowired + private EmployeeRepository employeeRepository; + + @Autowired + private OfficeRepository officeRepository; + + @BeforeEach + @Rollback(value = false) + public void initDatabase(){ + + Office office = new Office(); + office.setCity("A Mock City"); + office.setStreet("A Mock Street"); + + Employee employee = new Employee(); + employee.setFirstName("Anton"); + employee.setLastName("Mezhenin"); + + office.setEmployee(employee); + employee.setOffice(office); + + officeRepository.save(office); + employeeRepository.save(employee); + + } + + @Test + @Rollback(value = false) + public void getEmployee(){ + + Employee employee = employeeRepository.findById(52L).get(); + + Assertions.assertThat(employee.getId()).isEqualTo(52L); + } + + @Test + @Rollback(value = false) + public void getEmployeeWithOfficeId(){ + + Employee employee = employeeRepository.findById(52L).get(); + + Assertions.assertThat(employee.getOffice().getId()).isEqualTo(1L); + } + + @Test + @Rollback(value = false) + public void getListOfEmployees(){ + + List employees = employeeRepository.findAll(); + + Assertions.assertThat(employees.size()).isGreaterThan(0); + + } + + @Test + @Rollback(value = false) + public void updateEmployee(){ + + Employee employee = employeeRepository.findById(52L).get(); + + employee.setLastName("Great"); + + Employee employeeUpdated = employeeRepository.save(employee); + + Assertions.assertThat(employeeUpdated.getLastName()).isEqualTo("Great"); + + } + + @Test + @Rollback(value = false) + //can delete Employee without conflicts. Office exists + public void deleteEmployee(){ + + Employee employee = employeeRepository.findById(52L).get(); + + employeeRepository.delete(employee); + + Employee employee1 = null; + + Optional optionalEmployee = employeeRepository.findById(52L); + + if(optionalEmployee.isPresent()){ + employee1 = optionalEmployee.get(); + } + + Assertions.assertThat(employee1).isNull(); + } + + @Test + @Rollback(value = false) + //Firstly have to delete employee and then delete office + public void deleteOffice(){ + + Employee employee = employeeRepository.findById(52L).get(); + + employeeRepository.delete(employee); + + Office office = officeRepository.findById(1L).get(); + + officeRepository.delete(office); + + Office office1 = null; + + Optional optionalOffice = officeRepository.findById(1L); + + if(optionalOffice.isPresent()){ + office1 = optionalOffice.get(); + } + + Assertions.assertThat(office1).isNull(); + } +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo05/bidirectionalCascade/Employee.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo05/bidirectionalCascade/Employee.java new file mode 100644 index 0000000..109703e --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo05/bidirectionalCascade/Employee.java @@ -0,0 +1,24 @@ +package com.knits.jpa.orm.d01.one.to.one.demo05.bidirectionalCascade; + +import lombok.Data; + +import javax.persistence.*; + +@Entity +@Table(name = "employee") +@Data +public class Employee { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String firstName; + + private String lastName; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "office_id") + private Office office; +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo05/bidirectionalCascade/EmployeeRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo05/bidirectionalCascade/EmployeeRepository.java new file mode 100644 index 0000000..46743b5 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo05/bidirectionalCascade/EmployeeRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d01.one.to.one.demo05.bidirectionalCascade; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface EmployeeRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo05/bidirectionalCascade/Office.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo05/bidirectionalCascade/Office.java new file mode 100644 index 0000000..6249633 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo05/bidirectionalCascade/Office.java @@ -0,0 +1,26 @@ +package com.knits.jpa.orm.d01.one.to.one.demo05.bidirectionalCascade; + +import lombok.Data; + +import javax.persistence.*; + +@Entity +@Data +public class Office { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String city; + + private String street; + + @OneToOne( + mappedBy = "office", + fetch = FetchType.LAZY, + cascade = CascadeType.ALL + ) + private Employee employee; +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo05/bidirectionalCascade/OfficeRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo05/bidirectionalCascade/OfficeRepository.java new file mode 100644 index 0000000..f125d86 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo05/bidirectionalCascade/OfficeRepository.java @@ -0,0 +1,6 @@ +package com.knits.jpa.orm.d01.one.to.one.demo05.bidirectionalCascade; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface OfficeRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo05/bidirectionalCascade/TestJpaDemo05.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo05/bidirectionalCascade/TestJpaDemo05.java new file mode 100644 index 0000000..d8c8a78 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d01/one/to/one/demo05/bidirectionalCascade/TestJpaDemo05.java @@ -0,0 +1,95 @@ +package com.knits.jpa.orm.d01.one.to.one.demo05.bidirectionalCascade; + + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.TestPropertySource; + +import java.util.Optional; + +@DataJpaTest +@EntityScan("com.knits.jpa.orm.d01.one.to.one.demo05.*") //otherwise finds all other entities in subpackages +@EnableJpaRepositories("com.knits.jpa.orm.d01.one.to.one.demo05.*") //otherwise doesnt create jpa repositories instances +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@TestPropertySource(properties = { + "spring.jpa.hibernate.ddl-auto=create", + "spring.datasource.url=jdbc:postgresql://localhost:5432/JPA-ORM-05" +}) +//to clean and fill the DB before each test +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +public class TestJpaDemo05 { + + @Autowired + private EmployeeRepository employeeRepository; + + @Autowired + private OfficeRepository officeRepository; + + @BeforeEach + @Rollback(value = false) + public void initDatabase(){ + + Office office = new Office(); + office.setCity("A Mock City"); + office.setStreet("A Mock Street"); + + Employee employee = new Employee(); + employee.setFirstName("Anton"); + employee.setLastName("Mezhenin"); + + office.setEmployee(employee); + employee.setOffice(office); + + officeRepository.save(office); + employeeRepository.save(employee); + + } + + @Test + @Rollback(value = false) + //can delete data from Employee and join table without conflicts. Office exists + public void deleteEmployee(){ + + Employee employee = employeeRepository.findById(52L).get(); + + employeeRepository.delete(employee); + + Employee employee1 = null; + + Optional optionalEmployee = employeeRepository.findById(52L); + + if(optionalEmployee.isPresent()){ + employee1 = optionalEmployee.get(); + } + + Assertions.assertThat(employee1).isNull(); + } + + @Test + @Rollback(value = false) + //Can delete office and employee by cascade + public void deleteOffice(){ + + Office office = officeRepository.findById(1L).get(); + + officeRepository.delete(office); + + Office office1 = null; + + Optional optionalOffice = officeRepository.findById(1L); + + if(optionalOffice.isPresent()){ + office1 = optionalOffice.get(); + } + + Assertions.assertThat(office1).isNull(); + } +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo01/TestJpaOneToManyDemo01.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo01/TestJpaOneToManyDemo01.java index 5ac3199..07b81b6 100644 --- a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo01/TestJpaOneToManyDemo01.java +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo01/TestJpaOneToManyDemo01.java @@ -1,6 +1,8 @@ package com.knits.jpa.orm.d02.one.to.many.demo01; import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.domain.EntityScan; @@ -8,19 +10,25 @@ import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.ComponentScan; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.Rollback; import org.springframework.test.context.TestPropertySource; +import java.util.List; +import java.util.Optional; + @DataJpaTest @EntityScan("com.knits.jpa.orm.d02.one.to.many.demo01") @EnableJpaRepositories("com.knits.jpa.orm.d02.one.to.many.demo01") @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) @TestPropertySource(properties = { - "spring.jpa.hibernate.ddl-auto=update", - "spring.datasource.url=jdbc:postgresql://localhost:5432/JPA-ORM-02" + "spring.jpa.hibernate.ddl-auto=create", + "spring.datasource.url=jdbc:postgresql://localhost:5432/JPA-ORM-02-01" }) @Slf4j +//to clean and fill the DB before each test +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) public class TestJpaOneToManyDemo01 { @Autowired @@ -29,12 +37,11 @@ public class TestJpaOneToManyDemo01 { @Autowired private ProjectRepository projectRepository; - @Test + @BeforeEach @Rollback(value = false) + //In Db Employee table we can see project_id public void initDatabase(){ - - Project project = new Project(); project.setName("A Mock Project Name"); @@ -61,4 +68,85 @@ public void initDatabase(){ savedProject.getEmployees().forEach(emp -> log.info("Employee Found: {} ",emp.getFirstName())); } + + @Test + public void getProjectEmployeeList(){ + + Project project = projectRepository.findById(52L).get(); + + Assertions.assertThat(project.getEmployees().size()).isGreaterThan(0); + } + + @Test + public void getListOfProjectsTest(){ + + List projects = projectRepository.findAll(); + + Assertions.assertThat(projects.size()).isGreaterThan(0); + + } + + @Test + @Rollback(value = false) + public void updateEmployeeAndProjectTest(){ + + Project project = projectRepository.findById(52L).get(); + + project.setName("Mock 2"); + project.getEmployees().forEach(emp -> emp.setFirstName("Anton")); + + Project projectUpdated = projectRepository.save(project); + Employee employeeUpdated = projectUpdated.getEmployees().get(1); + + Assertions.assertThat(projectUpdated.getName()).isEqualTo("Mock 2"); + Assertions.assertThat(employeeUpdated.getFirstName()).isEqualTo("Anton"); + + } + + @Test + @Rollback(value = false) + //can delete employee if he in relationships with project + public void deleteEmployeeTest(){ + + Employee employee = employeeRepository.findById(1L).get(); + + employeeRepository.delete(employee); + + Employee employee1 = null; + + Optional optionalEmployee = employeeRepository.findById(1L); + + if(optionalEmployee.isPresent()){ + employee1 = optionalEmployee.get(); + } + + Assertions.assertThat(employee1).isNull(); + } + + @Test + @Rollback(value = false) + //Can't delete a project if it has employees + //must first delete the employees and then the project + public void deleteProjectTest(){ + + Employee employee = employeeRepository.findById(1L).get(); + Employee employee1 = employeeRepository.findById(2L).get(); + + employeeRepository.delete(employee); + employeeRepository.delete(employee1); + + Project project = projectRepository.findById(52L).get(); + projectRepository.delete(project); + + Project project1 = null; + + Optional optionalProject = projectRepository.findById(52L); + + if(optionalProject.isPresent()){ + project1 = optionalProject.get(); + } + + Assertions.assertThat(project1).isNull(); + + } } diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo02/linktable/Employee.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo02/linktable/Employee.java new file mode 100644 index 0000000..c24a9d8 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo02/linktable/Employee.java @@ -0,0 +1,19 @@ +package com.knits.jpa.orm.d02.one.to.many.demo02.linktable; + +import lombok.Data; + +import javax.persistence.*; + +@Entity +@Data +public class Employee { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String firstName; + + private String lastName; +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo02/linktable/EmployeeRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo02/linktable/EmployeeRepository.java new file mode 100644 index 0000000..da73648 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo02/linktable/EmployeeRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d02.one.to.many.demo02.linktable; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface EmployeeRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo02/linktable/Project.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo02/linktable/Project.java new file mode 100644 index 0000000..695ec44 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo02/linktable/Project.java @@ -0,0 +1,25 @@ +package com.knits.jpa.orm.d02.one.to.many.demo02.linktable; + +import lombok.Data; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Data +public class Project { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String name; + + @OneToMany + @JoinTable(name = "EMPLOYEE_PROJECT_TABLE", + joinColumns = {@JoinColumn(name = "PROJECT_FK")}, + inverseJoinColumns = {@JoinColumn(name = "EMPLOYEE_FK")} + ) + private List employeeList = new ArrayList<>(); +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo02/linktable/ProjectRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo02/linktable/ProjectRepository.java new file mode 100644 index 0000000..864681f --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo02/linktable/ProjectRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d02.one.to.many.demo02.linktable; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ProjectRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo02/linktable/TestJpaOneToManyDemo02.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo02/linktable/TestJpaOneToManyDemo02.java new file mode 100644 index 0000000..a98f889 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo02/linktable/TestJpaOneToManyDemo02.java @@ -0,0 +1,146 @@ +package com.knits.jpa.orm.d02.one.to.many.demo02.linktable; + +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.TestPropertySource; + +import java.util.List; +import java.util.Optional; + +@DataJpaTest +@EntityScan("com.knits.jpa.orm.d02.one.to.many.demo02.*") +@EnableJpaRepositories("com.knits.jpa.orm.d02.one.to.many.demo02.*") +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@TestPropertySource(properties = { + "spring.jpa.hibernate.ddl-auto=create", + "spring.datasource.url=jdbc:postgresql://localhost:5432/JPA-ORM-02-02" +}) +@Slf4j +//to clean and fill the DB before each test +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +public class TestJpaOneToManyDemo02 { + + @Autowired + private EmployeeRepository employeeRepository; + + @Autowired + private ProjectRepository projectRepository; + + @BeforeEach + @Rollback(value = false) + //In DB Employee table project_id is null + public void initDatabase(){ + + Project project = new Project(); + project.setName("A Mock Project Name"); + + Employee employee = new Employee(); + employee.setFirstName("Stefano"); + employee.setLastName("Fiorenza"); + + Employee employee2 = new Employee(); + employee2.setFirstName("Luna"); + employee2.setLastName("Doria"); + + project.getEmployeeList().add(employee); + project.getEmployeeList().add(employee2); + + employeeRepository.save(employee); + employeeRepository.save(employee2); + Project savedProject = projectRepository.save(project); + + log.info("Employees for Project: {} ",savedProject.getName()); + savedProject.getEmployeeList().forEach(emp -> log.info("Employee Found: {} ",emp.getFirstName())); + + } + + @Test + @Rollback(value = false) + public void getProjectWithEmployees(){ + + Project project = projectRepository.findById(52L).get(); + + Assertions.assertThat(project.getEmployeeList().size()).isGreaterThan(0); + } + + @Test + @Rollback(value = false) + public void getListOfProjects(){ + + List projects = projectRepository.findAll(); + + Assertions.assertThat(projects.size()).isGreaterThan(0); + + } + + @Test + @Rollback(value = false) + public void updateEmployeeAndProject(){ + + Project project = projectRepository.findById(52L).get(); + + project.setName("Mock 2"); + project.getEmployeeList().forEach(emp -> emp.setFirstName("Anton")); + + Project projectUpdated = projectRepository.save(project); + Employee employeeUpdated = projectUpdated.getEmployeeList().get(1); + + Assertions.assertThat(projectUpdated.getName()).isEqualTo("Mock 2"); + Assertions.assertThat(employeeUpdated.getFirstName()).isEqualTo("Anton"); + + } + + @Test + @Rollback(value = false) + //can not delete employee if he in relationships with project + //Have to delete employee from list and after delete employee + public void removeEmployeeFromProjectAndDeleteEmployee(){ + + Employee employee = employeeRepository.findById(1L).get(); + + Project project = projectRepository.findById(52L).get(); + project.getEmployeeList().remove(employee); + employeeRepository.delete(employee); + + Employee employee1 = null; + + Optional optionalEmployee = employeeRepository.findById(1L); + + if(optionalEmployee.isPresent()){ + employee1 = optionalEmployee.get(); + } + + project.getEmployeeList().forEach(emp -> log.info("Employee Found: {} ",emp.getFirstName())); + + Assertions.assertThat(employee1).isNull(); + } + + @Test + @Rollback(value = false) + //can delete the project even if there is a list with employees + public void deleteProject(){ + + Project project = projectRepository.findById(52L).get(); + projectRepository.delete(project); + + Project project1 = null; + + Optional optionalProject = projectRepository.findById(52L); + + if(optionalProject.isPresent()){ + project1 = optionalProject.get(); + } + + Assertions.assertThat(project1).isNull(); + + } +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo03/FKey/Employee.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo03/FKey/Employee.java new file mode 100644 index 0000000..0332d4a --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo03/FKey/Employee.java @@ -0,0 +1,21 @@ +package com.knits.jpa.orm.d02.one.to.many.demo03.FKey; + +import lombok.Data; + +import javax.persistence.*; + +@Entity +@Data +public class Employee { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String firstName; + + private String lastName; + + @ManyToOne + private Project project; +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo03/FKey/EmployeeRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo03/FKey/EmployeeRepository.java new file mode 100644 index 0000000..59e1db7 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo03/FKey/EmployeeRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d02.one.to.many.demo03.FKey; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface EmployeeRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo03/FKey/Project.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo03/FKey/Project.java new file mode 100644 index 0000000..0ada02e --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo03/FKey/Project.java @@ -0,0 +1,17 @@ +package com.knits.jpa.orm.d02.one.to.many.demo03.FKey; + +import lombok.Data; + +import javax.persistence.*; + +@Entity +@Data +public class Project { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String name; +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo03/FKey/ProjectRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo03/FKey/ProjectRepository.java new file mode 100644 index 0000000..2ffe6f6 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo03/FKey/ProjectRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d02.one.to.many.demo03.FKey; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ProjectRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo03/FKey/TestJpaOneToManyDemo03.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo03/FKey/TestJpaOneToManyDemo03.java new file mode 100644 index 0000000..4142005 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo03/FKey/TestJpaOneToManyDemo03.java @@ -0,0 +1,144 @@ +package com.knits.jpa.orm.d02.one.to.many.demo03.FKey; + + +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.TestPropertySource; + +import java.util.List; +import java.util.Optional; + +@DataJpaTest +@EntityScan("com.knits.jpa.orm.d02.one.to.many.demo03.*") +@EnableJpaRepositories("com.knits.jpa.orm.d02.one.to.many.demo03.*") +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@TestPropertySource(properties = { + "spring.jpa.hibernate.ddl-auto=create", + "spring.datasource.url=jdbc:postgresql://localhost:5432/JPA-ORM-02-03" +}) +@Slf4j +//to clean and fill the DB before each test +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +public class TestJpaOneToManyDemo03 { + + @Autowired + private EmployeeRepository employeeRepository; + + @Autowired + private ProjectRepository projectRepository; + + @BeforeEach + @Rollback(value = false) + //In Db Employee table we can see project_id + public void initDatabase(){ + + Project project = new Project(); + project.setName("A Mock Project Name"); + + Employee employee = new Employee(); + employee.setFirstName("Stefano"); + employee.setLastName("Fiorenza"); + + Employee employee2 = new Employee(); + employee2.setFirstName("Luna"); + employee2.setLastName("Doria"); + + employee.setProject(project); + employee2.setProject(project); + + projectRepository.save(project); + employeeRepository.save(employee); + employeeRepository.save(employee2); + + } + + @Test + @Rollback(value = false) + public void getEmployeeWithProject(){ + + Employee employee = employeeRepository.findById(52L).get(); + + Assertions.assertThat(employee.getProject().getName()).isEqualTo("A Mock Project Name"); + } + + @Test + @Rollback(value = false) + public void getListOfEmployees(){ + + List employees = employeeRepository.findAll(); + + Assertions.assertThat(employees.size()).isGreaterThan(0); + + } + + @Test + @Rollback(value = false) + public void updateEmployeeAndProject(){ + + Employee employee = employeeRepository.findById(52L).get(); + + employee.getProject().setName("Mock 2"); + employee.setFirstName("Anton"); + + Employee employeeUpdated = employeeRepository.save(employee); + + Assertions.assertThat(employeeUpdated.getFirstName()).isEqualTo("Anton"); + Assertions.assertThat(employeeUpdated.getProject().getName()).isEqualTo("Mock 2"); + + } + + @Test + @Rollback(value = false) + //can delete employee with project reference + public void deleteEmployee(){ + + Employee employee = employeeRepository.findById(52L).get(); + + employeeRepository.delete(employee); + + Employee employee1 = null; + + Optional optionalEmployee = employeeRepository.findById(52L); + + if(optionalEmployee.isPresent()){ + employee1 = optionalEmployee.get(); + } + + Assertions.assertThat(employee1).isNull(); + } + + @Test + @Rollback(value = false) + //I can't delete a project if it has employees + public void deleteProject(){ + + Employee employee = employeeRepository.findById(53L).get(); + employee.setProject(null); + + Employee employee2 = employeeRepository.findById(52L).get(); + employee2.setProject(null); + + Project project = projectRepository.findById(1L).get(); + projectRepository.delete(project); + + Project project1 = null; + + Optional optionalProject = projectRepository.findById(1L); + + if(optionalProject.isPresent()){ + project1 = optionalProject.get(); + } + + Assertions.assertThat(project1).isNull(); + + } +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo04/bidirectionalJoinTable/Employee.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo04/bidirectionalJoinTable/Employee.java new file mode 100644 index 0000000..c5aa274 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo04/bidirectionalJoinTable/Employee.java @@ -0,0 +1,39 @@ +package com.knits.jpa.orm.d02.one.to.many.demo04.bidirectionalJoinTable; + +import lombok.Data; + +import javax.persistence.*; + +@Entity +@Data +public class Employee { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String firstName; + + private String lastName; + + /* + By default, a bidirectional OneToMany/ManyToOne association uses a foreign + key column on the side which has the single-valued reference with @ManyToOne annotation. + We can override this default by using an intermediate join table to persist the association. + To achieve that we have to use @JoinTable annotation on the both sides. + In this case, we don't have to use 'mappedBy' element of the @OneToMany annotation. + + Note that we have to use insertable/updatable=false on @ManyToOne side, + to avoid persisting same relationship twice from both sides. When insertable/updatable=false, + the column is not included in the generated SQL INSERT/UPDATE statements. + */ + @ManyToOne + @JoinTable(name = "EMPLOYEE_PROJECT_TABLE", + joinColumns = {@JoinColumn(name = "EMPLOYEE_FK", insertable = false, + updatable = false, referencedColumnName = "id")}, + inverseJoinColumns = {@JoinColumn(name = "PROJECT_FK", insertable = false, + updatable = false, referencedColumnName = "id")} + ) + private Project project; +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo04/bidirectionalJoinTable/EmployeeRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo04/bidirectionalJoinTable/EmployeeRepository.java new file mode 100644 index 0000000..18b507f --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo04/bidirectionalJoinTable/EmployeeRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d02.one.to.many.demo04.bidirectionalJoinTable; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface EmployeeRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo04/bidirectionalJoinTable/Project.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo04/bidirectionalJoinTable/Project.java new file mode 100644 index 0000000..3e6a1b4 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo04/bidirectionalJoinTable/Project.java @@ -0,0 +1,34 @@ +package com.knits.jpa.orm.d02.one.to.many.demo04.bidirectionalJoinTable; + +import lombok.Data; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Data +public class Project { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String name; + + + /* + By default, a bidirectional OneToMany/ManyToOne association uses a foreign + key column on the side which has the single-valued reference with @ManyToOne annotation. + We can override this default by using an intermediate join table to persist the association. + To achieve that we have to use @JoinTable annotation on the both sides. + In this case, we don't have to use 'mappedBy' element of the @OneToMany annotation. + */ + @OneToMany + @JoinTable(name = "EMPLOYEE_PROJECT_TABLE", + joinColumns = {@JoinColumn(name = "PROJECT_FK", referencedColumnName = "id")}, + inverseJoinColumns = {@JoinColumn(name = "EMPLOYEE_FK", referencedColumnName = "id")} + ) + private List employeeList = new ArrayList<>(); +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo04/bidirectionalJoinTable/ProjectRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo04/bidirectionalJoinTable/ProjectRepository.java new file mode 100644 index 0000000..15a76a3 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo04/bidirectionalJoinTable/ProjectRepository.java @@ -0,0 +1,9 @@ +package com.knits.jpa.orm.d02.one.to.many.demo04.bidirectionalJoinTable; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ProjectRepository extends JpaRepository { + +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo04/bidirectionalJoinTable/TestJpaOneToManyDemo04.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo04/bidirectionalJoinTable/TestJpaOneToManyDemo04.java new file mode 100644 index 0000000..6b52d58 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo04/bidirectionalJoinTable/TestJpaOneToManyDemo04.java @@ -0,0 +1,145 @@ +package com.knits.jpa.orm.d02.one.to.many.demo04.bidirectionalJoinTable; + +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.TestPropertySource; + +import java.util.List; +import java.util.Optional; + +@DataJpaTest +@EntityScan("com.knits.jpa.orm.d02.one.to.many.demo04.*") +@EnableJpaRepositories("com.knits.jpa.orm.d02.one.to.many.demo04.*") +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@TestPropertySource(properties = { + "spring.jpa.hibernate.ddl-auto=create", + "spring.datasource.url=jdbc:postgresql://localhost:5432/JPA-ORM-02-04" +}) +@Slf4j +//to clean and fill the DB before each test +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +public class TestJpaOneToManyDemo04 { + + @Autowired + private EmployeeRepository employeeRepository; + + @Autowired + private ProjectRepository projectRepository; + + @BeforeEach + @Rollback(value = false) + public void initDatabase() { + + Project project = new Project(); + project.setName("A Mock Project Name"); + + Employee employee = new Employee(); + employee.setFirstName("Stefano"); + employee.setLastName("Fiorenza"); + + Employee employee2 = new Employee(); + employee2.setFirstName("Luna"); + employee2.setLastName("Doria"); + + project.getEmployeeList().add(employee); + project.getEmployeeList().add(employee2); + + employeeRepository.save(employee); + employeeRepository.save(employee2); + Project savedProject = projectRepository.save(project); + + log.info("Employees for Project: {} ", savedProject.getName()); + savedProject.getEmployeeList().forEach(emp -> log.info("Employee Found: {} ", emp.getFirstName())); + + } + + @Test + @Rollback(value = false) + public void getProjectWithEmployees() { + + Project project = projectRepository.findById(52L).get(); + + Assertions.assertThat(project.getEmployeeList().size()).isGreaterThan(0); + } + + @Test + @Rollback(value = false) + public void getListOfProjects() { + + List projects = projectRepository.findAll(); + + Assertions.assertThat(projects.size()).isGreaterThan(0); + + } + + @Test + @Rollback(value = false) + public void updateEmployeeAndProject() { + + Project project = projectRepository.findById(52L).get(); + + project.setName("Mock 2"); + project.getEmployeeList().forEach(emp -> emp.setFirstName("Anton")); + + Project projectUpdated = projectRepository.save(project); + Employee employeeUpdated = projectUpdated.getEmployeeList().get(1); + + Assertions.assertThat(projectUpdated.getName()).isEqualTo("Mock 2"); + Assertions.assertThat(employeeUpdated.getFirstName()).isEqualTo("Anton"); + + } + + @Test + @Rollback(value = false) + // can delete an employee who is on the project + public void deleteEmployee() { + + Employee employee = employeeRepository.findById(1L).get(); + + employeeRepository.delete(employee); + + Employee employee1 = null; + + Optional optionalEmployee = employeeRepository.findById(1L); + + if (optionalEmployee.isPresent()) { + employee1 = optionalEmployee.get(); + } + + Assertions.assertThat(employee1).isNull(); + } + + @Test + @Rollback(value = false) + //can delete the project even if there is a list with employees + //can delete both employees and project without any conflicts. Even if objects are related + public void deleteProject() { + + Project project = projectRepository.findById(52L).get(); + projectRepository.delete(project); + + Project project1 = null; + + Optional optionalProject = projectRepository.findById(52L); + + if (optionalProject.isPresent()) { + project1 = optionalProject.get(); + } + + Assertions.assertThat(project1).isNull(); + + } + + /* + can delete both workers and the project without any conflicts. Even if u objects are related + */ +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo05/Sets/Employee.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo05/Sets/Employee.java new file mode 100644 index 0000000..bd47cdf --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo05/Sets/Employee.java @@ -0,0 +1,36 @@ +package com.knits.jpa.orm.d02.one.to.many.demo05.Sets; + +import lombok.Data; + +import javax.persistence.*; + +@Entity +@Data +public class Employee { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String firstName; + + private String lastName; + + @ManyToOne(fetch = FetchType.LAZY) + private Project project; + + + /*It's important to @Override the equals() and hashCode() method since the Author entity relies on + checking equality for it's helper methods...*/ + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Employee )) return false; + return id != null && id.equals(((Employee) o).getId()); + } + @Override + public int hashCode() { + return getClass().hashCode(); + } +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo05/Sets/EmployeeRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo05/Sets/EmployeeRepository.java new file mode 100644 index 0000000..2a3506e --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo05/Sets/EmployeeRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d02.one.to.many.demo05.Sets; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface EmployeeRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo05/Sets/Project.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo05/Sets/Project.java new file mode 100644 index 0000000..4df84e0 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo05/Sets/Project.java @@ -0,0 +1,35 @@ +package com.knits.jpa.orm.d02.one.to.many.demo05.Sets; + +import lombok.Data; + +import javax.persistence.*; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; + +@Entity +@Data +public class Project { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String name; + + @OneToMany(mappedBy = "project", cascade = CascadeType.ALL, orphanRemoval = false) + private Set employees = new HashSet<>(); + + public void addEmployee(Employee employee) { + employees.add(employee); + employee.setProject(this); + } + + public void removeEmployee(Employee employee) { + employees.remove(employee); + employee.setProject(null); + + } + +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo05/Sets/ProjectRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo05/Sets/ProjectRepository.java new file mode 100644 index 0000000..15eab7e --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo05/Sets/ProjectRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d02.one.to.many.demo05.Sets; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ProjectRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo05/Sets/TestJpaOneToManyDemo05.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo05/Sets/TestJpaOneToManyDemo05.java new file mode 100644 index 0000000..1a23043 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d02/one/to/many/demo05/Sets/TestJpaOneToManyDemo05.java @@ -0,0 +1,181 @@ +package com.knits.jpa.orm.d02.one.to.many.demo05.Sets; + + +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.TestPropertySource; + +import java.util.List; +import java.util.Optional; + + +@DataJpaTest +@EntityScan("com.knits.jpa.orm.d02.one.to.many.demo05.*") +@EnableJpaRepositories("com.knits.jpa.orm.d02.one.to.many.demo05.*") +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@TestPropertySource(properties = { + "spring.jpa.hibernate.ddl-auto=create", + "spring.datasource.url=jdbc:postgresql://localhost:5432/JPA-ORM-02-05" +}) +@Slf4j +//to clean and fill the DB before each test +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +public class TestJpaOneToManyDemo05 { + + @Autowired + private EmployeeRepository employeeRepository; + + @Autowired + private ProjectRepository projectRepository; + + + @BeforeEach + @Rollback(value = false) + public void initDatabase() { + + Project project = new Project(); + project.setName("A Mock Project Name"); + + Employee employee1 = new Employee(); + employee1.setFirstName("Stefano"); + employee1.setLastName("Fiorenza"); + + Employee employee2 = new Employee(); + employee2.setFirstName("Luna"); + employee2.setLastName("Doria"); + + //it works, but project_id in Employee table is null + /*project.getEmployees().add(employee); + project.getEmployees().add(employee2);*/ + + /*The helper methods addBook() and removeBook() are useful in keeping the persisted context in sync. + Strange things can happen when both sides of the bidirectional relationship aren't updated. + The database can get out of sync with the context and unexpected things can happen. + These methods make it easy to update both sides of the relationship...*/ + //via helper methods in model project_id is not null + project.addEmployee(employee1); + project.addEmployee(employee2); + + Project savedProject = projectRepository.save(project); + employeeRepository.save(employee1); + employeeRepository.save(employee2); + + log.info("Employees for Project: {} ", savedProject.getName()); + savedProject.getEmployees().forEach(emp -> log.info("Employee Found: {} ", emp.getFirstName())); + + } + + @Test + @Order(1) + @Rollback(value = false) + public void getProjectWithEmployees() { + + Project project = projectRepository.findById(1L).get(); + + Assertions.assertThat(project.getEmployees().size()).isGreaterThan(0); + + } + + @Test + @Order(2) + @Rollback(value = false) + public void getListOfProjects() { + + List projects = projectRepository.findAll(); + + Assertions.assertThat(projects.size()).isGreaterThan(0); + + } + + @Test + @Rollback(value = false) + @Order(3) + public void updateEmployeeAndProject() { + + Project project = projectRepository.findById(1L).get(); + + project.setName("Mock 2"); + project.getEmployees().forEach(emp -> emp.setFirstName("Anton")); + + Project projectUpdated = projectRepository.save(project); + Employee employeeUpdated = employeeRepository.findById(52L).get(); + + Assertions.assertThat(projectUpdated.getName()).isEqualTo("Mock 2"); + Assertions.assertThat(employeeUpdated.getFirstName()).isEqualTo("Anton"); + + } + + @Test + @Rollback(value = false) + @Order(4) + public void deleteEmployee() { + + Employee employee = employeeRepository.findById(53L).get(); + + employeeRepository.delete(employee); + + Employee employee1 = null; + + Optional optionalEmployee = employeeRepository.findById(53L); + + if (optionalEmployee.isPresent()) { + employee1 = optionalEmployee.get(); + } + + Assertions.assertThat(employee1).isNull(); + + } + + + @Test + @Rollback(value = false) + @Order(5) + public void deleteProjectShouldNotDeleteEmployees() { + + Project project = projectRepository.findById(1L).get(); + + Employee employee = employeeRepository.findById(52L).get(); + Employee employee1 = employeeRepository.findById(53L).get(); + + project.removeEmployee(employee); + project.removeEmployee(employee1); + + projectRepository.delete(project); + + List employees = employeeRepository.findAll(); + + Assertions.assertThat(employees.size()).isGreaterThan(0); + + } + + @Test + @Rollback(value = false) + @Order(6) + //since I have a project like parent, all children (employees) deletes with project + public void deleteProject() { + + Project project = projectRepository.findById(1L).get(); + + projectRepository.delete(project); + + Project project1 = null; + + Optional optionalProject = projectRepository.findById(1L); + + if (optionalProject.isPresent()) { + project1 = optionalProject.get(); + } + + Assertions.assertThat(project1).isNull(); + + } +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo01/TestJpaManyToManyDemo01.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo01/TestJpaManyToManyDemo01.java index 7643b02..5cd8fc6 100644 --- a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo01/TestJpaManyToManyDemo01.java +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo01/TestJpaManyToManyDemo01.java @@ -1,6 +1,8 @@ package com.knits.jpa.orm.d03.many.to.many.demo01; +import com.knits.jpa.orm.d02.one.to.many.demo04.bidirectionalJoinTable.Project; import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.domain.EntityScan; @@ -31,9 +33,9 @@ public class TestJpaManyToManyDemo01 { @Test @Rollback(value = false) - public void initDatabase(){ + public void initDatabase() { - Employee employee= new Employee(); + Employee employee = new Employee(); employee.setFirstName("Stefano"); employee.setLastName("Fiorenza"); @@ -65,11 +67,12 @@ public void initDatabase(){ employeeRepository.save(employee2); employeeRepository.save(employee3); - Group savedGroup =groupRepository.save(group); + Group savedGroup = groupRepository.save(group); groupRepository.save(group2); - log.info("Employees for Group: {} ",savedGroup.getName()); - savedGroup.getEmployees().forEach(emp -> log.info("Employee Found: {} ",emp.getFirstName())); + log.info("Employees for Group: {} ", savedGroup.getName()); + savedGroup.getEmployees().forEach(emp -> log.info("Employee Found: {} ", emp.getFirstName())); } + } diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo02/linkTable/Employee.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo02/linkTable/Employee.java new file mode 100644 index 0000000..9efdf92 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo02/linkTable/Employee.java @@ -0,0 +1,29 @@ +package com.knits.jpa.orm.d03.many.to.many.demo02.linkTable; + +import lombok.Data; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Data +/*The entity having the collection reference is called 'source' entity', +whereas the entity which is being referenced is called 'target entity'. +To map many-to-many association to database tables, +@ManyToMany annotation is used on the collection.*/ +//Source entity +public class Employee { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String firstName; + + private String lastName; + + @ManyToMany + private List groups = new ArrayList<>(); //Group is target entity +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo02/linkTable/EmployeeRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo02/linkTable/EmployeeRepository.java new file mode 100644 index 0000000..fabda30 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo02/linkTable/EmployeeRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d03.many.to.many.demo02.linkTable; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface EmployeeRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo02/linkTable/Group.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo02/linkTable/Group.java new file mode 100644 index 0000000..7c6fce3 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo02/linkTable/Group.java @@ -0,0 +1,19 @@ +package com.knits.jpa.orm.d03.many.to.many.demo02.linkTable; + +import lombok.Data; + +import javax.persistence.*; + +@Entity +@Table(name="\"group\"") //group is a reserved word in sql +@Data +//Target +public class Group { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String name; +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo02/linkTable/GroupRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo02/linkTable/GroupRepository.java new file mode 100644 index 0000000..cbcee75 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo02/linkTable/GroupRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d03.many.to.many.demo02.linkTable; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface GroupRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo02/linkTable/TestJpaManyToManyDemo02.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo02/linkTable/TestJpaManyToManyDemo02.java new file mode 100644 index 0000000..5920e6f --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo02/linkTable/TestJpaManyToManyDemo02.java @@ -0,0 +1,163 @@ +package com.knits.jpa.orm.d03.many.to.many.demo02.linkTable; + +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.TestPropertySource; + +import java.util.List; +import java.util.Optional; + +@DataJpaTest +@EntityScan("com.knits.jpa.orm.d03.many.to.many.demo02.*") +@EnableJpaRepositories("com.knits.jpa.orm.d03.many.to.many.demo02.*") +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@TestPropertySource(properties = { + "spring.jpa.hibernate.ddl-auto=create", + "spring.datasource.url=jdbc:postgresql://localhost:5432/JPA-ORM-03-01" +}) +@Slf4j +//help to clean and fill the DB before each test +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +public class TestJpaManyToManyDemo02 { + + @Autowired + private EmployeeRepository employeeRepository; + + @Autowired + private GroupRepository groupRepository; + + @BeforeEach + @Rollback(value = false) + public void initDatabase(){ + + Employee employee= new Employee(); + employee.setFirstName("Stefano"); + employee.setLastName("Fiorenza"); + + Employee employee2 = new Employee(); + employee2.setFirstName("Luna"); + employee2.setLastName("Doria"); + + Employee employee3 = new Employee(); + employee3.setFirstName("Maria"); + employee3.setLastName("Bertolucci"); + + Group group = new Group(); + group.setName("A Mock Group Name"); + + Group group2 = new Group(); + group2.setName("Another Mock Group Name"); + + //emp 1 and 2 are in group1 + employee.getGroups().add(group); + employee2.getGroups().add(group); + + //emp 3 and 1 are in group2 + employee3.getGroups().add(group2); + employee.getGroups().add(group2); + + groupRepository.save(group); + groupRepository.save(group2); + + Employee savedEmployee = employeeRepository.save(employee); + employeeRepository.save(employee2); + employeeRepository.save(employee3); + + log.info("Employee: {} ",savedEmployee.getFirstName()); + savedEmployee.getGroups().forEach(gr -> log.info("Groups Found: {} ",gr.getName())); + + } + + @Test + @Rollback(value = false) + public void getEmployeeWithGroups() { + + Employee employee = employeeRepository.findById(52L).get(); + + Assertions.assertThat(employee.getGroups().size()).isGreaterThan(0); + } + + @Test + @Rollback(value = false) + public void getListOfGroups() { + + List groups = groupRepository.findAll(); + + Assertions.assertThat(groups.size()).isGreaterThan(0); + + } + + @Test + @Rollback(value = false) + public void updateEmployeeAndGroup() { + + Employee employee = employeeRepository.findById(52L).get(); + + employee.setFirstName("Anton"); + employee.getGroups().forEach(emp -> emp.setName("Group updated")); + + Employee employeeUpdated = employeeRepository.save(employee); + + Assertions.assertThat(employeeUpdated.getFirstName()).isEqualTo("Anton"); + Assertions.assertThat(employeeUpdated.getGroups().get(1).getName()).isEqualTo("Group updated"); + + } + + @Test + @Rollback(value = false) + //can delete an employee who in the group + public void deleteEmployee() { + + Employee employee = employeeRepository.findById(52L).get(); + + employeeRepository.delete(employee); + + Employee employee1 = null; + + Optional optionalEmployee = employeeRepository.findById(52L); + + if (optionalEmployee.isPresent()) { + employee1 = optionalEmployee.get(); + } + + Assertions.assertThat(employee1).isNull(); + } + + @Test + @Rollback(value = false) + //can not delete the group/target with employees/source + //should remove employees from group then can delete group + public void removeEmployeesFromGroupThenDeleteGroup() { + + Employee employee = employeeRepository.findById(52L).get(); + Employee employee1 = employeeRepository.findById(53L).get(); + + Group group = groupRepository.findById(1L).get(); + + employee.getGroups().remove(group); + employee1.getGroups().remove(group); + + groupRepository.delete(group); + + Group group1 = null; + + Optional optionalGroup = groupRepository.findById(1L); + + if (optionalGroup.isPresent()) { + group1 = optionalGroup.get(); + } + + Assertions.assertThat(group1).isNull(); + + } + +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo03/bidirectional/Employee.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo03/bidirectional/Employee.java new file mode 100644 index 0000000..c260310 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo03/bidirectional/Employee.java @@ -0,0 +1,25 @@ +package com.knits.jpa.orm.d03.many.to.many.demo03.bidirectional; + + +import lombok.Data; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Data +public class Employee { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String firstName; + + private String lastName; + + @ManyToMany + private List groups = new ArrayList<>(); +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo03/bidirectional/EmployeeRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo03/bidirectional/EmployeeRepository.java new file mode 100644 index 0000000..1aa199d --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo03/bidirectional/EmployeeRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d03.many.to.many.demo03.bidirectional; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface EmployeeRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo03/bidirectional/Group.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo03/bidirectional/Group.java new file mode 100644 index 0000000..111b51c --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo03/bidirectional/Group.java @@ -0,0 +1,25 @@ +package com.knits.jpa.orm.d03.many.to.many.demo03.bidirectional; + +import lombok.Data; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Table(name="\"group\"") //group is a reserved word in sql +@Data +public class Group { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String name; + + @ManyToMany + private List employees = new ArrayList<>(); + + +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo03/bidirectional/GroupRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo03/bidirectional/GroupRepository.java new file mode 100644 index 0000000..fc28c2f --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo03/bidirectional/GroupRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d03.many.to.many.demo03.bidirectional; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface GroupRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo03/bidirectional/TestJpaManyToManyDemo03.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo03/bidirectional/TestJpaManyToManyDemo03.java new file mode 100644 index 0000000..2fda88c --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo03/bidirectional/TestJpaManyToManyDemo03.java @@ -0,0 +1,164 @@ +package com.knits.jpa.orm.d03.many.to.many.demo03.bidirectional; + + +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.TestPropertySource; + +import java.util.List; +import java.util.Optional; + +@DataJpaTest +@EntityScan("com.knits.jpa.orm.d03.many.to.many.demo03.*") +@EnableJpaRepositories("com.knits.jpa.orm.d03.many.to.many.demo03.*") +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@TestPropertySource(properties = { + "spring.jpa.hibernate.ddl-auto=create", + "spring.datasource.url=jdbc:postgresql://localhost:5432/JPA-ORM-03-02" +}) +@Slf4j +//help to clean and fill the DB before each test +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +public class TestJpaManyToManyDemo03 { + + @Autowired + private EmployeeRepository employeeRepository; + + @Autowired + private GroupRepository groupRepository; + + @BeforeEach + @Rollback(value = false) + //created two tables with FKs - employee_groups(with records) and group_employees(this dont have records) + public void initDatabase(){ + + Employee employee= new Employee(); + employee.setFirstName("Stefano"); + employee.setLastName("Fiorenza"); + + Employee employee2 = new Employee(); + employee2.setFirstName("Luna"); + employee2.setLastName("Doria"); + + Employee employee3 = new Employee(); + employee3.setFirstName("Maria"); + employee3.setLastName("Bertolucci"); + + Group group = new Group(); + group.setName("A Mock Group Name"); + + Group group2 = new Group(); + group2.setName("Another Mock Group Name"); + + //emp 1 and 2 are in group1 + employee.getGroups().add(group); + employee2.getGroups().add(group); + + //emp 3 and 1 are in group2 + employee3.getGroups().add(group2); + employee.getGroups().add(group2); + + groupRepository.save(group); + groupRepository.save(group2); + + Employee savedEmployee = employeeRepository.save(employee); + employeeRepository.save(employee2); + employeeRepository.save(employee3); + + log.info("Employee: {} ",savedEmployee.getFirstName()); + savedEmployee.getGroups().forEach(gr -> log.info("Groups Found: {} ",gr.getName())); + + } + + @Test + @Rollback(value = false) + public void getEmployeeWithGroups() { + + Employee employee = employeeRepository.findById(52L).get(); + + Assertions.assertThat(employee.getGroups().size()).isGreaterThan(0); + } + + @Test + @Rollback(value = false) + public void getListOfGroups() { + + List groups = groupRepository.findAll(); + + Assertions.assertThat(groups.size()).isGreaterThan(0); + + } + + @Test + @Rollback(value = false) + public void updateEmployeeAndGroup() { + + Employee employee = employeeRepository.findById(52L).get(); + + employee.setFirstName("Anton"); + employee.getGroups().forEach(emp -> emp.setName("Group updated")); + + Employee employeeUpdated = employeeRepository.save(employee); + + Assertions.assertThat(employeeUpdated.getFirstName()).isEqualTo("Anton"); + Assertions.assertThat(employeeUpdated.getGroups().get(1).getName()).isEqualTo("Group updated"); + + } + + @Test + @Rollback(value = false) + //can delete an employee who in the group + public void deleteEmployee() { + + Employee employee = employeeRepository.findById(52L).get(); + + employeeRepository.delete(employee); + + Employee employee1 = null; + + Optional optionalEmployee = employeeRepository.findById(52L); + + if (optionalEmployee.isPresent()) { + employee1 = optionalEmployee.get(); + } + + Assertions.assertThat(employee1).isNull(); + } + + @Test + @Rollback(value = false) + //can not delete the group with employees + //should remove employees from group then can delete group + public void removeEmployeesFromGroupThenDeleteGroup() { + + Employee employee = employeeRepository.findById(52L).get(); + Employee employee1 = employeeRepository.findById(53L).get(); + + Group group = groupRepository.findById(1L).get(); + + employee.getGroups().remove(group); + employee1.getGroups().remove(group); + + groupRepository.delete(group); + + Group group1 = null; + + Optional optionalGroup = groupRepository.findById(1L); + + if (optionalGroup.isPresent()) { + group1 = optionalGroup.get(); + } + + Assertions.assertThat(group1).isNull(); + + } +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/Employee.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/Employee.java new file mode 100644 index 0000000..e1a757b --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/Employee.java @@ -0,0 +1,59 @@ +package com.knits.jpa.orm.d03.many.to.many.demo04.withNewEntity; + +import lombok.Data; + +import javax.persistence.*; +import java.util.HashSet; +import java.util.Set; + +@Entity +@Data +public class Employee { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String firstName; + + private String lastName; + + @OneToMany(mappedBy = "employee") + private Set registrations = new HashSet<>(); + + public void addRegistration(GroupRegistration groupRegistration) { + registrations.add(groupRegistration); + groupRegistration.setEmployee(this); + } + + public void removeRegistration(GroupRegistration groupRegistration) { + registrations.remove(groupRegistration); + groupRegistration.setEmployee(null); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Employee other = (Employee) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/EmployeeRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/EmployeeRepository.java new file mode 100644 index 0000000..c65092f --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/EmployeeRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d03.many.to.many.demo04.withNewEntity; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface EmployeeRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/Group.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/Group.java new file mode 100644 index 0000000..08fd0f9 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/Group.java @@ -0,0 +1,58 @@ +package com.knits.jpa.orm.d03.many.to.many.demo04.withNewEntity; + +import lombok.Data; + +import javax.persistence.*; +import java.util.HashSet; +import java.util.Set; + +@Entity +@Data +@Table(name="\"group\"") //group is a reserved word in sql +public class Group { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String name; + + @OneToMany(mappedBy = "group") + private Set registrations = new HashSet<>(); + + public void addRegistration(GroupRegistration groupRegistration) { + registrations.add(groupRegistration); + groupRegistration.setGroup(this); + } + + public void removeRegistration(GroupRegistration groupRegistration) { + registrations.remove(groupRegistration); + groupRegistration.setGroup(null); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Group other = (Group) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/GroupRegistration.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/GroupRegistration.java new file mode 100644 index 0000000..f4b77e2 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/GroupRegistration.java @@ -0,0 +1,53 @@ +package com.knits.jpa.orm.d03.many.to.many.demo04.withNewEntity; + +import lombok.Data; + +import javax.persistence.*; +import java.time.LocalDateTime; + +@Entity +@Data +public class GroupRegistration { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + @ManyToOne + @JoinColumn(name = "employee_id") + private Employee employee; + + @ManyToOne + @JoinColumn(name = "group_id") + private Group group; + + private LocalDateTime registeredAt; + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + GroupRegistration other = (GroupRegistration) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } + + +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/GroupRegistrationRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/GroupRegistrationRepository.java new file mode 100644 index 0000000..f5175ac --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/GroupRegistrationRepository.java @@ -0,0 +1,10 @@ +package com.knits.jpa.orm.d03.many.to.many.demo04.withNewEntity; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface GroupRegistrationRepository extends JpaRepository { + + +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/GroupRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/GroupRepository.java new file mode 100644 index 0000000..3882e7d --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/GroupRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d03.many.to.many.demo04.withNewEntity; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface GroupRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/TestJpaManyToManyDemo04.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/TestJpaManyToManyDemo04.java new file mode 100644 index 0000000..eba9594 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo04/withNewEntity/TestJpaManyToManyDemo04.java @@ -0,0 +1,228 @@ +package com.knits.jpa.orm.d03.many.to.many.demo04.withNewEntity; + + +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.TestPropertySource; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +@DataJpaTest +@EntityScan("com.knits.jpa.orm.d03.many.to.many.demo04.*") +@EnableJpaRepositories("com.knits.jpa.orm.d03.many.to.many.demo04.*") +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@TestPropertySource(properties = { + "spring.jpa.hibernate.ddl-auto=create", + "spring.datasource.url=jdbc:postgresql://localhost:5432/JPA-ORM-03-03" +}) +@Slf4j +//help to clean and fill the DB before each test +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +public class TestJpaManyToManyDemo04 { + + @Autowired + private EmployeeRepository employeeRepository; + + @Autowired + private GroupRepository groupRepository; + + @Autowired + private GroupRegistrationRepository groupRegistrationRepository; + + @BeforeEach + @Rollback(value = false) + public void initDatabase(){ + + Employee employee= new Employee(); + employee.setFirstName("Stefano"); + employee.setLastName("Fiorenza"); + + Employee employee2 = new Employee(); + employee2.setFirstName("Luna"); + employee2.setLastName("Doria"); + + Employee employee3 = new Employee(); + employee3.setFirstName("Maria"); + employee3.setLastName("Bertolucci"); + + Group group = new Group(); + group.setName("A Mock Group Name"); + + Group group2 = new Group(); + group2.setName("Another Mock Group Name"); + + //create registration object + GroupRegistration groupRegistration = new GroupRegistration(); + groupRegistration.setRegisteredAt(LocalDateTime.now()); + + GroupRegistration groupRegistration2 = new GroupRegistration(); + groupRegistration2.setRegisteredAt(LocalDateTime.now()); + + GroupRegistration groupRegistration3 = new GroupRegistration(); + groupRegistration3.setRegisteredAt(LocalDateTime.now()); + + GroupRegistration groupRegistration4 = new GroupRegistration(); + groupRegistration4.setRegisteredAt(LocalDateTime.now()); + + //Use helper methods (add and set) + employee.addRegistration(groupRegistration); + employee.addRegistration(groupRegistration2); + employee2.addRegistration(groupRegistration3); + employee3.addRegistration(groupRegistration4); + + group.addRegistration(groupRegistration); + group2.addRegistration(groupRegistration2); + group.addRegistration(groupRegistration3); + group2.addRegistration(groupRegistration4); + + //save two groups + groupRepository.save(group); + groupRepository.save(group2); + + //save three employees + employeeRepository.save(employee); + Employee savedEmployee = employeeRepository.save(employee2); + employeeRepository.save(employee3); + + //save 4 registrations + groupRegistrationRepository.save(groupRegistration); + groupRegistrationRepository.save(groupRegistration2); + groupRegistrationRepository.save(groupRegistration3); + groupRegistrationRepository.save(groupRegistration4); + + + log.info("Employee: {} ",savedEmployee.getFirstName()); + savedEmployee.getRegistrations().forEach(reg -> log.info("Registered in group: {} ",reg.getGroup().getName())); + + } + + @Test + @Rollback(value = false) + public void getGroupRegistration() { + + GroupRegistration groupRegistration = groupRegistrationRepository.findById(102L).get(); + + Assertions.assertThat(groupRegistration.getId()).isEqualTo(102L); + } + + @Test + @Rollback(value = false) + public void getGroup() { + + Group group = groupRepository.findById(1L).get(); + + Assertions.assertThat(group.getId()).isEqualTo(1L); + } + + @Test + @Rollback(value = false) + public void getEmployee() { + + Employee employee = employeeRepository.findById(52L).get(); + + Assertions.assertThat(employee.getId()).isEqualTo(52L); + } + + + @Test + @Rollback(value = false) + public void getEmployeeWithRegistrations() { + + Employee employee = employeeRepository.findById(52L).get(); + + Assertions.assertThat(employee.getRegistrations().size()).isGreaterThan(0); + } + + @Test + @Rollback(value = false) + public void getListOfGroups() { + + List groups = groupRepository.findAll(); + + Assertions.assertThat(groups.size()).isGreaterThan(0); + + } + + @Test + @Rollback(value = false) + public void updateEmployeeAndGroup() { + + Employee employee = employeeRepository.findById(52L).get(); + + employee.setFirstName("Anton"); + employee.getRegistrations().forEach(groupRegistration -> groupRegistration.getGroup().setName("SuperGroup")); + + Employee employeeUpdated = employeeRepository.save(employee); + Group groupUpdated = groupRepository.findById(1L).get(); + + Assertions.assertThat(employeeUpdated.getFirstName()).isEqualTo("Anton"); + Assertions.assertThat(groupUpdated.getName()).isEqualTo("SuperGroup"); + + } + + @Test + @Rollback(value = false) + //can not delete an employee who in the reg_group + //should to delete employee registrations then delete employee + public void deleteEmployee() { + + Employee employee = employeeRepository.findById(52L).get(); + + GroupRegistration groupRegistration = groupRegistrationRepository.findById(102L).get(); + GroupRegistration groupRegistration2 = groupRegistrationRepository.findById(103L).get(); + + groupRegistrationRepository.delete(groupRegistration); + groupRegistrationRepository.delete(groupRegistration2); + + employeeRepository.delete(employee); + + Employee employee1 = null; + + Optional optionalEmployee = employeeRepository.findById(52L); + + if (optionalEmployee.isPresent()) { + employee1 = optionalEmployee.get(); + } + + Assertions.assertThat(employee1).isNull(); + } + + @Test + @Rollback(value = false) + //can not delete a group if its in the reg_group + //should to delete group registrations then delete group + public void deleteGroup() { + + Group group = groupRepository.findById(1L).get(); + + GroupRegistration groupRegistration = groupRegistrationRepository.findById(102L).get(); + GroupRegistration groupRegistration2 = groupRegistrationRepository.findById(104L).get(); + + groupRegistrationRepository.delete(groupRegistration); + groupRegistrationRepository.delete(groupRegistration2); + + groupRepository.delete(group); + + Group group1 = null; + + Optional optionalGroup = groupRepository.findById(1L); + + if (optionalGroup.isPresent()) { + group1 = optionalGroup.get(); + } + + Assertions.assertThat(group1).isNull(); + } + +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/Employee.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/Employee.java new file mode 100644 index 0000000..6aa4d60 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/Employee.java @@ -0,0 +1,74 @@ +package com.knits.jpa.orm.d03.many.to.many.demo05.bestPractice; + +import lombok.Data; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; + +@Entity +@Data +public class Employee { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + private String firstName; + + private String lastName; + + @OneToMany( + mappedBy = "employee", + cascade = CascadeType.ALL, + orphanRemoval = true + ) + private List groups = new ArrayList<>(); + + public Employee() { + } + + public Employee(String lastName) { + this.lastName = lastName; + } + + public void addGroup(Group group) { + EmployeeGroup employeeGroup = new EmployeeGroup(this, group); + groups.add(employeeGroup); + group.getEmployees().add(employeeGroup); + } + + public void removeGroup(Group group) { + for (Iterator iterator = groups.iterator(); + iterator.hasNext(); ) { + EmployeeGroup employeeGroup = iterator.next(); + + if (employeeGroup.getEmployee().equals(this) && + employeeGroup.getGroup().equals(group)) { + iterator.remove(); + employeeGroup.getGroup().getEmployees().remove(employeeGroup); + employeeGroup.setEmployee(null); + employeeGroup.setGroup(null); + } + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o == null || getClass() != o.getClass()) + return false; + + Employee employee = (Employee) o; + return Objects.equals(lastName, employee.lastName); + } + + @Override + public int hashCode() { + return Objects.hash(lastName); + } +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/EmployeeGroup.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/EmployeeGroup.java new file mode 100644 index 0000000..120aa7b --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/EmployeeGroup.java @@ -0,0 +1,58 @@ +package com.knits.jpa.orm.d03.many.to.many.demo05.bestPractice; + +import lombok.Data; + +import javax.persistence.*; +import java.util.Date; +import java.util.Objects; + +@Entity(name = "EmployeeGroup") +@Table(name = "employee_group") +@Data +public class EmployeeGroup { + + @EmbeddedId + private EmployeeGroupId id; + + @ManyToOne(fetch = FetchType.LAZY) + @MapsId("employeeId") + private Employee employee; + + @ManyToOne(fetch = FetchType.LAZY) + @MapsId("groupId") + private Group group; + + @Column(name = "created_on") + private Date createdOn = new Date(); + + private EmployeeGroup() { + + } + + public EmployeeGroup(Employee employee, Group group) { + this.employee = employee; + this.group = group; + this.id = new EmployeeGroupId(employee.getId(), group.getId()); + } + + public EmployeeGroupId getId() { + return id; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o == null || getClass() != o.getClass()) + return false; + + EmployeeGroup that = (EmployeeGroup) o; + return Objects.equals(employee, that.employee) && + Objects.equals(group, that.group); + } + + @Override + public int hashCode() { + return Objects.hash(employee, group); + } +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/EmployeeGroupId.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/EmployeeGroupId.java new file mode 100644 index 0000000..d1d2f3f --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/EmployeeGroupId.java @@ -0,0 +1,47 @@ +package com.knits.jpa.orm.d03.many.to.many.demo05.bestPractice; + +import lombok.Data; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import javax.persistence.Entity; +import java.io.Serializable; +import java.util.Objects; + +@Embeddable +@Data +/*You need the @Embeddable type to be Serializable +The @Embeddable type must override the default equals and +hashCode methods based on the two Primary Key identifier values.*/ +public class EmployeeGroupId implements Serializable { + + @Column(name = "employee_id") + private Long employeeId; + + @Column(name = "group_id") + private Long groupId; + + private EmployeeGroupId() {} + + public EmployeeGroupId(Long employeeId, Long groupId) { + this.employeeId = employeeId; + this.groupId = groupId; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o == null || getClass() != o.getClass()) + return false; + + EmployeeGroupId that = (EmployeeGroupId) o; + return Objects.equals(employeeId, that.employeeId) && + Objects.equals(groupId, that.groupId); + } + + @Override + public int hashCode() { + return Objects.hash(employeeId, groupId); + } +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/EmployeeGroupRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/EmployeeGroupRepository.java new file mode 100644 index 0000000..ea265f1 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/EmployeeGroupRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d03.many.to.many.demo05.bestPractice; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface EmployeeGroupRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/EmployeeRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/EmployeeRepository.java new file mode 100644 index 0000000..22567b5 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/EmployeeRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d03.many.to.many.demo05.bestPractice; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface EmployeeRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/Group.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/Group.java new file mode 100644 index 0000000..b0927e3 --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/Group.java @@ -0,0 +1,58 @@ +package com.knits.jpa.orm.d03.many.to.many.demo05.bestPractice; + +import lombok.Data; +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; +import org.hibernate.annotations.NaturalId; +import org.hibernate.annotations.NaturalIdCache; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +@Entity +@Data +@Table(name="\"group\"") //group is a reserved word in sql +@NaturalIdCache +@Cache( + usage = CacheConcurrencyStrategy.READ_WRITE +) +public class Group { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + @NaturalId + //business key, can not update if NaturalId + private String name; + + @OneToMany( + mappedBy = "group", + cascade = CascadeType.ALL, + orphanRemoval = true + ) + private List employees = new ArrayList<>(); + + public Group() { + } + + public Group(String name) { + this.name = name; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Group group = (Group) o; + return Objects.equals(name, group.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/GroupRepository.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/GroupRepository.java new file mode 100644 index 0000000..1445d2b --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/GroupRepository.java @@ -0,0 +1,8 @@ +package com.knits.jpa.orm.d03.many.to.many.demo05.bestPractice; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface GroupRepository extends JpaRepository { +} diff --git a/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/TestJpaManyToManyDemo05.java b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/TestJpaManyToManyDemo05.java new file mode 100644 index 0000000..274cf7a --- /dev/null +++ b/S300-SBoot-JPA-ORM/src/test/java/com/knits/jpa/orm/d03/many/to/many/demo05/bestPractice/TestJpaManyToManyDemo05.java @@ -0,0 +1,219 @@ +package com.knits.jpa.orm.d03.many.to.many.demo05.bestPractice; + +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.TestPropertySource; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +@DataJpaTest +@EntityScan("com.knits.jpa.orm.d03.many.to.many.demo05.*") +@EnableJpaRepositories("com.knits.jpa.orm.d03.many.to.many.demo05.*") +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@TestPropertySource(properties = { + "spring.jpa.hibernate.ddl-auto=create", + "spring.datasource.url=jdbc:postgresql://localhost:5432/JPA-ORM-03-04" +}) +@Slf4j +//help to clean and fill the DB before each test +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +public class TestJpaManyToManyDemo05 { + + @Autowired + private EmployeeRepository employeeRepository; + + @Autowired + private GroupRepository groupRepository; + + @Autowired + private EmployeeGroupRepository employeeGroupRepository; + + @BeforeEach + @Rollback(value = false) + public void initDatabase() { + + Employee employee = new Employee(); + employee.setFirstName("Stefano"); + employee.setLastName("Fiorenza"); + + Employee employee2 = new Employee(); + employee2.setFirstName("Luna"); + employee2.setLastName("Doria"); + + Employee employee3 = new Employee(); + employee3.setFirstName("Maria"); + employee3.setLastName("Bertolucci"); + + Group group = new Group(); + group.setName("A Mock Group Name"); + + Group group2 = new Group(); + group2.setName("Another Mock Group Name"); + + //save two groups + groupRepository.save(group); + groupRepository.save(group2); + + //save employee + employeeRepository.save(employee); + Employee savedEmployee = employeeRepository.save(employee2); + employeeRepository.save(employee3); + + employee.addGroup(group); + employee.addGroup(group2); + employee2.addGroup(group); + employee3.addGroup(group2); + + log.info("Employee: {} ", savedEmployee.getFirstName()); + savedEmployee.getGroups().forEach(reg -> log.info("Registered in group: {} ", reg.getGroup().getName())); + + } + + @Test + @Rollback(value = false) + public void getEmployee() { + + Employee employee = employeeRepository.findById(52L).get(); + + Assertions.assertThat(employee.getId()).isEqualTo(52L); + } + + @Test + @Rollback(value = false) + public void getGroup() { + + Group group = groupRepository.findById(1L).get(); + + Assertions.assertThat(group.getId()).isEqualTo(1L); + } + + @Test + @Rollback(value = false) + public void getEmployeeWithGroup() { + + Employee employee = employeeRepository.findById(52L).get(); + + Assertions.assertThat(employee.getGroups().size()).isGreaterThan(0); + } + + @Test + @Rollback(value = false) + public void getListOfGroups() { + + List groups = groupRepository.findAll(); + + Assertions.assertThat(groups.size()).isGreaterThan(0); + + } + + @Test + @Rollback(value = false) + public void addEmployeeIntoGroup() { + + Employee employee = employeeRepository.findById(53L).get(); + Group group = groupRepository.findById(2L).get(); + employee.addGroup(group); + + Assertions.assertThat(employee.getGroups().get(1).getGroup().getId()).isEqualTo(2L); + + } + + @Test + @Rollback(value = false) + public void updateEmployee() { + + Employee employee = employeeRepository.findById(52L).get(); + + employee.setFirstName("Anton"); + employee.setLastName("Mezhenin"); + + Employee employeeUpdated = employeeRepository.findById(52L).get(); + + Assertions.assertThat(employeeUpdated.getFirstName()).isEqualTo("Anton"); + Assertions.assertThat(employeeUpdated.getLastName()).isEqualTo("Mezhenin"); + + } + + @Test + @Rollback(value = false) + public void removeEmployeeFromGroup() { + + Employee employee = employeeRepository.findById(52L).get(); + + Group group = groupRepository.findById(1L).get(); + Group group1 = groupRepository.findById(2L).get(); + + employee.removeGroup(group); + employee.removeGroup(group1); + + Employee employee1 = employeeRepository.findById(52L).get(); + + Assertions.assertThat(employee.getGroups().size()).isEqualTo(0); + } + + @Test + @Rollback(value = false) + //can delete employee if employee without groups + public void deleteEmployee() { + + Employee employee = employeeRepository.findById(52L).get(); + + Group group = groupRepository.findById(1L).get(); + Group group1 = groupRepository.findById(2L).get(); + + employee.removeGroup(group); + employee.removeGroup(group1); + + employeeRepository.delete(employee); + + Employee employee1 = null; + + Optional optionalEmployee = employeeRepository.findById(52L); + + if (optionalEmployee.isPresent()) { + employee1 = optionalEmployee.get(); + } + + Assertions.assertThat(employee1).isNull(); + } + + @Test + @Rollback(value = false) + //can delete group if it is empty + public void deleteGroup() { + + Group group = groupRepository.findById(1L).get(); + + Employee employee = employeeRepository.findById(53L).get(); + Employee employee2 = employeeRepository.findById(52L).get(); + + employee.removeGroup(group); + employee2.removeGroup(group); + + groupRepository.delete(group); + + Group group1 = null; + + Optional optionalGroup = groupRepository.findById(1L); + + if (optionalGroup.isPresent()) { + group1 = optionalGroup.get(); + } + + Assertions.assertThat(group1).isNull(); + + } + + +}