From fc231c59ffef95267d5ea0a6b3d11f70c52bb533 Mon Sep 17 00:00:00 2001 From: Thibault Faure Date: Sun, 14 Jan 2024 13:46:57 +0100 Subject: [PATCH 001/132] BAEL-7356 Code for the Morse Code Translation in Java article --- .../core-java-string-operations-7/pom.xml | 6 + .../com/baeldung/morse/MorseTranslator.java | 103 ++++++++++++++++++ .../morse/MorseTranslatorUnitTest.java | 55 ++++++++++ 3 files changed, 164 insertions(+) create mode 100644 core-java-modules/core-java-string-operations-7/src/main/java/com/baeldung/morse/MorseTranslator.java create mode 100644 core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/morse/MorseTranslatorUnitTest.java diff --git a/core-java-modules/core-java-string-operations-7/pom.xml b/core-java-modules/core-java-string-operations-7/pom.xml index cea3e32f2f..ebc587715d 100644 --- a/core-java-modules/core-java-string-operations-7/pom.xml +++ b/core-java-modules/core-java-string-operations-7/pom.xml @@ -39,6 +39,11 @@ icu4j ${icu4j.version} + + org.apache.commons + commons-collections4 + ${apache.commons.collection.version} + org.junit.jupiter junit-jupiter @@ -75,6 +80,7 @@ 11 11 3.13.0 + 4.4 2.9.1 1.10.0 74.1 diff --git a/core-java-modules/core-java-string-operations-7/src/main/java/com/baeldung/morse/MorseTranslator.java b/core-java-modules/core-java-string-operations-7/src/main/java/com/baeldung/morse/MorseTranslator.java new file mode 100644 index 0000000000..8d141f66e1 --- /dev/null +++ b/core-java-modules/core-java-string-operations-7/src/main/java/com/baeldung/morse/MorseTranslator.java @@ -0,0 +1,103 @@ +package com.baeldung.morse; + +import org.apache.commons.collections4.BidiMap; +import org.apache.commons.collections4.bidimap.DualHashBidiMap; + +public class MorseTranslator { + + private static final BidiMap morseAlphabet = new DualHashBidiMap<>(); + + static { + morseAlphabet.put("A", ".-"); + morseAlphabet.put("B", "-..."); + morseAlphabet.put("C", "-.-."); + morseAlphabet.put("D", "-.."); + morseAlphabet.put("E", "."); + morseAlphabet.put("F", "..-."); + morseAlphabet.put("G", "--."); + morseAlphabet.put("H", "...."); + morseAlphabet.put("I", ".."); + morseAlphabet.put("J", ".---"); + morseAlphabet.put("K", "-.-"); + morseAlphabet.put("L", ".-.."); + morseAlphabet.put("M", "--"); + morseAlphabet.put("N", "-."); + morseAlphabet.put("O", "---"); + morseAlphabet.put("P", ".--."); + morseAlphabet.put("Q", "--.-"); + morseAlphabet.put("R", ".-."); + morseAlphabet.put("S", "..."); + morseAlphabet.put("T", "-"); + morseAlphabet.put("U", "..-"); + morseAlphabet.put("V", "...-"); + morseAlphabet.put("W", ".--"); + morseAlphabet.put("X", "-..-"); + morseAlphabet.put("Y", "-.--"); + morseAlphabet.put("Z", "--.."); + morseAlphabet.put("0", "-----"); + morseAlphabet.put("1", ".----"); + morseAlphabet.put("2", "..---"); + morseAlphabet.put("3", "...--"); + morseAlphabet.put("4", "....-"); + morseAlphabet.put("5", "....."); + morseAlphabet.put("6", "-...."); + morseAlphabet.put("7", "--..."); + morseAlphabet.put("8", "---.."); + morseAlphabet.put("9", "----."); + morseAlphabet.put(".", ".-.-.-"); + morseAlphabet.put(",", "--..--"); + morseAlphabet.put("?", "..--.."); + morseAlphabet.put("'", ".----."); + morseAlphabet.put("!", "-.-.-----."); + morseAlphabet.put("/", "-..-."); + morseAlphabet.put("(", "-.--."); + morseAlphabet.put(")", "-.--.-"); + morseAlphabet.put("&", ".-..."); + morseAlphabet.put(":", "---..."); + morseAlphabet.put(";", "-.-.-."); + morseAlphabet.put("=", "-...-"); + morseAlphabet.put("+", ".-.-."); + morseAlphabet.put("-", "-....-"); + morseAlphabet.put("_", "..--.-"); + morseAlphabet.put("\"", ".-..-."); + morseAlphabet.put("$", "...-..-"); + morseAlphabet.put("@", ".--.-."); + morseAlphabet.put(" ", "/"); + } + + static String englishToMorse(String english) { + if (english == null) { + return null; + } + String upperCaseEnglish = english.toUpperCase(); + String[] morse = new String[upperCaseEnglish.length()]; + for (int index = 0; index < upperCaseEnglish.length(); index++) { + String morseCharacter = morseAlphabet.get(String.valueOf(upperCaseEnglish.charAt(index))); + if (morseCharacter == null) { + throw new IllegalArgumentException("Character " + upperCaseEnglish.charAt(index) + " can't be translated to morse"); + } + morse[index] = morseCharacter; + } + return String.join(" ", morse); + } + + static String morseToEnglish(String morse) { + if (morse == null) { + return null; + } + if (morse.isEmpty()) { + return ""; + } + String[] morseUnitCharacters = morse.split(" "); + StringBuilder stringBuilder = new StringBuilder(); + for (int index = 0; index < morseUnitCharacters.length; index ++) { + String englishCharacter = morseAlphabet.getKey(morseUnitCharacters[index]); + if (englishCharacter == null) { + throw new IllegalArgumentException("Character " + morseUnitCharacters[index] + " is not a valid morse character"); + } + stringBuilder.append(englishCharacter); + } + return stringBuilder.toString(); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/morse/MorseTranslatorUnitTest.java b/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/morse/MorseTranslatorUnitTest.java new file mode 100644 index 0000000000..f1ab2c961f --- /dev/null +++ b/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/morse/MorseTranslatorUnitTest.java @@ -0,0 +1,55 @@ +package com.baeldung.morse; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +public class MorseTranslatorUnitTest { + + @ParameterizedTest + @ValueSource(strings = {"MORSE CODE!", "morse code!", "mOrSe cOdE!"}) + void givenAValidEnglishWordWhateverTheCapitalization_whenEnglishToMorse_thenTranslatedToMorse(String english) { + assertEquals("-- --- .-. ... . / -.-. --- -.. . -.-.-----.", MorseTranslator.englishToMorse(english)); + } + + @Test + void givenAnEnglishWordWithAnIllegalCharacter_whenEnglishToMorse_thenThrows() { + String english = "~This sentence starts with an illegal character"; + assertThrows(IllegalArgumentException.class, () -> MorseTranslator.englishToMorse(english)); + } + + @Test + void givenNull_whenEnglishToMorse_thenNull() { + assertNull(MorseTranslator.englishToMorse(null)); + } + + @Test + void givenEmptyString_whenEnglishToMorse_thenEmptyArray() { + assertEquals("", MorseTranslator.englishToMorse("")); + } + + @Test + void givenAValidMorseWord_whenMorseToEnglish_thenTranslatedToUpperCaseEnglish() { + assertEquals("MORSE CODE!", MorseTranslator.morseToEnglish("-- --- .-. ... . / -.-. --- -.. . -.-.-----.")); + } + + @Test + void givenAMorseWordWithAnIllegalCharacter_whenMorseToEnglish_thenThrows() { + assertThrows(IllegalArgumentException.class, () -> MorseTranslator.morseToEnglish(".!!!!!!!")); + } + + @Test + void givenNull_whenMorseToEnglish_thenNull() { + assertNull(MorseTranslator.morseToEnglish(null)); + } + + @Test + void givenEmptyArray_whenMorseToEnglish_thenEmptyString() { + assertEquals("", MorseTranslator.morseToEnglish("")); + } + +} \ No newline at end of file From 9231d3611c278dd742a12e8181975d86f8446c6f Mon Sep 17 00:00:00 2001 From: Sam Gardner Date: Mon, 15 Jan 2024 14:35:18 +0000 Subject: [PATCH 002/132] BAEL-7382 Add code for calculating weekdays between two dates --- .../core-java-date-operations-4/README.md | 6 ++ .../core-java-date-operations-4/pom.xml | 45 ++++++++++ .../calculateweekdays/CalculateWeekdays.java | 46 ++++++++++ .../CalculateWeekdaysUnitTest.java | 83 +++++++++++++++++++ 4 files changed, 180 insertions(+) create mode 100644 core-java-modules/core-java-date-operations-4/README.md create mode 100644 core-java-modules/core-java-date-operations-4/pom.xml create mode 100644 core-java-modules/core-java-date-operations-4/src/main/java/com/baeldung/calculateweekdays/CalculateWeekdays.java create mode 100644 core-java-modules/core-java-date-operations-4/src/test/java/com/baeldung/calculateweekdays/CalculateWeekdaysUnitTest.java diff --git a/core-java-modules/core-java-date-operations-4/README.md b/core-java-modules/core-java-date-operations-4/README.md new file mode 100644 index 0000000000..e023a5ca53 --- /dev/null +++ b/core-java-modules/core-java-date-operations-4/README.md @@ -0,0 +1,6 @@ +## Core Date Operations (Part 4) +This module contains articles about date operations in Java. + +### Relevant Articles: + + diff --git a/core-java-modules/core-java-date-operations-4/pom.xml b/core-java-modules/core-java-date-operations-4/pom.xml new file mode 100644 index 0000000000..5153b4b354 --- /dev/null +++ b/core-java-modules/core-java-date-operations-4/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + core-java-date-operations-4 + core-java-date-operations-4 + + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + + + + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + + joda-time + joda-time + ${joda-time.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + + 2.12.5 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-date-operations-4/src/main/java/com/baeldung/calculateweekdays/CalculateWeekdays.java b/core-java-modules/core-java-date-operations-4/src/main/java/com/baeldung/calculateweekdays/CalculateWeekdays.java new file mode 100644 index 0000000000..ded8f9bc13 --- /dev/null +++ b/core-java-modules/core-java-date-operations-4/src/main/java/com/baeldung/calculateweekdays/CalculateWeekdays.java @@ -0,0 +1,46 @@ +package com.baeldung.calculateweekdays; + +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.temporal.ChronoUnit; +import java.time.temporal.TemporalAdjusters; +import java.util.Arrays; + +public class CalculateWeekdays { + + public long getWorkingDaysWithStream(LocalDate start, LocalDate end){ + return start.datesUntil(end) + .map(LocalDate::getDayOfWeek) + .filter(day -> !Arrays.asList(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY).contains(day)) + .count(); + } + + public long getWorkingDaysWithoutStream(LocalDate start, LocalDate end) { + boolean startOnWeekend = false; + + // If starting at the weekend, move to following Monday + if(start.getDayOfWeek().getValue() > 5){ + start = start.with(TemporalAdjusters.next(DayOfWeek.MONDAY)); + startOnWeekend = true; + } + boolean endOnWeekend = false; + // If ending at the weekend, move to previous Friday + if(end.getDayOfWeek().getValue() > 5){ + end = end.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY)); + endOnWeekend = true; + } + // Cover case where starting on Saturday and ending following Sunday + if(start.isAfter(end)){ + return 0; + } + // Get total weeks + long weeks = ChronoUnit.WEEKS.between(start, end); + + long addValue = startOnWeekend || endOnWeekend ? 1 : 0; + + // Add on days that did not make up a full week + return ( weeks * 5 ) + ( end.getDayOfWeek().getValue() - start.getDayOfWeek().getValue() ) + addValue; + } + + +} diff --git a/core-java-modules/core-java-date-operations-4/src/test/java/com/baeldung/calculateweekdays/CalculateWeekdaysUnitTest.java b/core-java-modules/core-java-date-operations-4/src/test/java/com/baeldung/calculateweekdays/CalculateWeekdaysUnitTest.java new file mode 100644 index 0000000000..4a14b6bb99 --- /dev/null +++ b/core-java-modules/core-java-date-operations-4/src/test/java/com/baeldung/calculateweekdays/CalculateWeekdaysUnitTest.java @@ -0,0 +1,83 @@ +package com.baeldung.calculateweekdays; + +import static junit.framework.TestCase.assertEquals; + +import java.time.LocalDate; + +import org.junit.Test; + +public class CalculateWeekdaysUnitTest { + + // Start Saturday end following Sunday (answer is 0) + LocalDate startTomorrow = LocalDate.of(2023, 12, 2); + LocalDate endTomorrow = LocalDate.of(2023, 12, 3); + + // Three week gap with midweek start and finish (answer is 17) + LocalDate startThreeWeeks = LocalDate.of(2023, 11, 28); + LocalDate endThreeWeeks = LocalDate.of(2023, 12, 21); + + // Three week gap with midweek start and weekend finish (answer is 17) + LocalDate startThreeWeeks2 = LocalDate.of(2023, 11, 6); + LocalDate endThreeWeeks2 = LocalDate.of(2023, 12, 30); + + // Week gap start and end on weekend (answer is 40) + LocalDate startThreeWeeksWeekend = LocalDate.of(2023, 12, 2); + LocalDate endThreeWeeksWeekend = LocalDate.of(2023, 12, 9); + + @Test + public void givenTwoDaysOnSameWeekend_whenUsingStreams_calculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithStream(startTomorrow, endTomorrow); + assertEquals(0, result); + } + + @Test + public void givenTwoDaysOnSameWeekend_whenUsingMaths_calculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithoutStream(startTomorrow, endTomorrow); + assertEquals(0, result); + } + + @Test + public void givenAThreeWeekGapMidweekDates_whenUsingStreams_calculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithStream(startThreeWeeks, endThreeWeeks); + assertEquals(17, result); + } + + @Test + public void givenAThreeWeekGapMidweekDates_whenUsingMaths_calculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithoutStream(startThreeWeeks, endThreeWeeks); + assertEquals(17, result); + } + + @Test + public void givenThreeWeekGapMidweekAndWeekendDates_whenUsingStreams_calculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithStream(startThreeWeeksWeekend, endThreeWeeksWeekend); + assertEquals(5, result); + } + + @Test + public void givenThreeWeekGapMidweekAndWeekendDates_whenUsingMaths_calculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithoutStream(startThreeWeeksWeekend, endThreeWeeksWeekend); + assertEquals(5, result); + } + + @Test + public void givenThreeWeekGapWeekendDates_whenUsingStreams_calculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithStream(startThreeWeeks2, endThreeWeeks2); + assertEquals(40, result); + } + + @Test + public void givenThreeWeekGapWeekendDates_whenUsingMaths_calculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithoutStream(startThreeWeeks2, endThreeWeeks2); + assertEquals(40, result); + } + +} From 84530dd8bbf6a2eb0cb9ebc3d61f13665b716221 Mon Sep 17 00:00:00 2001 From: anujgaud <146576725+anujgaud@users.noreply.github.com> Date: Mon, 15 Jan 2024 22:31:09 +0530 Subject: [PATCH 003/132] Add byte to int conversion code --- .../bytetoint/ByteToIntConversion.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 core-java-modules/core-java-numbers-conversions/src/main/java/com/baeldung/bytetoint/ByteToIntConversion.java diff --git a/core-java-modules/core-java-numbers-conversions/src/main/java/com/baeldung/bytetoint/ByteToIntConversion.java b/core-java-modules/core-java-numbers-conversions/src/main/java/com/baeldung/bytetoint/ByteToIntConversion.java new file mode 100644 index 0000000000..59d350cba4 --- /dev/null +++ b/core-java-modules/core-java-numbers-conversions/src/main/java/com/baeldung/bytetoint/ByteToIntConversion.java @@ -0,0 +1,25 @@ +package com.baeldung.bytetoint; + +public class ByteToIntConversion { + static int usingTypeCasting(byte b){ + int i = b; + return i; + } + + static int usingIntegerValueOf(byte b){ + return Integer.valueOf(b); + } + + static int usingByteIntValue(byte b){ + Byte byteObj = new Byte(b); + return byteObj.intValue(); + } + + static int usingMathToIntExact(byte b){ + return Math.toIntExact(b); + } + + static int usingByteUnsignedInt(byte b){ + return Byte.toUnsignedInt(b); + } +} From 444d747468b80ec2e136cfdedd52dd6baf55155a Mon Sep 17 00:00:00 2001 From: anujgaud <146576725+anujgaud@users.noreply.github.com> Date: Mon, 15 Jan 2024 22:32:26 +0530 Subject: [PATCH 004/132] Add tests for byte to int conversion --- .../ByteToIntConversionUnitTest.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/bytetoint/ByteToIntConversionUnitTest.java diff --git a/core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/bytetoint/ByteToIntConversionUnitTest.java b/core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/bytetoint/ByteToIntConversionUnitTest.java new file mode 100644 index 0000000000..61217aad6d --- /dev/null +++ b/core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/bytetoint/ByteToIntConversionUnitTest.java @@ -0,0 +1,45 @@ +package com.baeldung.bytetoint; + +import org.junit.Test; +import static org.junit.Assert.assertEquals; + +public class ByteToIntConversionUnitTest { + @Test + public void givenByte_whenUsingTypeCasting_thenConvertToInt() { + byte b = -51; + int result = ByteToIntConversion.usingTypeCasting(b); + assertEquals(-51, result); + } + + @Test + void givenByte_whenUsingIntegerValueOf_thenConvertToInt() { + byte b = -51; + int result = ByteToIntConversion.usingIntegerValueOf(b); + + assertEquals(-51, result); + } + + @Test + void givenByte_whenUsingByteIntValue_thenConvertToInt() { + byte b = -51; + int result = ByteToIntConversion.usingByteIntValue(b); + + assertEquals(-51, result); + } + + @Test + void givenByte_whenUsingMathToIntExact_thenConvertToInt() { + byte b = -51; + int result = ByteToIntConversion.usingMathToIntExact(b); + + assertEquals(-51, result); + } + + @Test + void givenByte_whenUsingByteUnsignedInt_thenConvertToInt() { + byte b = -51; + int result = ByteToIntConversion.usingByteUnsignedInt(b); + + assertEquals(205, result); + } +} From 7a1158484ababf5be936e4619902b8fccfe76fad Mon Sep 17 00:00:00 2001 From: michaelin007 Date: Mon, 15 Jan 2024 18:57:48 +0000 Subject: [PATCH 005/132] https://jira.baeldung.com/browse/BAEL-3205 --- gradle-modules/gradle-5/cmd-line-args/build.gradle | 2 ++ gradle-modules/gradle-5/gradle-lint-intro/build.gradle | 3 +++ gradle-modules/gradle-5/java-exec/build.gradle | 2 ++ gradle-modules/gradle-5/source-sets/build.gradle | 3 +++ gradle-modules/gradle-5/unused-dependencies/build.gradle | 3 +++ .../gradle-6/dependency-constraints/build.gradle.kts | 2 ++ gradle-modules/gradle-6/fibonacci-recursive/build.gradle.kts | 3 +++ gradle-modules/gradle-6/fibonacci-spi/build.gradle.kts | 3 +++ gradle-modules/gradle-6/httpclient-platform/build.gradle.kts | 3 +++ .../gradle-6/module-metadata-publishing/build.gradle.kts | 3 +++ gradle-modules/gradle-6/person-rest-client/build.gradle.kts | 3 +++ gradle-modules/gradle-6/widget-rest-client/build.gradle.kts | 3 +++ .../gradle-7/conditional-dependency-demo/build.gradle.kts | 2 ++ .../conditional-dependency-demo/consumer1/build.gradle.kts | 2 ++ .../conditional-dependency-demo/consumer2/build.gradle.kts | 2 ++ .../conditional-dependency-demo/provider1/build.gradle.kts | 2 ++ .../conditional-dependency-demo/provider2/build.gradle.kts | 2 ++ gradle-modules/gradle-7/gradle-javadoc/build.gradle | 2 ++ .../gradle-7/gradle-proxy-configuration/build.gradle | 2 ++ gradle-modules/gradle-7/gradle-wsdl-stubs/build.gradle | 3 +++ .../multiple-repositories-demo/publish-package/build.gradle | 2 ++ gradle-modules/gradle/build.gradle | 2 ++ gradle-modules/gradle/gradle-fat-jar/build.gradle | 3 +++ gradle-modules/gradle/gradle-to-maven/build.gradle | 2 ++ gradle-modules/gradle/gradletaskdemo/build.gradle | 3 +++ gradle-modules/gradle/greeter/build.gradle | 3 +++ gradle-modules/gradle/greeting-library-java/build.gradle | 3 +++ gradle-modules/gradle/junit5/build.gradle | 3 +++ 28 files changed, 71 insertions(+) diff --git a/gradle-modules/gradle-5/cmd-line-args/build.gradle b/gradle-modules/gradle-5/cmd-line-args/build.gradle index 15c9288024..a40b04a7a1 100644 --- a/gradle-modules/gradle-5/cmd-line-args/build.gradle +++ b/gradle-modules/gradle-5/cmd-line-args/build.gradle @@ -7,6 +7,8 @@ ext.javaMainClass = "com.baeldung.cmd.MainClass" application { mainClassName = javaMainClass } +sourceCompatibility = "1.8" +targetCompatibility = "1.8" task propertyTypes(){ doLast{ diff --git a/gradle-modules/gradle-5/gradle-lint-intro/build.gradle b/gradle-modules/gradle-5/gradle-lint-intro/build.gradle index fab83bfeec..ba32d53605 100644 --- a/gradle-modules/gradle-5/gradle-lint-intro/build.gradle +++ b/gradle-modules/gradle-5/gradle-lint-intro/build.gradle @@ -5,6 +5,9 @@ ext { awsVersion = '2.20.83' } +sourceCompatibility = "1.8" +targetCompatibility = "1.8" + dependencies { implementation platform("software.amazon.awssdk:bom:$awsVersion") diff --git a/gradle-modules/gradle-5/java-exec/build.gradle b/gradle-modules/gradle-5/java-exec/build.gradle index 08aa738902..67ea3e3d39 100644 --- a/gradle-modules/gradle-5/java-exec/build.gradle +++ b/gradle-modules/gradle-5/java-exec/build.gradle @@ -13,6 +13,8 @@ jar { ) } } +sourceCompatibility = "1.8" +targetCompatibility = "1.8" application { mainClassName = javaMainClass diff --git a/gradle-modules/gradle-5/source-sets/build.gradle b/gradle-modules/gradle-5/source-sets/build.gradle index 8325450cfd..8a65e5a845 100644 --- a/gradle-modules/gradle-5/source-sets/build.gradle +++ b/gradle-modules/gradle-5/source-sets/build.gradle @@ -3,6 +3,9 @@ apply plugin: "eclipse" apply plugin: "java" description = "Source Sets example" +sourceCompatibility = "1.8" +targetCompatibility = "1.8" + task printSourceSetInformation(){ description = "Print source set information" diff --git a/gradle-modules/gradle-5/unused-dependencies/build.gradle b/gradle-modules/gradle-5/unused-dependencies/build.gradle index d848cd0e0d..028224519c 100644 --- a/gradle-modules/gradle-5/unused-dependencies/build.gradle +++ b/gradle-modules/gradle-5/unused-dependencies/build.gradle @@ -1,6 +1,9 @@ description = "Gradle Unused Dependencies example" +sourceCompatibility = "1.8" +targetCompatibility = "1.8" + dependencies { implementation('com.google.guava:guava:29.0-jre') implementation('org.apache.httpcomponents:httpclient:4.5.12') diff --git a/gradle-modules/gradle-6/dependency-constraints/build.gradle.kts b/gradle-modules/gradle-6/dependency-constraints/build.gradle.kts index 41336d3c91..138dbcc595 100644 --- a/gradle-modules/gradle-6/dependency-constraints/build.gradle.kts +++ b/gradle-modules/gradle-6/dependency-constraints/build.gradle.kts @@ -4,6 +4,8 @@ plugins { group = "com.baeldung" version = "1.0.0" +sourceCompatibility = "1.8" +targetCompatibility = "1.8" dependencies { api("io.reactivex.rxjava2:rxjava:2.2.16") diff --git a/gradle-modules/gradle-6/fibonacci-recursive/build.gradle.kts b/gradle-modules/gradle-6/fibonacci-recursive/build.gradle.kts index 0872a52472..884175577f 100644 --- a/gradle-modules/gradle-6/fibonacci-recursive/build.gradle.kts +++ b/gradle-modules/gradle-6/fibonacci-recursive/build.gradle.kts @@ -2,6 +2,9 @@ plugins { `java-library` } +sourceCompatibility = "1.8" +targetCompatibility = "1.8" + dependencies { api(project(":fibonacci-spi")) compileOnly("com.google.auto.service:auto-service-annotations:1.0-rc6") diff --git a/gradle-modules/gradle-6/fibonacci-spi/build.gradle.kts b/gradle-modules/gradle-6/fibonacci-spi/build.gradle.kts index e571f329a9..b468793a3f 100644 --- a/gradle-modules/gradle-6/fibonacci-spi/build.gradle.kts +++ b/gradle-modules/gradle-6/fibonacci-spi/build.gradle.kts @@ -3,6 +3,9 @@ plugins { `java-test-fixtures` } +sourceCompatibility = "1.8" +targetCompatibility = "1.8" + dependencies { testFixturesApi("org.junit.jupiter:junit-jupiter-api:5.5.2") testFixturesImplementation("org.junit.jupiter:junit-jupiter-engine:5.5.2") diff --git a/gradle-modules/gradle-6/httpclient-platform/build.gradle.kts b/gradle-modules/gradle-6/httpclient-platform/build.gradle.kts index a021bff013..693f4e5452 100644 --- a/gradle-modules/gradle-6/httpclient-platform/build.gradle.kts +++ b/gradle-modules/gradle-6/httpclient-platform/build.gradle.kts @@ -2,6 +2,9 @@ plugins { `java-platform` } +sourceCompatibility = "1.8" +targetCompatibility = "1.8" + dependencies { constraints { api("org.apache.httpcomponents:fluent-hc:4.5.10") diff --git a/gradle-modules/gradle-6/module-metadata-publishing/build.gradle.kts b/gradle-modules/gradle-6/module-metadata-publishing/build.gradle.kts index 9812c72f6f..382f989e7c 100644 --- a/gradle-modules/gradle-6/module-metadata-publishing/build.gradle.kts +++ b/gradle-modules/gradle-6/module-metadata-publishing/build.gradle.kts @@ -3,6 +3,9 @@ plugins { `maven-publish` } +sourceCompatibility = "1.8" +targetCompatibility = "1.8" + publishing { publications { register("mavenJava") { diff --git a/gradle-modules/gradle-6/person-rest-client/build.gradle.kts b/gradle-modules/gradle-6/person-rest-client/build.gradle.kts index c562b3e164..3ca9d21adc 100644 --- a/gradle-modules/gradle-6/person-rest-client/build.gradle.kts +++ b/gradle-modules/gradle-6/person-rest-client/build.gradle.kts @@ -2,6 +2,9 @@ plugins { `java-library` } +sourceCompatibility = "1.8" +targetCompatibility = "1.8" + dependencies { api(platform(project(":httpclient-platform"))) implementation("org.apache.httpcomponents:fluent-hc") diff --git a/gradle-modules/gradle-6/widget-rest-client/build.gradle.kts b/gradle-modules/gradle-6/widget-rest-client/build.gradle.kts index e1af4b7f71..2f5842b8dc 100644 --- a/gradle-modules/gradle-6/widget-rest-client/build.gradle.kts +++ b/gradle-modules/gradle-6/widget-rest-client/build.gradle.kts @@ -2,6 +2,9 @@ plugins { `java-library` } +sourceCompatibility = "1.8" +targetCompatibility = "1.8" + dependencies { api(platform(project(":httpclient-platform"))) implementation("org.apache.httpcomponents:httpclient") diff --git a/gradle-modules/gradle-7/conditional-dependency-demo/build.gradle.kts b/gradle-modules/gradle-7/conditional-dependency-demo/build.gradle.kts index 95601a160d..935a23d56f 100644 --- a/gradle-modules/gradle-7/conditional-dependency-demo/build.gradle.kts +++ b/gradle-modules/gradle-7/conditional-dependency-demo/build.gradle.kts @@ -6,6 +6,8 @@ plugins { group = "com.baeldung.gradle" version = "0.0.1-SNAPSHOT" +sourceCompatibility = "1.8" +targetCompatibility = "1.8" repositories { mavenCentral() diff --git a/gradle-modules/gradle-7/conditional-dependency-demo/consumer1/build.gradle.kts b/gradle-modules/gradle-7/conditional-dependency-demo/consumer1/build.gradle.kts index 9858c5b139..5f266cae7a 100644 --- a/gradle-modules/gradle-7/conditional-dependency-demo/consumer1/build.gradle.kts +++ b/gradle-modules/gradle-7/conditional-dependency-demo/consumer1/build.gradle.kts @@ -4,6 +4,8 @@ plugins { group = "com.baeldung.gradle" version = "0.0.1-SNAPSHOT" +sourceCompatibility = "1.8" +targetCompatibility = "1.8" repositories { mavenCentral() diff --git a/gradle-modules/gradle-7/conditional-dependency-demo/consumer2/build.gradle.kts b/gradle-modules/gradle-7/conditional-dependency-demo/consumer2/build.gradle.kts index 2031aea59c..70a16e2971 100644 --- a/gradle-modules/gradle-7/conditional-dependency-demo/consumer2/build.gradle.kts +++ b/gradle-modules/gradle-7/conditional-dependency-demo/consumer2/build.gradle.kts @@ -4,6 +4,8 @@ plugins { group = "com.baeldung.gradle" version = "0.0.1-SNAPSHOT" +sourceCompatibility = "1.8" +targetCompatibility = "1.8" repositories { mavenCentral() diff --git a/gradle-modules/gradle-7/conditional-dependency-demo/provider1/build.gradle.kts b/gradle-modules/gradle-7/conditional-dependency-demo/provider1/build.gradle.kts index d3dcd96b08..8601796ac4 100644 --- a/gradle-modules/gradle-7/conditional-dependency-demo/provider1/build.gradle.kts +++ b/gradle-modules/gradle-7/conditional-dependency-demo/provider1/build.gradle.kts @@ -4,6 +4,8 @@ plugins { group = "com.baeldung.gradle" version = "0.0.1-SNAPSHOT" +sourceCompatibility = "1.8" +targetCompatibility = "1.8" repositories { mavenCentral() diff --git a/gradle-modules/gradle-7/conditional-dependency-demo/provider2/build.gradle.kts b/gradle-modules/gradle-7/conditional-dependency-demo/provider2/build.gradle.kts index d3dcd96b08..8601796ac4 100644 --- a/gradle-modules/gradle-7/conditional-dependency-demo/provider2/build.gradle.kts +++ b/gradle-modules/gradle-7/conditional-dependency-demo/provider2/build.gradle.kts @@ -4,6 +4,8 @@ plugins { group = "com.baeldung.gradle" version = "0.0.1-SNAPSHOT" +sourceCompatibility = "1.8" +targetCompatibility = "1.8" repositories { mavenCentral() diff --git a/gradle-modules/gradle-7/gradle-javadoc/build.gradle b/gradle-modules/gradle-7/gradle-javadoc/build.gradle index 5d8303d64c..761d911ad8 100644 --- a/gradle-modules/gradle-7/gradle-javadoc/build.gradle +++ b/gradle-modules/gradle-7/gradle-javadoc/build.gradle @@ -4,6 +4,8 @@ plugins { group 'org.example' version '1.0-SNAPSHOT' +sourceCompatibility = "1.8" +targetCompatibility = "1.8" javadoc { destinationDir = file("${buildDir}/docs/javadoc") diff --git a/gradle-modules/gradle-7/gradle-proxy-configuration/build.gradle b/gradle-modules/gradle-7/gradle-proxy-configuration/build.gradle index 7463486961..c6e10b053e 100644 --- a/gradle-modules/gradle-7/gradle-proxy-configuration/build.gradle +++ b/gradle-modules/gradle-7/gradle-proxy-configuration/build.gradle @@ -4,6 +4,8 @@ plugins { group = 'org.baeldung' version = '1.0-SNAPSHOT' +sourceCompatibility = "1.8" +targetCompatibility = "1.8" repositories { mavenCentral() diff --git a/gradle-modules/gradle-7/gradle-wsdl-stubs/build.gradle b/gradle-modules/gradle-7/gradle-wsdl-stubs/build.gradle index 6d0cfc1972..3917c2f401 100644 --- a/gradle-modules/gradle-7/gradle-wsdl-stubs/build.gradle +++ b/gradle-modules/gradle-7/gradle-wsdl-stubs/build.gradle @@ -3,6 +3,9 @@ plugins { id 'com.github.bjornvester.wsdl2java' version '2.0.2' } +sourceCompatibility = "1.8" +targetCompatibility = "1.8" + repositories { mavenCentral() } diff --git a/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/build.gradle b/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/build.gradle index bd97650e9c..89d77ddcae 100644 --- a/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/build.gradle +++ b/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/build.gradle @@ -5,6 +5,8 @@ plugins { group = "com.baeldung.gradle" version = "1.0.0-SNAPSHOT" +sourceCompatibility = "1.8" +targetCompatibility = "1.8" repositories { mavenLocal() diff --git a/gradle-modules/gradle/build.gradle b/gradle-modules/gradle/build.gradle index d808f4a3cc..d69a3384a8 100644 --- a/gradle-modules/gradle/build.gradle +++ b/gradle-modules/gradle/build.gradle @@ -10,6 +10,8 @@ allprojects { subprojects { version = '1.0' + sourceCompatibility = "1.8" + targetCompatibility = "1.8" } apply plugin: 'eclipse' diff --git a/gradle-modules/gradle/gradle-fat-jar/build.gradle b/gradle-modules/gradle/gradle-fat-jar/build.gradle index 4c3d86d757..55fbf2d748 100644 --- a/gradle-modules/gradle/gradle-fat-jar/build.gradle +++ b/gradle-modules/gradle/gradle-fat-jar/build.gradle @@ -13,6 +13,9 @@ plugins { id 'java' } +sourceCompatibility = JavaVersion.VERSION_1_8 +targetCompatibility = JavaVersion.VERSION_1_8 + repositories { mavenCentral() } diff --git a/gradle-modules/gradle/gradle-to-maven/build.gradle b/gradle-modules/gradle/gradle-to-maven/build.gradle index 7cd2617ef4..87f4272c13 100644 --- a/gradle-modules/gradle/gradle-to-maven/build.gradle +++ b/gradle-modules/gradle/gradle-to-maven/build.gradle @@ -10,6 +10,8 @@ group = 'com.baeldung' // by default, pom's artifactId is taken from the directory name version = '0.0.1' +sourceCompatibility = JavaVersion.VERSION_1_8 +targetCompatibility = JavaVersion.VERSION_1_8 dependencies { implementation 'org.slf4j:slf4j-api:1.7.25' diff --git a/gradle-modules/gradle/gradletaskdemo/build.gradle b/gradle-modules/gradle/gradletaskdemo/build.gradle index 5f07573365..cb8f285fa0 100644 --- a/gradle-modules/gradle/gradletaskdemo/build.gradle +++ b/gradle-modules/gradle/gradletaskdemo/build.gradle @@ -13,6 +13,9 @@ plugins { id 'java' } +sourceCompatibility = JavaVersion.VERSION_1_8 +targetCompatibility = JavaVersion.VERSION_1_8 + apply from: 'aplugin.gradle' apply plugin: 'org.shipkit.bintray-release' diff --git a/gradle-modules/gradle/greeter/build.gradle b/gradle-modules/gradle/greeter/build.gradle index 0aab8c2313..bc6f800ea0 100644 --- a/gradle-modules/gradle/greeter/build.gradle +++ b/gradle-modules/gradle/greeter/build.gradle @@ -1,6 +1,9 @@ apply plugin : 'java' apply plugin : 'application' +sourceCompatibility = JavaVersion.VERSION_1_8 +targetCompatibility = JavaVersion.VERSION_1_8 + dependencies { implementation project(':greeting-library') implementation project(':greeting-library-java') diff --git a/gradle-modules/gradle/greeting-library-java/build.gradle b/gradle-modules/gradle/greeting-library-java/build.gradle index 916a9a435e..778536ba49 100644 --- a/gradle-modules/gradle/greeting-library-java/build.gradle +++ b/gradle-modules/gradle/greeting-library-java/build.gradle @@ -1,6 +1,9 @@ apply plugin :'java' //apply plugin : 'application' +sourceCompatibility = JavaVersion.VERSION_1_8 +targetCompatibility = JavaVersion.VERSION_1_8 + dependencies{ implementation group: 'joda-time', name: 'joda-time', version: '2.9.9' testImplementation group: 'junit', name: 'junit', version: '4.12' diff --git a/gradle-modules/gradle/junit5/build.gradle b/gradle-modules/gradle/junit5/build.gradle index e589541e08..41c870e6f6 100644 --- a/gradle-modules/gradle/junit5/build.gradle +++ b/gradle-modules/gradle/junit5/build.gradle @@ -3,6 +3,9 @@ plugins { id 'java-library' } +sourceCompatibility = JavaVersion.VERSION_1_8 +targetCompatibility = JavaVersion.VERSION_1_8 + dependencies { testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1' From 8e3857655ddfe0ac57adbc75a38060ec17593e3e Mon Sep 17 00:00:00 2001 From: luca Date: Tue, 16 Jan 2024 10:46:10 +0100 Subject: [PATCH 006/132] gradle setup --- .../spring-boot-testing-spock/.gitattributes | 9 + .../spring-boot-testing-spock/.gitignore | 5 + .../spring-boot-testing-spock/build.gradle | 39 +++ .../gradle/libs.versions.toml | 2 + .../gradle/wrapper/gradle-wrapper.properties | 7 + .../spring-boot-testing-spock/gradlew | 249 ++++++++++++++++++ .../spring-boot-testing-spock/gradlew.bat | 92 +++++++ .../spring-boot-testing-spock/settings.gradle | 1 + 8 files changed, 404 insertions(+) create mode 100644 spring-boot-modules/spring-boot-testing-spock/.gitattributes create mode 100644 spring-boot-modules/spring-boot-testing-spock/.gitignore create mode 100644 spring-boot-modules/spring-boot-testing-spock/build.gradle create mode 100644 spring-boot-modules/spring-boot-testing-spock/gradle/libs.versions.toml create mode 100644 spring-boot-modules/spring-boot-testing-spock/gradle/wrapper/gradle-wrapper.properties create mode 100755 spring-boot-modules/spring-boot-testing-spock/gradlew create mode 100644 spring-boot-modules/spring-boot-testing-spock/gradlew.bat create mode 100644 spring-boot-modules/spring-boot-testing-spock/settings.gradle diff --git a/spring-boot-modules/spring-boot-testing-spock/.gitattributes b/spring-boot-modules/spring-boot-testing-spock/.gitattributes new file mode 100644 index 0000000000..097f9f98d9 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-spock/.gitattributes @@ -0,0 +1,9 @@ +# +# https://help.github.com/articles/dealing-with-line-endings/ +# +# Linux start script should use lf +/gradlew text eol=lf + +# These are Windows script files and should use crlf +*.bat text eol=crlf + diff --git a/spring-boot-modules/spring-boot-testing-spock/.gitignore b/spring-boot-modules/spring-boot-testing-spock/.gitignore new file mode 100644 index 0000000000..1b6985c009 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-spock/.gitignore @@ -0,0 +1,5 @@ +# Ignore Gradle project-specific cache directory +.gradle + +# Ignore Gradle build output directory +build diff --git a/spring-boot-modules/spring-boot-testing-spock/build.gradle b/spring-boot-modules/spring-boot-testing-spock/build.gradle new file mode 100644 index 0000000000..6505c6bc9d --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-spock/build.gradle @@ -0,0 +1,39 @@ +plugins { + id 'java' + id 'groovy' + id 'io.spring.dependency-management' version '1.1.4' +} + +repositories { + mavenCentral() +} + +dependencyManagement { + imports { + mavenBom 'org.springframework.boot:spring-boot-dependencies:3.0.0' + } +} + +dependencies { + + // Spring implementation dependencies + implementation 'org.springframework.boot:spring-boot-starter-web' + + // Test implementation + testImplementation( + 'junit:junit', + 'org.spockframework:spock-core:2.4-M1-groovy-4.0', + 'org.spockframework:spock-spring:2.4-M1-groovy-4.0', + 'org.springframework.boot:spring-boot-starter-test', + ) +} + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(17) + } +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-testing-spock/gradle/libs.versions.toml b/spring-boot-modules/spring-boot-testing-spock/gradle/libs.versions.toml new file mode 100644 index 0000000000..4ac3234a6a --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-spock/gradle/libs.versions.toml @@ -0,0 +1,2 @@ +# This file was generated by the Gradle 'init' task. +# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format diff --git a/spring-boot-modules/spring-boot-testing-spock/gradle/wrapper/gradle-wrapper.properties b/spring-boot-modules/spring-boot-testing-spock/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..1af9e0930b --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-spock/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/spring-boot-modules/spring-boot-testing-spock/gradlew b/spring-boot-modules/spring-boot-testing-spock/gradlew new file mode 100755 index 0000000000..1aa94a4269 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-spock/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/spring-boot-modules/spring-boot-testing-spock/gradlew.bat b/spring-boot-modules/spring-boot-testing-spock/gradlew.bat new file mode 100644 index 0000000000..93e3f59f13 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-spock/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/spring-boot-modules/spring-boot-testing-spock/settings.gradle b/spring-boot-modules/spring-boot-testing-spock/settings.gradle new file mode 100644 index 0000000000..66a6367abb --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-spock/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'spring-boot-testing-spock' From 83d4c400f103fd1fc204aa4999134e437a77befa Mon Sep 17 00:00:00 2001 From: luca Date: Tue, 16 Jan 2024 11:14:42 +0100 Subject: [PATCH 007/132] fix: warning --- spring-boot-modules/spring-boot-testing-spock/build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spring-boot-modules/spring-boot-testing-spock/build.gradle b/spring-boot-modules/spring-boot-testing-spock/build.gradle index 6505c6bc9d..7f447b8370 100644 --- a/spring-boot-modules/spring-boot-testing-spock/build.gradle +++ b/spring-boot-modules/spring-boot-testing-spock/build.gradle @@ -26,6 +26,8 @@ dependencies { 'org.spockframework:spock-spring:2.4-M1-groovy-4.0', 'org.springframework.boot:spring-boot-starter-test', ) + // Test run time only + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } java { From 0b55315e8e530c7ad73d6773598ab98976f37189 Mon Sep 17 00:00:00 2001 From: michaelin007 Date: Tue, 16 Jan 2024 10:59:00 +0000 Subject: [PATCH 008/132] https://jira.baeldung.com/browse/BAEL-3205 --- gradle-modules/gradle/build.gradle | 2 -- gradle-modules/gradle/greeting-library/build.gradle | 5 +++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/gradle-modules/gradle/build.gradle b/gradle-modules/gradle/build.gradle index d69a3384a8..d808f4a3cc 100644 --- a/gradle-modules/gradle/build.gradle +++ b/gradle-modules/gradle/build.gradle @@ -10,8 +10,6 @@ allprojects { subprojects { version = '1.0' - sourceCompatibility = "1.8" - targetCompatibility = "1.8" } apply plugin: 'eclipse' diff --git a/gradle-modules/gradle/greeting-library/build.gradle b/gradle-modules/gradle/greeting-library/build.gradle index a8fa91963c..16304cd5ed 100644 --- a/gradle-modules/gradle/greeting-library/build.gradle +++ b/gradle-modules/gradle/greeting-library/build.gradle @@ -7,3 +7,8 @@ dependencies { exclude module : 'groovy-all' } } + +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} From b07acc0151ed6261d98585e1a21c01c074825570 Mon Sep 17 00:00:00 2001 From: luca Date: Tue, 16 Jan 2024 15:35:40 +0100 Subject: [PATCH 009/132] add test logging --- spring-boot-modules/spring-boot-testing-spock/build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spring-boot-modules/spring-boot-testing-spock/build.gradle b/spring-boot-modules/spring-boot-testing-spock/build.gradle index 7f447b8370..974cdd6b74 100644 --- a/spring-boot-modules/spring-boot-testing-spock/build.gradle +++ b/spring-boot-modules/spring-boot-testing-spock/build.gradle @@ -38,4 +38,8 @@ java { test { useJUnitPlatform() + + testLogging { + events "started", "passed", "skipped", "failed" + } } \ No newline at end of file From cd654c9e20b3e5390910290f144d5c0bb634f0f9 Mon Sep 17 00:00:00 2001 From: Forb Yuan Date: Tue, 26 Dec 2023 12:03:02 +0800 Subject: [PATCH 010/132] BAEL-6080: Getting Query String Parameters from HttpServletRequest --- .../requestparam/QueryStringController.java | 64 +++++++++++++++++++ .../com/baeldung/requestparam/UserDTO.java | 24 +++++++ .../QueryStringControllerIntegrationTest.java | 64 +++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestparam/QueryStringController.java create mode 100644 spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestparam/UserDTO.java create mode 100644 spring-web-modules/spring-mvc-basics-5/src/test/java/com/baeldung/requestparam/QueryStringControllerIntegrationTest.java diff --git a/spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestparam/QueryStringController.java b/spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestparam/QueryStringController.java new file mode 100644 index 0000000000..6c7c5aad43 --- /dev/null +++ b/spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestparam/QueryStringController.java @@ -0,0 +1,64 @@ +package com.baeldung.requestparam; + +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +@RestController +public class QueryStringController { + + @GetMapping("/api/user0") + public String byGetQueryString(HttpServletRequest request) { + return request.getQueryString(); + } + + @GetMapping("/api/user1") + public String byGetParameter(HttpServletRequest request) { + String username = request.getParameter("username"); + return "username:" + username; + } + + @GetMapping("/api/user2") + public String byGetParameterValues(HttpServletRequest request) { + String[] roles = request.getParameterValues("roles"); + return "roles:" + Arrays.toString(roles); + } + + @GetMapping("/api/user3") + public UserDTO byGetParameterMap(HttpServletRequest request) { + Map parameterMap = request.getParameterMap(); + String[] usernames = parameterMap.get("username"); + String[] roles = parameterMap.get("roles"); + UserDTO userDTO = new UserDTO(); + userDTO.setUsername(usernames[0]); + userDTO.setRoles(Arrays.asList(roles)); + return userDTO; + } + + @GetMapping("/api/user4") + public UserDTO byParameterName(String username, String[] roles) { + UserDTO userDTO = new UserDTO(); + userDTO.setUsername(username); + userDTO.setRoles(Arrays.asList(roles)); + return userDTO; + } + + @GetMapping("/api/user5") + public UserDTO byRequestParamAnnotation(@RequestParam("username") String var1, @RequestParam("roles") List var2) { + UserDTO userDTO = new UserDTO(); + userDTO.setUsername(var1); + userDTO.setRoles(var2); + return userDTO; + } + + @GetMapping("/api/user6") + public UserDTO byPojo(UserDTO userDTO) { + return userDTO; + } + +} diff --git a/spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestparam/UserDTO.java b/spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestparam/UserDTO.java new file mode 100644 index 0000000000..847411936a --- /dev/null +++ b/spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestparam/UserDTO.java @@ -0,0 +1,24 @@ +package com.baeldung.requestparam; + +import java.util.List; + +public class UserDTO { + private String username; + private List roles; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public List getRoles() { + return roles; + } + + public void setRoles(List roles) { + this.roles = roles; + } +} diff --git a/spring-web-modules/spring-mvc-basics-5/src/test/java/com/baeldung/requestparam/QueryStringControllerIntegrationTest.java b/spring-web-modules/spring-mvc-basics-5/src/test/java/com/baeldung/requestparam/QueryStringControllerIntegrationTest.java new file mode 100644 index 0000000000..95ca3599df --- /dev/null +++ b/spring-web-modules/spring-mvc-basics-5/src/test/java/com/baeldung/requestparam/QueryStringControllerIntegrationTest.java @@ -0,0 +1,64 @@ +package com.baeldung.requestparam; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.servlet.MockMvc; + +import static org.hamcrest.Matchers.containsInRelativeOrder; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup; + + +@SpringBootTest +@AutoConfigureMockMvc +class QueryStringControllerIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @BeforeEach + public void setup() { + this.mockMvc = standaloneSetup(new QueryStringController()).build(); + } + + @Test + public void whenInvokeGetQueryString_thenReturnTheOriginQueryString() throws Exception { + this.mockMvc.perform(get("/api/user0?username=bob&roles=admin&roles=stuff")) + .andExpect(status().isOk()) + .andExpect(content().string("username=bob&roles=admin&roles=stuff")); + } + + @Test + public void whenInvokeGetQueryParameter_thenReturnOneParameterValue() throws Exception { + this.mockMvc.perform(get("/api/user1?username=bob")) + .andExpect(status().isOk()) + .andExpect(content().string("username:bob")); + } + + @Test + public void whenInvokeGetParameterValues_thenReturnParameterAsArray() throws Exception { + this.mockMvc.perform(get("/api/user2?roles=admin&roles=stuff")) + .andExpect(status().isOk()) + .andExpect(content().string("roles:[admin, stuff]")); + } + + @ParameterizedTest + @CsvSource(textBlock = """ + /api/user3 + /api/user4 + /api/user5 + /api/user6 + """) + public void whenPassParameters_thenReturnResolvedModel(String path) throws Exception { + this.mockMvc.perform(get(path + "?username=bob&roles=admin&roles=stuff")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.username").value("bob")) + .andExpect(jsonPath("$.roles").value(containsInRelativeOrder("admin", "stuff"))); + } +} \ No newline at end of file From 69eddf18d3afb9d53d122dfb96670d1dad99be78 Mon Sep 17 00:00:00 2001 From: Forb Yuan Date: Wed, 27 Dec 2023 10:11:41 +0800 Subject: [PATCH 011/132] BAEL-6080: Getting Query String Parameters from HttpServletRequest --- .../requestparam/QueryStringController.java | 59 ++++++++++--------- .../{UserDTO.java => UserDto.java} | 2 +- .../QueryStringControllerIntegrationTest.java | 47 +++++++-------- 3 files changed, 55 insertions(+), 53 deletions(-) rename spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestparam/{UserDTO.java => UserDto.java} (94%) diff --git a/spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestparam/QueryStringController.java b/spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestparam/QueryStringController.java index 6c7c5aad43..8d34ecd802 100644 --- a/spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestparam/QueryStringController.java +++ b/spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestparam/QueryStringController.java @@ -1,64 +1,65 @@ package com.baeldung.requestparam; -import jakarta.servlet.http.HttpServletRequest; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - import java.util.Arrays; import java.util.List; import java.util.Map; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import jakarta.servlet.http.HttpServletRequest; + @RestController public class QueryStringController { - @GetMapping("/api/user0") + @GetMapping("/api/byGetQueryString") public String byGetQueryString(HttpServletRequest request) { return request.getQueryString(); } - @GetMapping("/api/user1") + @GetMapping("/api/byGetParameter") public String byGetParameter(HttpServletRequest request) { String username = request.getParameter("username"); return "username:" + username; } - @GetMapping("/api/user2") + @GetMapping("/api/byGetParameterValues") public String byGetParameterValues(HttpServletRequest request) { String[] roles = request.getParameterValues("roles"); return "roles:" + Arrays.toString(roles); } - @GetMapping("/api/user3") - public UserDTO byGetParameterMap(HttpServletRequest request) { + @GetMapping("/api/byGetParameterMap") + public UserDto byGetParameterMap(HttpServletRequest request) { Map parameterMap = request.getParameterMap(); String[] usernames = parameterMap.get("username"); String[] roles = parameterMap.get("roles"); - UserDTO userDTO = new UserDTO(); - userDTO.setUsername(usernames[0]); - userDTO.setRoles(Arrays.asList(roles)); - return userDTO; + UserDto userDto = new UserDto(); + userDto.setUsername(usernames[0]); + userDto.setRoles(Arrays.asList(roles)); + return userDto; } - @GetMapping("/api/user4") - public UserDTO byParameterName(String username, String[] roles) { - UserDTO userDTO = new UserDTO(); - userDTO.setUsername(username); - userDTO.setRoles(Arrays.asList(roles)); - return userDTO; + @GetMapping("/api/byParameterName") + public UserDto byParameterName(String username, String[] roles) { + UserDto userDto = new UserDto(); + userDto.setUsername(username); + userDto.setRoles(Arrays.asList(roles)); + return userDto; } - @GetMapping("/api/user5") - public UserDTO byRequestParamAnnotation(@RequestParam("username") String var1, @RequestParam("roles") List var2) { - UserDTO userDTO = new UserDTO(); - userDTO.setUsername(var1); - userDTO.setRoles(var2); - return userDTO; + @GetMapping("/api/byAnnoRequestParam") + public UserDto byAnnoRequestParam(@RequestParam("username") String var1, @RequestParam("roles") List var2) { + UserDto userDto = new UserDto(); + userDto.setUsername(var1); + userDto.setRoles(var2); + return userDto; } - @GetMapping("/api/user6") - public UserDTO byPojo(UserDTO userDTO) { - return userDTO; + @GetMapping("/api/byPojo") + public UserDto byPojo(UserDto userDto) { + return userDto; } } diff --git a/spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestparam/UserDTO.java b/spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestparam/UserDto.java similarity index 94% rename from spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestparam/UserDTO.java rename to spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestparam/UserDto.java index 847411936a..5e7327c6d3 100644 --- a/spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestparam/UserDTO.java +++ b/spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestparam/UserDto.java @@ -2,7 +2,7 @@ package com.baeldung.requestparam; import java.util.List; -public class UserDTO { +public class UserDto { private String username; private List roles; diff --git a/spring-web-modules/spring-mvc-basics-5/src/test/java/com/baeldung/requestparam/QueryStringControllerIntegrationTest.java b/spring-web-modules/spring-mvc-basics-5/src/test/java/com/baeldung/requestparam/QueryStringControllerIntegrationTest.java index 95ca3599df..4aeaa60156 100644 --- a/spring-web-modules/spring-mvc-basics-5/src/test/java/com/baeldung/requestparam/QueryStringControllerIntegrationTest.java +++ b/spring-web-modules/spring-mvc-basics-5/src/test/java/com/baeldung/requestparam/QueryStringControllerIntegrationTest.java @@ -1,5 +1,12 @@ package com.baeldung.requestparam; +import static org.hamcrest.Matchers.containsInRelativeOrder; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -9,12 +16,6 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMock import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; -import static org.hamcrest.Matchers.containsInRelativeOrder; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; -import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup; - - @SpringBootTest @AutoConfigureMockMvc class QueryStringControllerIntegrationTest { @@ -29,36 +30,36 @@ class QueryStringControllerIntegrationTest { @Test public void whenInvokeGetQueryString_thenReturnTheOriginQueryString() throws Exception { - this.mockMvc.perform(get("/api/user0?username=bob&roles=admin&roles=stuff")) - .andExpect(status().isOk()) - .andExpect(content().string("username=bob&roles=admin&roles=stuff")); + this.mockMvc.perform(get("/api/byGetQueryString?username=bob&roles=admin&roles=stuff")) + .andExpect(status().isOk()) + .andExpect(content().string("username=bob&roles=admin&roles=stuff")); } @Test public void whenInvokeGetQueryParameter_thenReturnOneParameterValue() throws Exception { - this.mockMvc.perform(get("/api/user1?username=bob")) - .andExpect(status().isOk()) - .andExpect(content().string("username:bob")); + this.mockMvc.perform(get("/api/byGetParameter?username=bob")) + .andExpect(status().isOk()) + .andExpect(content().string("username:bob")); } @Test public void whenInvokeGetParameterValues_thenReturnParameterAsArray() throws Exception { - this.mockMvc.perform(get("/api/user2?roles=admin&roles=stuff")) - .andExpect(status().isOk()) - .andExpect(content().string("roles:[admin, stuff]")); + this.mockMvc.perform(get("/api/byGetParameterValues?roles=admin&roles=stuff")) + .andExpect(status().isOk()) + .andExpect(content().string("roles:[admin, stuff]")); } @ParameterizedTest @CsvSource(textBlock = """ - /api/user3 - /api/user4 - /api/user5 - /api/user6 - """) + /api/byGetParameterMap + /api/byParameterName + /api/byAnnoRequestParam + /api/byPojo + """) public void whenPassParameters_thenReturnResolvedModel(String path) throws Exception { this.mockMvc.perform(get(path + "?username=bob&roles=admin&roles=stuff")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.username").value("bob")) - .andExpect(jsonPath("$.roles").value(containsInRelativeOrder("admin", "stuff"))); + .andExpect(status().isOk()) + .andExpect(jsonPath("$.username").value("bob")) + .andExpect(jsonPath("$.roles").value(containsInRelativeOrder("admin", "stuff"))); } } \ No newline at end of file From b9c8a43ff024f5cd14c4cb8007fbd05709be1b90 Mon Sep 17 00:00:00 2001 From: michaelin007 Date: Wed, 17 Jan 2024 02:34:51 +0000 Subject: [PATCH 012/132] https://jira.baeldung.com/browse/BAEL-3205 --- gradle-modules/gradle/gradle-employee-app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle-modules/gradle/gradle-employee-app/build.gradle b/gradle-modules/gradle/gradle-employee-app/build.gradle index c7040504f1..03d28f7e20 100644 --- a/gradle-modules/gradle/gradle-employee-app/build.gradle +++ b/gradle-modules/gradle/gradle-employee-app/build.gradle @@ -6,8 +6,8 @@ plugins { apply plugin: 'application' mainClassName = 'employee.EmployeeApp' -sourceCompatibility = JavaVersion.VERSION_1_8 -targetCompatibility = JavaVersion.VERSION_1_8 +sourceCompatibility = "1.8" +targetCompatibility = "1.8" println 'This is executed during configuration phase' From ad9942e8112dea31fe58a478aefda5ad829055ec Mon Sep 17 00:00:00 2001 From: "emanuel.trandafir" Date: Wed, 17 Jan 2024 12:24:03 +0100 Subject: [PATCH 013/132] BAEL-7202: handling kafka deser errors --- spring-kafka-3/pom.xml | 25 +++++ .../exception/Application.java | 13 +++ .../exception/ArticlePublishedEvent.java | 4 + .../exception/ArticlesPublishedListener.java | 22 +++++ .../exception/EmailService.java | 22 +++++ .../exception/KafkaConfig.java | 55 +++++++++++ .../exception/KafkaErrorHandler.java | 34 +++++++ .../kafka/trusted/packages/SomeData.java | 37 +++++++ .../DeserializationExceptionLiveTest.java | 96 +++++++++++++++++++ .../packages/ListenerConfiguration.java | 42 ++++++++ .../packages/ProducerConfiguration.java | 39 ++++++++ .../packages/TrustedPackagesLiveTest.java | 59 ++++++++++++ spring-kafka-3_/README.md | 2 + spring-kafka-3_/pom.xml | 36 +++++++ .../com/baeldung/spring/kafka/SomeData.java | 0 .../spring/kafka/ListenerConfiguration.java | 0 .../spring/kafka/ProducerConfiguration.java | 0 .../spring/kafka/TrustedPackagesLiveTest.java | 0 18 files changed, 486 insertions(+) create mode 100644 spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/Application.java create mode 100644 spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/ArticlePublishedEvent.java create mode 100644 spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/ArticlesPublishedListener.java create mode 100644 spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/EmailService.java create mode 100644 spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/KafkaConfig.java create mode 100644 spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/KafkaErrorHandler.java create mode 100644 spring-kafka-3/src/main/java/com/baeldung/spring/kafka/trusted/packages/SomeData.java create mode 100644 spring-kafka-3/src/test/java/com/baeldung/spring/kafka/deserialization/exception/DeserializationExceptionLiveTest.java create mode 100644 spring-kafka-3/src/test/java/com/baeldung/spring/kafka/trusted/packages/ListenerConfiguration.java create mode 100644 spring-kafka-3/src/test/java/com/baeldung/spring/kafka/trusted/packages/ProducerConfiguration.java create mode 100644 spring-kafka-3/src/test/java/com/baeldung/spring/kafka/trusted/packages/TrustedPackagesLiveTest.java create mode 100644 spring-kafka-3_/README.md create mode 100644 spring-kafka-3_/pom.xml rename {spring-kafka-3 => spring-kafka-3_}/src/main/java/com/baeldung/spring/kafka/SomeData.java (100%) rename {spring-kafka-3 => spring-kafka-3_}/src/test/java/com/baeldung/spring/kafka/ListenerConfiguration.java (100%) rename {spring-kafka-3 => spring-kafka-3_}/src/test/java/com/baeldung/spring/kafka/ProducerConfiguration.java (100%) rename {spring-kafka-3 => spring-kafka-3_}/src/test/java/com/baeldung/spring/kafka/TrustedPackagesLiveTest.java (100%) diff --git a/spring-kafka-3/pom.xml b/spring-kafka-3/pom.xml index 972412d18e..894eab2576 100644 --- a/spring-kafka-3/pom.xml +++ b/spring-kafka-3/pom.xml @@ -15,6 +15,10 @@ spring-kafka-3 + + org.springframework.boot + spring-boot-starter + org.springframework.kafka spring-kafka @@ -28,9 +32,30 @@ spring-kafka-test test + + org.testcontainers + junit-jupiter + ${testcontainers.version} + test + + + org.testcontainers + kafka + ${testcontainers.version} + test + + + org.awaitility + awaitility + ${awaitility.version} + test + + 17 3.0.12 + 1.19.3 + 4.2.0 diff --git a/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/Application.java b/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/Application.java new file mode 100644 index 0000000000..d3857a0ca0 --- /dev/null +++ b/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/Application.java @@ -0,0 +1,13 @@ +package com.baeldung.spring.kafka.deserialization.exception; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/ArticlePublishedEvent.java b/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/ArticlePublishedEvent.java new file mode 100644 index 0000000000..d43f6a6692 --- /dev/null +++ b/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/ArticlePublishedEvent.java @@ -0,0 +1,4 @@ +package com.baeldung.spring.kafka.deserialization.exception; + +public record ArticlePublishedEvent(String article) { +} \ No newline at end of file diff --git a/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/ArticlesPublishedListener.java b/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/ArticlesPublishedListener.java new file mode 100644 index 0000000000..c5d977aa8e --- /dev/null +++ b/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/ArticlesPublishedListener.java @@ -0,0 +1,22 @@ +package com.baeldung.spring.kafka.deserialization.exception; + +import java.util.logging.Logger; + +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.stereotype.Component; + +@Component +public class ArticlesPublishedListener { + private static final Logger log = Logger.getLogger(ArticlesPublishedListener.class.getName()); + private final EmailService emailService; + + public ArticlesPublishedListener(EmailService emailService) { + this.emailService = emailService; + } + + @KafkaListener(topics = "baeldung.articles.published") + public void onArticlePublished(ArticlePublishedEvent event) { + log.info("Received event published event: " + event); + emailService.sendNewsletter(event.article()); + } +} diff --git a/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/EmailService.java b/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/EmailService.java new file mode 100644 index 0000000000..1e48bd87b3 --- /dev/null +++ b/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/EmailService.java @@ -0,0 +1,22 @@ +package com.baeldung.spring.kafka.deserialization.exception; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +import org.springframework.stereotype.Service; + +@Service +public class EmailService { + private final static Logger log = Logger.getLogger(EmailService.class.getName()); + private final List articles = new ArrayList<>(); + + public void sendNewsletter(String article) { + log.info("Sending newsletter for article: " + article); + articles.add(article); + } + + public List getArticles() { + return articles; + } +} diff --git a/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/KafkaConfig.java b/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/KafkaConfig.java new file mode 100644 index 0000000000..5151e98b87 --- /dev/null +++ b/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/KafkaConfig.java @@ -0,0 +1,55 @@ +package com.baeldung.spring.kafka.deserialization.exception; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.annotation.EnableKafka; +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; +import org.springframework.kafka.core.ConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.listener.CommonErrorHandler; +import org.springframework.kafka.support.serializer.JsonDeserializer; + +@EnableKafka +@Configuration +class KafkaConfig { + + @Bean + ConsumerFactory consumerFactory( + @Value("${spring.kafka.bootstrap-servers}") String bootstrapServers + ) { + Map props = new HashMap<>(); + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); + props.put(ConsumerConfig.GROUP_ID_CONFIG, "baeldung-app-1"); + props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class); + return new DefaultKafkaConsumerFactory<>( + props, + new StringDeserializer(), + new JsonDeserializer<>(ArticlePublishedEvent.class) + ); + } + + @Bean + ConcurrentKafkaListenerContainerFactory kafkaListenerContainerFactory( + ConsumerFactory consumerFactory, + CommonErrorHandler commonErrorHandler + ) { + var factory = new ConcurrentKafkaListenerContainerFactory(); + factory.setConsumerFactory(consumerFactory); + factory.setCommonErrorHandler(commonErrorHandler); + return factory; + } + + @Bean + CommonErrorHandler kafkaErrorHandler() { + return new KafkaErrorHandler(); + } + +} \ No newline at end of file diff --git a/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/KafkaErrorHandler.java b/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/KafkaErrorHandler.java new file mode 100644 index 0000000000..ea4211ab53 --- /dev/null +++ b/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/deserialization/exception/KafkaErrorHandler.java @@ -0,0 +1,34 @@ +package com.baeldung.spring.kafka.deserialization.exception; + + +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.common.errors.RecordDeserializationException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.kafka.listener.CommonErrorHandler; +import org.springframework.kafka.listener.MessageListenerContainer; + +class KafkaErrorHandler implements CommonErrorHandler { + private static final Logger log = LoggerFactory.getLogger(KafkaErrorHandler.class); + + @Override + public void handleRecord(Exception exception, ConsumerRecord record, Consumer consumer, MessageListenerContainer container) { + handle(exception, consumer); + } + + @Override + public void handleOtherException(Exception exception, Consumer consumer, MessageListenerContainer container, boolean batchListener) { + handle(exception, consumer); + } + + private void handle(Exception exception, Consumer consumer) { + log.error("Exception thrown", exception); + if (exception instanceof RecordDeserializationException ex) { + consumer.seek(ex.topicPartition(), ex.offset() + 1L); + consumer.commitSync(); + } else { + log.error("Exception not handled", exception); + } + } +} \ No newline at end of file diff --git a/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/trusted/packages/SomeData.java b/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/trusted/packages/SomeData.java new file mode 100644 index 0000000000..1da3ad8635 --- /dev/null +++ b/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/trusted/packages/SomeData.java @@ -0,0 +1,37 @@ +package com.baeldung.spring.kafka.trusted.packages; + +import java.time.Instant; + +public class SomeData { + + private String id; + private String type; + private String status; + private Instant timestamp; + + public SomeData() { + } + + public SomeData(String id, String type, String status, Instant timestamp) { + this.id = id; + this.type = type; + this.status = status; + this.timestamp = timestamp; + } + + public String getId() { + return id; + } + + public String getType() { + return type; + } + + public String getStatus() { + return status; + } + + public Instant getTimestamp() { + return timestamp; + } +} diff --git a/spring-kafka-3/src/test/java/com/baeldung/spring/kafka/deserialization/exception/DeserializationExceptionLiveTest.java b/spring-kafka-3/src/test/java/com/baeldung/spring/kafka/deserialization/exception/DeserializationExceptionLiveTest.java new file mode 100644 index 0000000000..19950ad54b --- /dev/null +++ b/spring-kafka-3/src/test/java/com/baeldung/spring/kafka/deserialization/exception/DeserializationExceptionLiveTest.java @@ -0,0 +1,96 @@ +package com.baeldung.spring.kafka.deserialization.exception; + +import static java.time.Duration.ofMillis; +import static java.time.Duration.ofSeconds; +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; + +import java.util.Properties; +import java.util.concurrent.ExecutionException; + +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.common.serialization.StringSerializer; +import org.awaitility.Awaitility; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.testcontainers.containers.KafkaContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +@Testcontainers +@SpringBootTest(classes = Application.class) +class DeserializationExceptionLiveTest { + + @Container + private static KafkaContainer KAFKA = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); + + private static KafkaProducer testKafkaProducer; + + @Autowired + private EmailService emailService; + + @DynamicPropertySource + static void setProps(DynamicPropertyRegistry registry) { + registry.add("spring.kafka.bootstrap-servers", KAFKA::getBootstrapServers); + } + + @BeforeAll + static void beforeAll() { + Properties props = new Properties(); + props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA.getBootstrapServers()); + props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + testKafkaProducer = new KafkaProducer<>(props); + + Awaitility.setDefaultTimeout(ofSeconds(5)); + Awaitility.setDefaultPollInterval(ofMillis(50)); + } + + @BeforeEach + void beforeEach() { + emailService.getArticles().clear(); + } + + @Test + void whenPublishingInvalidArticleEvent_thenHandleExceptionAndContinueProcessing() { + publishArticle("{ \"article\": \"Introduction to Kafka\" }"); + publishArticle(" !! Invalid JSON !! "); + publishArticle("{ \"article\": \"Kafka Streams Tutorial\" }"); + + await().untilAsserted(() -> assertThat(emailService.getArticles()) + .containsExactlyInAnyOrder( + "Introduction to Kafka", + "Kafka Streams Tutorial" + )); + } + + @Test + void whenPublishingValidArticleEvent_thenProcessWithoutErrors() { + publishArticle("{ \"article\": \"Kotlin for Java Developers\" }"); + publishArticle("{ \"article\": \"The S.O.L.I.D. Principles\" }"); + + await().untilAsserted(() -> assertThat(emailService.getArticles()) + .containsExactlyInAnyOrder( + "Kotlin for Java Developers", + "The S.O.L.I.D. Principles" + )); + } + + + static void publishArticle(String jsonBody) { + ProducerRecord record = new ProducerRecord<>("baeldung.articles.published", jsonBody); + try { + testKafkaProducer.send(record).get(); + } catch (ExecutionException | InterruptedException e) { + throw new RuntimeException(e); + } + } +} diff --git a/spring-kafka-3/src/test/java/com/baeldung/spring/kafka/trusted/packages/ListenerConfiguration.java b/spring-kafka-3/src/test/java/com/baeldung/spring/kafka/trusted/packages/ListenerConfiguration.java new file mode 100644 index 0000000000..6bcb047c19 --- /dev/null +++ b/spring-kafka-3/src/test/java/com/baeldung/spring/kafka/trusted/packages/ListenerConfiguration.java @@ -0,0 +1,42 @@ +package com.baeldung.spring.kafka.trusted.packages; + +import java.util.Map; + +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; +import org.springframework.kafka.core.ConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.support.serializer.JsonDeserializer; + +@Configuration +public class ListenerConfiguration { + + @Bean("messageListenerContainer") + public ConcurrentKafkaListenerContainerFactory messageListenerContainer() { + ConcurrentKafkaListenerContainerFactory container = new ConcurrentKafkaListenerContainerFactory<>(); + container.setConsumerFactory(someDataConsumerFactory()); + return container; + } + + @Bean + public ConsumerFactory someDataConsumerFactory() { + JsonDeserializer payloadJsonDeserializer = new JsonDeserializer<>(); + payloadJsonDeserializer.trustedPackages("com.baeldung.spring.kafka"); + return new DefaultKafkaConsumerFactory<>( + consumerConfigs(), + new StringDeserializer(), + payloadJsonDeserializer + ); + } + + @Bean + public Map consumerConfigs() { + return Map.of( + ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "PLAINTEXT://localhost:9092", + ConsumerConfig.GROUP_ID_CONFIG, "some-group-id" + ); + } +} \ No newline at end of file diff --git a/spring-kafka-3/src/test/java/com/baeldung/spring/kafka/trusted/packages/ProducerConfiguration.java b/spring-kafka-3/src/test/java/com/baeldung/spring/kafka/trusted/packages/ProducerConfiguration.java new file mode 100644 index 0000000000..f7de2f5023 --- /dev/null +++ b/spring-kafka-3/src/test/java/com/baeldung/spring/kafka/trusted/packages/ProducerConfiguration.java @@ -0,0 +1,39 @@ +package com.baeldung.spring.kafka.trusted.packages; + +import org.apache.kafka.clients.producer.ProducerConfig; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.core.ProducerFactory; +import org.springframework.kafka.support.serializer.JsonSerializer; +import org.springframework.kafka.support.serializer.StringOrBytesSerializer; + +import java.util.Map; + +@Configuration +public class ProducerConfiguration { + + @Bean + public KafkaTemplate kafkaTemplate() { + return new KafkaTemplate<>(producerFactory()); + } + + @Bean + public ProducerFactory producerFactory() { + JsonSerializer jsonSerializer = new JsonSerializer<>(); + jsonSerializer.setAddTypeInfo(true); + return new DefaultKafkaProducerFactory<>( + producerFactoryConfig(), + new StringOrBytesSerializer(), + jsonSerializer + ); + } + + @Bean + public Map producerFactoryConfig() { + return Map.of( + ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "PLAINTEXT://localhost:9092" + ); + } +} \ No newline at end of file diff --git a/spring-kafka-3/src/test/java/com/baeldung/spring/kafka/trusted/packages/TrustedPackagesLiveTest.java b/spring-kafka-3/src/test/java/com/baeldung/spring/kafka/trusted/packages/TrustedPackagesLiveTest.java new file mode 100644 index 0000000000..532f862e13 --- /dev/null +++ b/spring-kafka-3/src/test/java/com/baeldung/spring/kafka/trusted/packages/TrustedPackagesLiveTest.java @@ -0,0 +1,59 @@ +package com.baeldung.spring.kafka.trusted.packages; + +import java.time.Instant; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.apache.kafka.clients.producer.ProducerRecord; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.stereotype.Component; + +/** + * This test requires a running instance of kafka to be present + */ +@SpringBootTest +@Disabled("This test requires a running instance of kafka to be present - manually run it") +public class TrustedPackagesLiveTest { + + @Autowired + private KafkaTemplate kafkaTemplate; + + @SpyBean + TestConsumer testConsumer; + + @Test + void givenMessageInTheTopic_whenTypeInfoPackageIsTrusted_thenMessageIsSuccessfullyConsumed() throws InterruptedException { + CountDownLatch latch = new CountDownLatch(1); + + Mockito.doAnswer(invocationOnMock -> { + try { + latch.countDown(); + return invocationOnMock.callRealMethod(); + } catch (Exception e) { + return null; + } + }).when(testConsumer).onMessage(Mockito.any()); + + SomeData someData = new SomeData("1", "active", "sent", Instant.now()); + kafkaTemplate.send(new ProducerRecord<>("sourceTopic", null, someData)); + + Assertions.assertTrue(latch.await(10, TimeUnit.SECONDS)); + } + + @Component + static class TestConsumer { + + @KafkaListener(topics = "sourceTopic", containerFactory = "messageListenerContainer") + public void onMessage(SomeData someData) { + + } + } +} diff --git a/spring-kafka-3_/README.md b/spring-kafka-3_/README.md new file mode 100644 index 0000000000..f9c0036ce3 --- /dev/null +++ b/spring-kafka-3_/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Spring Kafka Trusted Packages Feature](https://www.baeldung.com/spring-kafka-trusted-packages-feature) diff --git a/spring-kafka-3_/pom.xml b/spring-kafka-3_/pom.xml new file mode 100644 index 0000000000..972412d18e --- /dev/null +++ b/spring-kafka-3_/pom.xml @@ -0,0 +1,36 @@ + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + 4.0.0 + + spring-kafka-3 + jar + + spring-kafka-3 + + + + org.springframework.kafka + spring-kafka + + + com.fasterxml.jackson.core + jackson-databind + + + org.springframework.kafka + spring-kafka-test + test + + + + + 3.0.12 + + diff --git a/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/SomeData.java b/spring-kafka-3_/src/main/java/com/baeldung/spring/kafka/SomeData.java similarity index 100% rename from spring-kafka-3/src/main/java/com/baeldung/spring/kafka/SomeData.java rename to spring-kafka-3_/src/main/java/com/baeldung/spring/kafka/SomeData.java diff --git a/spring-kafka-3/src/test/java/com/baeldung/spring/kafka/ListenerConfiguration.java b/spring-kafka-3_/src/test/java/com/baeldung/spring/kafka/ListenerConfiguration.java similarity index 100% rename from spring-kafka-3/src/test/java/com/baeldung/spring/kafka/ListenerConfiguration.java rename to spring-kafka-3_/src/test/java/com/baeldung/spring/kafka/ListenerConfiguration.java diff --git a/spring-kafka-3/src/test/java/com/baeldung/spring/kafka/ProducerConfiguration.java b/spring-kafka-3_/src/test/java/com/baeldung/spring/kafka/ProducerConfiguration.java similarity index 100% rename from spring-kafka-3/src/test/java/com/baeldung/spring/kafka/ProducerConfiguration.java rename to spring-kafka-3_/src/test/java/com/baeldung/spring/kafka/ProducerConfiguration.java diff --git a/spring-kafka-3/src/test/java/com/baeldung/spring/kafka/TrustedPackagesLiveTest.java b/spring-kafka-3_/src/test/java/com/baeldung/spring/kafka/TrustedPackagesLiveTest.java similarity index 100% rename from spring-kafka-3/src/test/java/com/baeldung/spring/kafka/TrustedPackagesLiveTest.java rename to spring-kafka-3_/src/test/java/com/baeldung/spring/kafka/TrustedPackagesLiveTest.java From ed18f58d12dae4b2d5330a017568496d5afd0cd8 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Thu, 18 Jan 2024 10:30:54 +0800 Subject: [PATCH 014/132] Update README.md --- kubernetes-modules/k8s-operator/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kubernetes-modules/k8s-operator/README.md b/kubernetes-modules/k8s-operator/README.md index 215c7d8e18..40d6efd2c1 100644 --- a/kubernetes-modules/k8s-operator/README.md +++ b/kubernetes-modules/k8s-operator/README.md @@ -2,3 +2,6 @@ This sample demonstrates how to create a simple operator using the Java Operator Framework. In our case, the operator will facilitate the deployment of a Dependency-Track instance on a cluster. + +### Relevant Articles: +- [Create Kubernetes Operators with the Java Operator SDK](https://www.baeldung.com/java-kubernetes-operator-sdk) From aee45fb1494830f019b885755fc2fc71745bfc89 Mon Sep 17 00:00:00 2001 From: Niket Agrawal Date: Thu, 18 Jan 2024 10:53:08 +0530 Subject: [PATCH 015/132] NEW PR --- .../core-java-datetime-string-2/pom.xml | 12 ++ .../CurrentTimeAsFileNameUnitTest.java | 114 ++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 core-java-modules/core-java-datetime-string-2/src/test/java/com/baeldung/timestamp/CurrentTimeAsFileNameUnitTest.java diff --git a/core-java-modules/core-java-datetime-string-2/pom.xml b/core-java-modules/core-java-datetime-string-2/pom.xml index d619b0af84..d37d4d69a4 100644 --- a/core-java-modules/core-java-datetime-string-2/pom.xml +++ b/core-java-modules/core-java-datetime-string-2/pom.xml @@ -13,6 +13,14 @@ 0.0.1-SNAPSHOT + + + joda-time + joda-time + ${joda-time.version} + + + @@ -22,4 +30,8 @@ + + 2.12.5 + + \ No newline at end of file diff --git a/core-java-modules/core-java-datetime-string-2/src/test/java/com/baeldung/timestamp/CurrentTimeAsFileNameUnitTest.java b/core-java-modules/core-java-datetime-string-2/src/test/java/com/baeldung/timestamp/CurrentTimeAsFileNameUnitTest.java new file mode 100644 index 0000000000..4087df288b --- /dev/null +++ b/core-java-modules/core-java-datetime-string-2/src/test/java/com/baeldung/timestamp/CurrentTimeAsFileNameUnitTest.java @@ -0,0 +1,114 @@ +package com.baeldung.timestamp; + +import static org.junit.Assert.assertTrue; + +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.Calendar; +import java.util.Date; +import java.util.regex.Pattern; + +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; +import org.junit.Test; + +public class CurrentTimeAsFileNameUnitTest { + + static final String TIMESTAMP_FORMAT = "yyyyMMddHHmmss"; + static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern(TIMESTAMP_FORMAT); + static final SimpleDateFormat SIMPLEDATE_FORMAT = new SimpleDateFormat(TIMESTAMP_FORMAT); + + @Test + public void whenUsingCalendar_thenCurrentTimeAsFileName() { + String currentTime = SIMPLEDATE_FORMAT.format(Calendar.getInstance().getTime()); + String fileName = getFileName(currentTime); + + assertTrue(verifyFileName(fileName)); + } + + @Test + public void whenUsingDate_thenCurrentTimeAsFileName() { + String currentTime = SIMPLEDATE_FORMAT.format(new Date()); + String fileName = getFileName(currentTime); + + assertTrue(verifyFileName(fileName)); + } + + @Test + public void whenUsingInstant_thenCurrentTimeAsFileName() { + String currentTime = Instant + .now() + .truncatedTo(ChronoUnit.SECONDS) + .toString() + .replaceAll("[:TZ-]", ""); + String fileName = getFileName(currentTime); + + assertTrue(verifyFileName(fileName)); + } + + @Test + public void whenUsingLocalDateTime_thenCurrentTimeAsFileName() { + String currentTime = LocalDateTime.now().format(DATETIME_FORMATTER); + String fileName = getFileName(currentTime); + + assertTrue(verifyFileName(fileName)); + } + + @Test + public void whenUsingZonedDateTime_thenCurrentTimeAsFileName() { + String currentTime = ZonedDateTime + .now(ZoneId.of("Europe/Paris")) + .format(DATETIME_FORMATTER); + String fileName = getFileName(currentTime); + + assertTrue(verifyFileName(fileName)); + } + + @Test + public void whenUsingOffsetDateTime_thenCurrentTimeAsFileName() { + String currentTime = OffsetDateTime + .of(LocalDateTime.now(), ZoneOffset.of("+01:00")) + .format(DATETIME_FORMATTER); + String fileName = getFileName(currentTime); + + assertTrue(verifyFileName(fileName)); + } + + @Test + public void whenUsingJodaDateTime_thenCurrentTimeAsFileName() { + String currentTime = DateTime.now().toString(TIMESTAMP_FORMAT); + String fileName = getFileName(currentTime); + + assertTrue(verifyFileName(fileName)); + } + + @Test + public void whenUsingJodaInstant_thenCurrentTimeAsFileName() { + String currentTime = DateTimeFormat + .forPattern(TIMESTAMP_FORMAT) + .print(org.joda.time.Instant.now() + .toDateTime()); + String fileName = getFileName(currentTime); + + assertTrue(verifyFileName(fileName)); + } + + String getFileName(String currentTime) { + return MessageFormat.format("{0}.txt", currentTime); + } + + boolean verifyFileName(String fileName) { + return Pattern + .compile("[0-9]{14}+\\.txt", Pattern.CASE_INSENSITIVE) + .matcher(fileName) + .matches(); + } +} From 9801f1eb7dbbcdfc5ce3c6b5d0c3cab4beff3243 Mon Sep 17 00:00:00 2001 From: Amit Pandey Date: Thu, 18 Jan 2024 18:25:38 +0530 Subject: [PATCH 016/132] JAVA-29068 - Fixed Spring Boot Mysql and added it back to module POM (#15670) --- persistence-modules/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index 5ca2ffbf1a..bb7c01984f 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -62,7 +62,7 @@ solr spring-boot-persistence-2 spring-boot-persistence-3 - + spring-boot-mysql spring-boot-persistence spring-boot-persistence-h2 spring-boot-persistence-mongodb From 4b5a9dfbad59d1f9bf0b787ffba0bc83bec80dfd Mon Sep 17 00:00:00 2001 From: anujgaud <146576725+anujgaud@users.noreply.github.com> Date: Thu, 18 Jan 2024 22:13:33 +0530 Subject: [PATCH 017/132] Add code for enabling SSL Debug logs --- .../enablessldebug/SSLDebugLogger.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 core-java-modules/core-java-security-4/src/main/java/com/baeldung/enablessldebug/SSLDebugLogger.java diff --git a/core-java-modules/core-java-security-4/src/main/java/com/baeldung/enablessldebug/SSLDebugLogger.java b/core-java-modules/core-java-security-4/src/main/java/com/baeldung/enablessldebug/SSLDebugLogger.java new file mode 100644 index 0000000000..73fd3b9981 --- /dev/null +++ b/core-java-modules/core-java-security-4/src/main/java/com/baeldung/enablessldebug/SSLDebugLogger.java @@ -0,0 +1,32 @@ +package com.baeldung.enablessldebug; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.URL; + +import javax.net.ssl.HttpsURLConnection; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SSLDebugLogger { + private static final Logger logger = LoggerFactory.getLogger(SSLDebugLogger.class); + + public static void enableSSLDebugUsingSystemProperties() { + System.setProperty("javax.net.debug", "ssl"); + } + + public static void makeHttpsRequest() throws Exception { + String url = "https://github.com/eugenp/tutorials"; + URL httpsUrl = new URL(url); + HttpsURLConnection connection = (HttpsURLConnection) httpsUrl.openConnection(); + + try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { + String line; + logger.info("Response from " + url + ":"); + while ((line = reader.readLine()) != null) { + logger.info(line); + } + } + } +} From 6945c01ec7cd2e63e3e47e5cbdc4d6ff2cfa74d8 Mon Sep 17 00:00:00 2001 From: anujgaud <146576725+anujgaud@users.noreply.github.com> Date: Thu, 18 Jan 2024 22:14:45 +0530 Subject: [PATCH 018/132] Add unit tests for SSLDebugLogger --- .../SSLDebugLoggerUnitTest.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 core-java-modules/core-java-security-4/src/test/java/com/baeldung/enablessldebug/SSLDebugLoggerUnitTest.java diff --git a/core-java-modules/core-java-security-4/src/test/java/com/baeldung/enablessldebug/SSLDebugLoggerUnitTest.java b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/enablessldebug/SSLDebugLoggerUnitTest.java new file mode 100644 index 0000000000..759ebdef95 --- /dev/null +++ b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/enablessldebug/SSLDebugLoggerUnitTest.java @@ -0,0 +1,49 @@ +package com.baeldung.enablessldebug; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.util.logging.ConsoleHandler; +import java.util.logging.Level; +import java.util.logging.LogManager; +import java.util.logging.Logger; + +import org.junit.jupiter.api.Test; + +public class SSLDebugLoggerUnitTest { + @Test + void givenSSLDebuggingEnabled_whenUsingSystemProperties_thenEnableSSLDebugLogging() throws Exception { + ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + System.setErr(new PrintStream(outContent)); + + SSLDebugLogger.enableSSLDebugUsingSystemProperties(); + assertEquals("ssl", System.getProperty("javax.net.debug")); + + SSLDebugLogger.makeHttpsRequest(); + assertTrue(outContent.toString().contains("javax.net.ssl|DEBUG|")); + outContent.reset(); + + System.clearProperty("javax.net.debug"); + assertNull(System.getProperty("javax.net.debug")); + + SSLDebugLogger.makeHttpsRequest(); + assertEquals(outContent.toString(),""); + } + + @Test + void givenSSLDebuggingEnabled_whenUsingConfigurationFile_thenEnableSSLDebugLogging() throws IOException { + InputStream configFile = SSLDebugLoggerUnitTest.class.getClassLoader().getResourceAsStream("logging.properties"); + LogManager.getLogManager().readConfiguration(configFile); + + Logger sslLogger = Logger.getLogger("javax.net.ssl"); + ConsoleHandler consoleHandler = (ConsoleHandler) sslLogger.getHandlers()[0]; + Level consoleHandlerLevel = consoleHandler.getLevel(); + + assertEquals(Level.ALL, consoleHandlerLevel, "SSL ConsoleHandler level should be ALL"); + } +} From 3becb407b8ef0865570b879d23fe4ef3926075c2 Mon Sep 17 00:00:00 2001 From: anujgaud <146576725+anujgaud@users.noreply.github.com> Date: Thu, 18 Jan 2024 22:15:45 +0530 Subject: [PATCH 019/132] Add logging.properties file --- .../core-java-security-4/src/test/resources/logging.properties | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 core-java-modules/core-java-security-4/src/test/resources/logging.properties diff --git a/core-java-modules/core-java-security-4/src/test/resources/logging.properties b/core-java-modules/core-java-security-4/src/test/resources/logging.properties new file mode 100644 index 0000000000..ab5cf9862f --- /dev/null +++ b/core-java-modules/core-java-security-4/src/test/resources/logging.properties @@ -0,0 +1,3 @@ +java.util.logging.ConsoleHandler.level=ALL +javax.net.ssl.handlers=java.util.logging.ConsoleHandler +javax.net.ssl.level=ALL From 0fdf33e5bbf6c5e34d1f223fe8e02c5b83545b14 Mon Sep 17 00:00:00 2001 From: shahulbasha Date: Thu, 18 Jan 2024 11:51:34 -0500 Subject: [PATCH 020/132] BAEL-7206 new fork --- .../maven-build-lifecycle/.gitignore | 38 +++++++++++++ maven-modules/maven-build-lifecycle/pom.xml | 55 +++++++++++++++++++ .../baeldung/mavenlifecycle/CourseApp.java | 7 +++ .../baeldung/mavenlifecycle/CourseAppIT.java | 15 +++++ .../mavenlifecycle/CourseAppUnitTest.java | 16 ++++++ 5 files changed, 131 insertions(+) create mode 100644 maven-modules/maven-build-lifecycle/.gitignore create mode 100644 maven-modules/maven-build-lifecycle/pom.xml create mode 100644 maven-modules/maven-build-lifecycle/src/main/java/com/baeldung/mavenlifecycle/CourseApp.java create mode 100644 maven-modules/maven-build-lifecycle/src/test/java/com/baeldung/mavenlifecycle/CourseAppIT.java create mode 100644 maven-modules/maven-build-lifecycle/src/test/java/com/baeldung/mavenlifecycle/CourseAppUnitTest.java diff --git a/maven-modules/maven-build-lifecycle/.gitignore b/maven-modules/maven-build-lifecycle/.gitignore new file mode 100644 index 0000000000..5ff6309b71 --- /dev/null +++ b/maven-modules/maven-build-lifecycle/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/maven-modules/maven-build-lifecycle/pom.xml b/maven-modules/maven-build-lifecycle/pom.xml new file mode 100644 index 0000000000..5cfb854200 --- /dev/null +++ b/maven-modules/maven-build-lifecycle/pom.xml @@ -0,0 +1,55 @@ + + + 4.0.0 + + com.baeldung + maven-modules + 0.0.1-SNAPSHOT + + + maven-build-lifecycle + + + 11 + 11 + 3.1.2 + 3.1.2 + 5.3.1 + UTF-8 + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven.surefire.version} + + + + **/*Test.java + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + ${maven.failsafe.version} + + + + + integration-test + verify + + + + + + + + \ No newline at end of file diff --git a/maven-modules/maven-build-lifecycle/src/main/java/com/baeldung/mavenlifecycle/CourseApp.java b/maven-modules/maven-build-lifecycle/src/main/java/com/baeldung/mavenlifecycle/CourseApp.java new file mode 100644 index 0000000000..1982c7c422 --- /dev/null +++ b/maven-modules/maven-build-lifecycle/src/main/java/com/baeldung/mavenlifecycle/CourseApp.java @@ -0,0 +1,7 @@ +package com.baeldung.mavenlifecycle; + +public class CourseApp { + public String getCourse() { + return "Baeldung Spring Masterclass"; + } +} diff --git a/maven-modules/maven-build-lifecycle/src/test/java/com/baeldung/mavenlifecycle/CourseAppIT.java b/maven-modules/maven-build-lifecycle/src/test/java/com/baeldung/mavenlifecycle/CourseAppIT.java new file mode 100644 index 0000000000..d89181ab3a --- /dev/null +++ b/maven-modules/maven-build-lifecycle/src/test/java/com/baeldung/mavenlifecycle/CourseAppIT.java @@ -0,0 +1,15 @@ +package com.baeldung.mavenlifecycle; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class CourseAppIT { + + @Test + void givenIntegrationTest_whenGetCourse_ThenCourseShouldBePresent() { + CourseApp courseApp = new CourseApp(); + + assertEquals("Baeldung Spring Masterclass", courseApp.getCourse()); + } +} diff --git a/maven-modules/maven-build-lifecycle/src/test/java/com/baeldung/mavenlifecycle/CourseAppUnitTest.java b/maven-modules/maven-build-lifecycle/src/test/java/com/baeldung/mavenlifecycle/CourseAppUnitTest.java new file mode 100644 index 0000000000..e148075bb7 --- /dev/null +++ b/maven-modules/maven-build-lifecycle/src/test/java/com/baeldung/mavenlifecycle/CourseAppUnitTest.java @@ -0,0 +1,16 @@ +package com.baeldung.mavenlifecycle; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + + +class CourseAppUnitTest { + + @Test + void whenGetCourse_ThenCourseShouldBePresent() { + CourseApp courseApp = new CourseApp(); + + assertEquals("Baeldung Spring Masterclass", courseApp.getCourse()); + } +} From 75521b269b0981224f4bf535b7920aef2b1e2840 Mon Sep 17 00:00:00 2001 From: shahulbasha Date: Thu, 18 Jan 2024 11:56:03 -0500 Subject: [PATCH 021/132] BAEL-7206 new fork remove gitignore --- .../maven-build-lifecycle/.gitignore | 38 ------------------- 1 file changed, 38 deletions(-) delete mode 100644 maven-modules/maven-build-lifecycle/.gitignore diff --git a/maven-modules/maven-build-lifecycle/.gitignore b/maven-modules/maven-build-lifecycle/.gitignore deleted file mode 100644 index 5ff6309b71..0000000000 --- a/maven-modules/maven-build-lifecycle/.gitignore +++ /dev/null @@ -1,38 +0,0 @@ -target/ -!.mvn/wrapper/maven-wrapper.jar -!**/src/main/**/target/ -!**/src/test/**/target/ - -### IntelliJ IDEA ### -.idea/modules.xml -.idea/jarRepositories.xml -.idea/compiler.xml -.idea/libraries/ -*.iws -*.iml -*.ipr - -### Eclipse ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ -build/ -!**/src/main/**/build/ -!**/src/test/**/build/ - -### VS Code ### -.vscode/ - -### Mac OS ### -.DS_Store \ No newline at end of file From 1b75127c657c6b0f5978078165ccbf4b6d09dd6f Mon Sep 17 00:00:00 2001 From: shahulbasha Date: Thu, 18 Jan 2024 12:01:01 -0500 Subject: [PATCH 022/132] BAEL-7206 new module created for maven build lifecycle --- maven-modules/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/maven-modules/pom.xml b/maven-modules/pom.xml index 913421d496..5e293fdb02 100644 --- a/maven-modules/pom.xml +++ b/maven-modules/pom.xml @@ -21,6 +21,7 @@ host-maven-repo-example jacoco-coverage-aggregation maven-archetype + maven-build-lifecycle maven-build-optimization maven-builder-plugin maven-classifier From 9aa37e274616a2d8b533ebbd84d203997c3b417b Mon Sep 17 00:00:00 2001 From: Eugene Kovko <37694937+eukovko@users.noreply.github.com> Date: Thu, 18 Jan 2024 20:43:05 +0100 Subject: [PATCH 023/132] BAEL-6887: List vs Set in @OneToMany JPA (#15677) --- .../spring-boot-persistence-4/pom.xml | 24 + .../listvsset/ParametrizationAware.java | 14 + .../java/com/baeldung/listvsset/Service.java | 63 ++ .../eager/list/fulldomain/Application.java | 8 + .../eager/list/fulldomain/Comment.java | 25 + .../eager/list/fulldomain/Group.java | 23 + .../listvsset/eager/list/fulldomain/Post.java | 32 + .../eager/list/fulldomain/PostRepository.java | 7 + .../eager/list/fulldomain/Profile.java | 28 + .../listvsset/eager/list/fulldomain/User.java | 36 + .../eager/list/fulldomain/UserRepository.java | 7 + .../eager/list/fulldomain/UserService.java | 20 + .../list/moderatedomain/Application.java | 8 + .../eager/list/moderatedomain/Group.java | 23 + .../list/moderatedomain/GroupRepository.java | 7 + .../list/moderatedomain/GroupService.java | 29 + .../eager/list/moderatedomain/Post.java | 23 + .../list/moderatedomain/PostRepository.java | 7 + .../eager/list/moderatedomain/User.java | 46 + .../list/moderatedomain/UserRepository.java | 7 + .../list/moderatedomain/UserService.java | 20 + .../eager/list/simpledomain/Application.java | 8 + .../eager/list/simpledomain/Post.java | 23 + .../list/simpledomain/PostRepository.java | 7 + .../eager/list/simpledomain/User.java | 26 + .../list/simpledomain/UserRepository.java | 9 + .../eager/list/simpledomain/UserService.java | 20 + .../eager/set/fulldomain/Application.java | 8 + .../eager/set/fulldomain/Comment.java | 44 + .../listvsset/eager/set/fulldomain/Group.java | 43 + .../listvsset/eager/set/fulldomain/Post.java | 52 + .../eager/set/fulldomain/PostRepository.java | 7 + .../eager/set/fulldomain/Profile.java | 28 + .../listvsset/eager/set/fulldomain/User.java | 56 ++ .../eager/set/fulldomain/UserRepository.java | 7 + .../eager/set/fulldomain/UserService.java | 20 + .../eager/set/moderatedomain/Application.java | 8 + .../eager/set/moderatedomain/Group.java | 23 + .../set/moderatedomain/GroupRepository.java | 7 + .../set/moderatedomain/GroupService.java | 29 + .../eager/set/moderatedomain/Post.java | 43 + .../set/moderatedomain/PostRepository.java | 7 + .../eager/set/moderatedomain/User.java | 46 + .../set/moderatedomain/UserRepository.java | 7 + .../eager/set/moderatedomain/UserService.java | 20 + .../eager/set/simpledomain/Application.java | 8 + .../eager/set/simpledomain/Post.java | 43 + .../set/simpledomain/PostRepository.java | 7 + .../eager/set/simpledomain/User.java | 27 + .../set/simpledomain/UserRepository.java | 9 + .../eager/set/simpledomain/UserService.java | 20 + .../BaseNPlusOneIntegrationTest.java | 76 ++ .../com/baeldung/listvsset/JsonUtilTest.java | 56 ++ ...PlusOneEagerFullDomainIntegrationTest.java | 129 +++ ...OneEagerModerateDomainIntegrationTest.java | 87 ++ ...usOneEagerSimpleDomainIntegrationTest.java | 67 ++ ...OneEagerFullDomainJoinIntegrationTest.java | 106 +++ ...OneEagerModerateDomainIntegrationTest.java | 83 ++ ...usOneEagerSimpleDomainIntegrationTest.java | 68 ++ .../listvsset/util/DataSourceWrapper.java | 35 + .../baeldung/listvsset/util/DatabaseUtil.java | 47 + .../baeldung/listvsset/util/JsonUtils.java | 51 + .../baeldung/listvsset/util/TestConfig.java | 24 + .../src/test/resources/groups.json | 402 ++++++++ .../test/resources/groups_with_members.json | 183 ++++ .../src/test/resources/users.json | 899 ++++++++++++++++++ 66 files changed, 3432 insertions(+) create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/ParametrizationAware.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/Service.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Application.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Comment.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Group.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Post.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/PostRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Profile.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/User.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/UserRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/UserService.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/Application.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/Group.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/GroupRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/GroupService.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/Post.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/PostRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/User.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/UserRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/UserService.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/Application.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/Post.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/PostRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/User.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/UserRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/UserService.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Application.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Comment.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Group.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Post.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/PostRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Profile.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/User.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/UserRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/UserService.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/Application.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/Group.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/GroupRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/GroupService.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/Post.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/PostRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/User.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/UserRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/UserService.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/Application.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/Post.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/PostRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/User.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/UserRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/UserService.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/BaseNPlusOneIntegrationTest.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/JsonUtilTest.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerFullDomainIntegrationTest.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerModerateDomainIntegrationTest.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerSimpleDomainIntegrationTest.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerFullDomainJoinIntegrationTest.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerModerateDomainIntegrationTest.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerSimpleDomainIntegrationTest.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/util/DataSourceWrapper.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/util/DatabaseUtil.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/util/JsonUtils.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/util/TestConfig.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/test/resources/groups.json create mode 100644 persistence-modules/spring-boot-persistence-4/src/test/resources/groups_with_members.json create mode 100644 persistence-modules/spring-boot-persistence-4/src/test/resources/users.json diff --git a/persistence-modules/spring-boot-persistence-4/pom.xml b/persistence-modules/spring-boot-persistence-4/pom.xml index 7a6c2d2b17..78cd75234a 100644 --- a/persistence-modules/spring-boot-persistence-4/pom.xml +++ b/persistence-modules/spring-boot-persistence-4/pom.xml @@ -42,6 +42,26 @@ spring-boot-starter-test test + + io.hypersistence + hypersistence-utils-hibernate-62 + ${hypersistence-utils.version} + + + com.vladmihalcea + db-util + ${db.util.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + org.projectlombok + lombok + ${lombok.version} + @@ -58,6 +78,10 @@ 5.9.3 17 17 + 1.0.7 + 3.7.0 + 2.16.0 + 1.18.28 \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/ParametrizationAware.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/ParametrizationAware.java new file mode 100644 index 0000000000..08b12f38ab --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/ParametrizationAware.java @@ -0,0 +1,14 @@ +package com.baeldung.listvsset; + +import java.lang.reflect.ParameterizedType; +import java.util.Arrays; +import java.util.List; + +public abstract class ParametrizationAware { + + public List> getParametrizationClass() { + ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass(); + return Arrays.stream(type.getActualTypeArguments()) + .map(s -> ((Class) s)).toList(); + } +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/Service.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/Service.java new file mode 100644 index 0000000000..2a700de09b --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/Service.java @@ -0,0 +1,63 @@ +package com.baeldung.listvsset; + +import java.util.List; +import java.util.Optional; +import java.util.function.Predicate; +import java.util.function.ToIntFunction; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +public class Service extends ParametrizationAware { + + private final JpaRepository repository; + + public Service(JpaRepository repository) { + this.repository = repository; + } + + public JpaRepository getRepository() { + return repository; + } + + public int countNumberOfRequestsWithFunction(ToIntFunction> function) { + return function.applyAsInt(repository.findAll()); + } + + + public Optional getUserById(Long id) { + return repository.findById(id); + } + + public void deleteAll() { + repository.deleteAll(); + } + + public List saveAll(Iterable entities) { + return repository.saveAll(entities); + } + + public List findAll() { + return repository.findAll(); + } + + public Optional getUserByIdWithPredicate(long id, Predicate predicate) { + Optional user = repository.findById(id); + user.ifPresent(predicate::test); + return user; + } + + public int getUserByIdWithFunction(Long id, ToIntFunction function) { + + Optional optionalUser = repository.findById(id); + if(optionalUser.isPresent()) { + return function.applyAsInt(optionalUser.get()); + } else { + return 0; + } + } + + public void save(S entity) { + repository.save(entity); + } +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Application.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Application.java new file mode 100644 index 0000000000..8e48e25d58 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Application.java @@ -0,0 +1,8 @@ +package com.baeldung.listvsset.eager.list.fulldomain; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Comment.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Comment.java new file mode 100644 index 0000000000..482ddc3dc5 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Comment.java @@ -0,0 +1,25 @@ +package com.baeldung.listvsset.eager.list.fulldomain; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; +import lombok.Data; + +@Data +@Entity +public class Comment { + + @Id + private Long id; + + private String text; + + @ManyToOne + private User author; + + @JsonBackReference + @ManyToOne + private Post post; + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Group.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Group.java new file mode 100644 index 0000000000..0f02d3025c --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Group.java @@ -0,0 +1,23 @@ +package com.baeldung.listvsset.eager.list.fulldomain; + +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.Table; +import java.util.List; +import lombok.Data; + +@Data +@Entity(name = "interest_group") +@Table(name = "interest_group") +public class Group { + + @Id + private Long id; + + private String name; + + @ManyToMany(fetch = FetchType.EAGER) + private List members; +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Post.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Post.java new file mode 100644 index 0000000000..301301a1ff --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Post.java @@ -0,0 +1,32 @@ +package com.baeldung.listvsset.eager.list.fulldomain; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonManagedReference; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.Lob; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import java.util.List; +import lombok.Data; + +@Entity +@Data +public class Post { + + @Id + private Long id; + + @Lob + private String content; + + @JsonManagedReference + @OneToMany(cascade = CascadeType.ALL, mappedBy = "post", fetch = FetchType.EAGER) + private List comments; + + @JsonBackReference + @ManyToOne + private User author; +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/PostRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/PostRepository.java new file mode 100644 index 0000000000..ae84e4bc29 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/PostRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.listvsset.eager.list.fulldomain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PostRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Profile.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Profile.java new file mode 100644 index 0000000000..9e29eec2aa --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Profile.java @@ -0,0 +1,28 @@ +package com.baeldung.listvsset.eager.list.fulldomain; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.Lob; +import jakarta.persistence.OneToOne; +import lombok.Data; + +@Entity +@Data +public class Profile { + + @Id + private Long id; + + @Lob + private String biography; + private String website; + private String profilePictureUrl; + + @JsonBackReference + @OneToOne(mappedBy = "profile") + @JoinColumn(unique = true) + private User user; +} + diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/User.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/User.java new file mode 100644 index 0000000000..48f733e27a --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/User.java @@ -0,0 +1,36 @@ +package com.baeldung.listvsset.eager.list.fulldomain; + +import com.fasterxml.jackson.annotation.JsonManagedReference; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.OneToMany; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import java.util.List; +import lombok.Data; + +@Data +@Entity(name = "simple_user") +@Table(name = "simple_user") +public class User { + + @Id + private Long id; + private String username; + private String email; + + @JsonManagedReference + @OneToOne(cascade = CascadeType.ALL) + private Profile profile; + + @JsonManagedReference + @OneToMany(cascade = CascadeType.ALL, mappedBy = "author", fetch = FetchType.EAGER) + protected List posts; + + + @ManyToMany(mappedBy = "members", fetch = FetchType.EAGER) + private List groups; +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/UserRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/UserRepository.java new file mode 100644 index 0000000000..174c495bfe --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/UserRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.listvsset.eager.list.fulldomain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/UserService.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/UserService.java new file mode 100644 index 0000000000..acea27d2fa --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/UserService.java @@ -0,0 +1,20 @@ +package com.baeldung.listvsset.eager.list.fulldomain; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +@Service +public class UserService extends com.baeldung.listvsset.Service { + + public UserService(JpaRepository repository) { + super(repository); + } + + @Override + public UserRepository getRepository() { + return ((UserRepository) super.getRepository()); + } + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/Application.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/Application.java new file mode 100644 index 0000000000..81d82f5d43 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/Application.java @@ -0,0 +1,8 @@ +package com.baeldung.listvsset.eager.list.moderatedomain; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/Group.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/Group.java new file mode 100644 index 0000000000..0460f77a60 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/Group.java @@ -0,0 +1,23 @@ +package com.baeldung.listvsset.eager.list.moderatedomain; + +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.Table; +import java.util.List; +import lombok.Data; + +@Data +@Entity(name = "interest_group") +@Table(name = "interest_group") +public class Group { + + @Id + private Long id; + + private String name; + + @ManyToMany(fetch = FetchType.EAGER) + private List members; +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/GroupRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/GroupRepository.java new file mode 100644 index 0000000000..b14b210fc7 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/GroupRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.listvsset.eager.list.moderatedomain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface GroupRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/GroupService.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/GroupService.java new file mode 100644 index 0000000000..3f84410f94 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/GroupService.java @@ -0,0 +1,29 @@ +package com.baeldung.listvsset.eager.list.moderatedomain; + +import java.util.List; +import java.util.Optional; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class GroupService { + + private final GroupRepository groupRepository; + + @Autowired + public GroupService(GroupRepository groupRepository) { + this.groupRepository = groupRepository; + } + + public Optional findById(Long aLong) { + return groupRepository.findById(aLong); + } + + public List findAll() { + return groupRepository.findAll(); + } + + public S save(S entity) { + return groupRepository.save(entity); + } +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/Post.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/Post.java new file mode 100644 index 0000000000..faef97b212 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/Post.java @@ -0,0 +1,23 @@ +package com.baeldung.listvsset.eager.list.moderatedomain; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Lob; +import jakarta.persistence.ManyToOne; +import lombok.Data; + +@Entity +@Data +public class Post { + + @Id + private Long id; + + @Lob + private String content; + + @JsonBackReference + @ManyToOne + private User author; +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/PostRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/PostRepository.java new file mode 100644 index 0000000000..1c11f13690 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/PostRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.listvsset.eager.list.moderatedomain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PostRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/User.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/User.java new file mode 100644 index 0000000000..a58f6dd9e5 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/User.java @@ -0,0 +1,46 @@ +package com.baeldung.listvsset.eager.list.moderatedomain; + +import com.fasterxml.jackson.annotation.JsonManagedReference; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import java.util.List; +import java.util.Objects; +import lombok.Data; + +@Data +@Entity(name = "simple_user") +@Table(name = "simple_user") +public class User { + + @Id + private Long id; + private String username; + private String email; + + @JsonManagedReference + @OneToMany(cascade = CascadeType.ALL, mappedBy = "author", fetch = FetchType.EAGER) + protected List posts; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + User user = (User) o; + + return Objects.equals(id, user.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/UserRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/UserRepository.java new file mode 100644 index 0000000000..e3c7b471da --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/UserRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.listvsset.eager.list.moderatedomain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/UserService.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/UserService.java new file mode 100644 index 0000000000..439b9b6445 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/UserService.java @@ -0,0 +1,20 @@ +package com.baeldung.listvsset.eager.list.moderatedomain; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +@Service +public class UserService extends com.baeldung.listvsset.Service { + + public UserService(JpaRepository repository) { + super(repository); + } + + @Override + public UserRepository getRepository() { + return ((UserRepository) super.getRepository()); + } + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/Application.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/Application.java new file mode 100644 index 0000000000..dfa61d66b8 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/Application.java @@ -0,0 +1,8 @@ +package com.baeldung.listvsset.eager.list.simpledomain; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/Post.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/Post.java new file mode 100644 index 0000000000..35c436357f --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/Post.java @@ -0,0 +1,23 @@ +package com.baeldung.listvsset.eager.list.simpledomain; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Lob; +import jakarta.persistence.ManyToOne; +import lombok.Data; + +@Entity +@Data +public class Post { + + @Id + private Long id; + + @Lob + private String content; + + @JsonBackReference + @ManyToOne + private User author; +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/PostRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/PostRepository.java new file mode 100644 index 0000000000..95fc9ccf16 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/PostRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.listvsset.eager.list.simpledomain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PostRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/User.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/User.java new file mode 100644 index 0000000000..6495761c18 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/User.java @@ -0,0 +1,26 @@ +package com.baeldung.listvsset.eager.list.simpledomain; + +import com.fasterxml.jackson.annotation.JsonManagedReference; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import java.util.List; +import lombok.Data; + +@Data +@Entity(name = "simple_user") +@Table(name = "simple_user") +public class User { + + @Id + private Long id; + private String username; + private String email; + + @JsonManagedReference + @OneToMany(cascade = CascadeType.ALL, mappedBy = "author", fetch = FetchType.EAGER) + protected List posts; +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/UserRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/UserRepository.java new file mode 100644 index 0000000000..bba1de8723 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/UserRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.listvsset.eager.list.simpledomain; + +import org.springframework.context.annotation.Lazy; +import org.springframework.data.jpa.repository.JpaRepository; + +@Lazy(value = false) +public interface UserRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/UserService.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/UserService.java new file mode 100644 index 0000000000..7b7f42f2b3 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/UserService.java @@ -0,0 +1,20 @@ +package com.baeldung.listvsset.eager.list.simpledomain; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +@Service +public class UserService extends com.baeldung.listvsset.Service { + + public UserService(JpaRepository repository) { + super(repository); + } + + @Override + public UserRepository getRepository() { + return ((UserRepository) super.getRepository()); + } + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Application.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Application.java new file mode 100644 index 0000000000..6eb23eac7a --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Application.java @@ -0,0 +1,8 @@ +package com.baeldung.listvsset.eager.set.fulldomain; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Comment.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Comment.java new file mode 100644 index 0000000000..ab935de4ee --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Comment.java @@ -0,0 +1,44 @@ +package com.baeldung.listvsset.eager.set.fulldomain; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; +import java.util.Objects; +import lombok.Data; + +@Data +@Entity +public class Comment { + + @Id + private Long id; + + private String text; + + @ManyToOne + private User author; + + @JsonBackReference + @ManyToOne + private Post post; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Comment comment = (Comment) o; + + return Objects.equals(id, comment.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Group.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Group.java new file mode 100644 index 0000000000..de0ba9a59d --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Group.java @@ -0,0 +1,43 @@ +package com.baeldung.listvsset.eager.set.fulldomain; + +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.Table; +import java.util.Objects; +import java.util.Set; +import lombok.Data; + +@Data +@Entity(name = "interest_group") +@Table(name = "interest_group") +public class Group { + + @Id + private Long id; + + private String name; + + @ManyToMany(fetch = FetchType.EAGER) + private Set members; + + @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(id, group.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Post.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Post.java new file mode 100644 index 0000000000..7c4913fbec --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Post.java @@ -0,0 +1,52 @@ +package com.baeldung.listvsset.eager.set.fulldomain; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonManagedReference; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.Lob; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import java.util.Objects; +import java.util.Set; +import lombok.Data; + +@Entity +@Data +public class Post { + + @Id + private Long id; + + @Lob + private String content; + + @JsonManagedReference + @OneToMany(cascade = CascadeType.ALL, mappedBy = "post", fetch = FetchType.EAGER) + private Set comments; + + @JsonBackReference + @ManyToOne + private User author; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Post post = (Post) o; + + return Objects.equals(id, post.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/PostRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/PostRepository.java new file mode 100644 index 0000000000..adc22019c9 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/PostRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.listvsset.eager.set.fulldomain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PostRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Profile.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Profile.java new file mode 100644 index 0000000000..914702a373 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Profile.java @@ -0,0 +1,28 @@ +package com.baeldung.listvsset.eager.set.fulldomain; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.Lob; +import jakarta.persistence.OneToOne; +import lombok.Data; + +@Entity +@Data +public class Profile { + + @Id + private Long id; + + @Lob + private String biography; + private String website; + private String profilePictureUrl; + + @JsonBackReference + @OneToOne(mappedBy = "profile") + @JoinColumn(unique = true) + private User user; +} + diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/User.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/User.java new file mode 100644 index 0000000000..a0efbac57a --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/User.java @@ -0,0 +1,56 @@ +package com.baeldung.listvsset.eager.set.fulldomain; + +import com.fasterxml.jackson.annotation.JsonManagedReference; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.OneToMany; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import java.util.Objects; +import java.util.Set; +import lombok.Data; + +@Data +@Entity(name = "simple_user") +@Table(name = "simple_user") +public class User { + + @Id + private Long id; + private String username; + private String email; + + @JsonManagedReference + @OneToOne(cascade = CascadeType.ALL) + private Profile profile; + + @JsonManagedReference + @OneToMany(cascade = CascadeType.ALL, mappedBy = "author", fetch = FetchType.EAGER) + protected Set posts; + + + @ManyToMany(mappedBy = "members", fetch = FetchType.EAGER) + private Set groups; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + User user = (User) o; + + return Objects.equals(id, user.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/UserRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/UserRepository.java new file mode 100644 index 0000000000..5812881c89 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/UserRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.listvsset.eager.set.fulldomain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/UserService.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/UserService.java new file mode 100644 index 0000000000..c14e4a5fa4 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/UserService.java @@ -0,0 +1,20 @@ +package com.baeldung.listvsset.eager.set.fulldomain; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +@Service +public class UserService extends com.baeldung.listvsset.Service { + + public UserService(JpaRepository repository) { + super(repository); + } + + @Override + public UserRepository getRepository() { + return ((UserRepository) super.getRepository()); + } + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/Application.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/Application.java new file mode 100644 index 0000000000..ae999bd269 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/Application.java @@ -0,0 +1,8 @@ +package com.baeldung.listvsset.eager.set.moderatedomain; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/Group.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/Group.java new file mode 100644 index 0000000000..6331183ac9 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/Group.java @@ -0,0 +1,23 @@ +package com.baeldung.listvsset.eager.set.moderatedomain; + +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.Table; +import java.util.Set; +import lombok.Data; + +@Data +@Entity(name = "interest_group") +@Table(name = "interest_group") +public class Group { + + @Id + private Long id; + + private String name; + + @ManyToMany(fetch = FetchType.EAGER) + private Set members; +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/GroupRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/GroupRepository.java new file mode 100644 index 0000000000..5cb4690adb --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/GroupRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.listvsset.eager.set.moderatedomain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface GroupRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/GroupService.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/GroupService.java new file mode 100644 index 0000000000..3a8a4fcaa3 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/GroupService.java @@ -0,0 +1,29 @@ +package com.baeldung.listvsset.eager.set.moderatedomain; + +import java.util.List; +import java.util.Optional; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class GroupService { + + private final GroupRepository groupRepository; + + @Autowired + public GroupService(GroupRepository groupRepository) { + this.groupRepository = groupRepository; + } + + public Optional findById(Long aLong) { + return groupRepository.findById(aLong); + } + + public List findAll() { + return groupRepository.findAll(); + } + + public void save(Group group) { + groupRepository.save(group); + } +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/Post.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/Post.java new file mode 100644 index 0000000000..02449a3402 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/Post.java @@ -0,0 +1,43 @@ +package com.baeldung.listvsset.eager.set.moderatedomain; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Lob; +import jakarta.persistence.ManyToOne; +import java.util.Objects; +import lombok.Data; + +@Entity +@Data +public class Post { + + @Id + private Long id; + + @Lob + private String content; + + @JsonBackReference + @ManyToOne + private User author; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Post post = (Post) o; + + return Objects.equals(id, post.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/PostRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/PostRepository.java new file mode 100644 index 0000000000..6387cee108 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/PostRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.listvsset.eager.set.moderatedomain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PostRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/User.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/User.java new file mode 100644 index 0000000000..89f9736c41 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/User.java @@ -0,0 +1,46 @@ +package com.baeldung.listvsset.eager.set.moderatedomain; + +import com.fasterxml.jackson.annotation.JsonManagedReference; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import java.util.Objects; +import java.util.Set; +import lombok.Data; + +@Data +@Entity(name = "simple_user") +@Table(name = "simple_user") +public class User { + + @Id + private Long id; + private String username; + private String email; + + @JsonManagedReference + @OneToMany(cascade = CascadeType.ALL, mappedBy = "author", fetch = FetchType.EAGER) + protected Set posts; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + User user = (User) o; + + return Objects.equals(id, user.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/UserRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/UserRepository.java new file mode 100644 index 0000000000..bf54e0d11b --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/UserRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.listvsset.eager.set.moderatedomain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/UserService.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/UserService.java new file mode 100644 index 0000000000..59c8d5dd36 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/UserService.java @@ -0,0 +1,20 @@ +package com.baeldung.listvsset.eager.set.moderatedomain; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +@Service +public class UserService extends com.baeldung.listvsset.Service { + + public UserService(JpaRepository repository) { + super(repository); + } + + @Override + public UserRepository getRepository() { + return ((UserRepository) super.getRepository()); + } + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/Application.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/Application.java new file mode 100644 index 0000000000..15d780965a --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/Application.java @@ -0,0 +1,8 @@ +package com.baeldung.listvsset.eager.set.simpledomain; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/Post.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/Post.java new file mode 100644 index 0000000000..69c137e350 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/Post.java @@ -0,0 +1,43 @@ +package com.baeldung.listvsset.eager.set.simpledomain; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Lob; +import jakarta.persistence.ManyToOne; +import java.util.Objects; +import lombok.Data; + +@Entity +@Data +public class Post { + + @Id + private Long id; + + @Lob + private String content; + + @JsonBackReference + @ManyToOne + private User author; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Post post = (Post) o; + + return Objects.equals(id, post.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/PostRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/PostRepository.java new file mode 100644 index 0000000000..867144e1b1 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/PostRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.listvsset.eager.set.simpledomain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PostRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/User.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/User.java new file mode 100644 index 0000000000..481ef14499 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/User.java @@ -0,0 +1,27 @@ +package com.baeldung.listvsset.eager.set.simpledomain; + +import com.fasterxml.jackson.annotation.JsonManagedReference; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import java.util.Set; +import lombok.Data; + +@Data +@Entity(name = "simple_user") +@Table(name = "simple_user") +public class User { + + @Id + private Long id; + private String username; + private String email; + + @JsonManagedReference + @OneToMany(cascade = CascadeType.ALL, mappedBy = "author", fetch = FetchType.EAGER) + protected Set posts; + +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/UserRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/UserRepository.java new file mode 100644 index 0000000000..959a7b3357 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/UserRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.listvsset.eager.set.simpledomain; + +import org.springframework.context.annotation.Lazy; +import org.springframework.data.jpa.repository.JpaRepository; + +@Lazy(value = false) +public interface UserRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/UserService.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/UserService.java new file mode 100644 index 0000000000..36e9804b36 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/UserService.java @@ -0,0 +1,20 @@ +package com.baeldung.listvsset.eager.set.simpledomain; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +@Service +public class UserService extends com.baeldung.listvsset.Service { + + public UserService(JpaRepository repository) { + super(repository); + } + + @Override + public UserRepository getRepository() { + return ((UserRepository) super.getRepository()); + } + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/BaseNPlusOneIntegrationTest.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/BaseNPlusOneIntegrationTest.java new file mode 100644 index 0000000000..4e669dadc4 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/BaseNPlusOneIntegrationTest.java @@ -0,0 +1,76 @@ +package com.baeldung.listvsset; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.baeldung.listvsset.util.DatabaseUtil; +import com.baeldung.listvsset.util.JsonUtils; +import io.hypersistence.utils.jdbc.validator.SQLStatementCountValidator; +import jakarta.annotation.PostConstruct; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest(properties = { + "spring.jpa.generate-ddl=true", + "spring.jpa.show-sql=false", + "spring.datasource.url=jdbc:h2:mem:~/test;DATABASE_TO_UPPER=false" +}) +abstract public class BaseNPlusOneIntegrationTest extends ParametrizationAware { + + @Autowired + protected List> services; + @Autowired + protected DatabaseUtil databaseUtil; + @Autowired + protected JsonUtils jsonUtils; + + private final Map, Service> serviceMap = new HashMap<>(); + + @PostConstruct + void init() { + for (Service service : services) { + Class parametrization = service.getParametrizationClass().get(0); + serviceMap.put(parametrization, service); + } + } + + @BeforeEach + void setUp() { + addUsers(); + SQLStatementCountValidator.reset(); + System.out.println("************************************************"); + System.out.println("\n\n\n\n\n"); + + } + + @AfterEach + void tearDown() { + System.out.println("\n\n\n\n\n"); + System.out.println("************************************************"); + databaseUtil.truncateAllTables(); + SQLStatementCountValidator.reset(); + } + + @Test + void givenCorrectConfigurationWhenStartContextThenRepositoryIsPresent() { + assertThat(getService()).isNotNull(); + } + + @Test + void givenCorrectDatabaseWhenStartThenDatabaseIsNotEmpty() { + List result = getService().findAll(); + assertThat(result).isNotEmpty(); + } + + protected Service getService() { + Class parametrization = getParametrizationClass().get(0); + return (Service) serviceMap.get(parametrization); + } + + protected abstract void addUsers(); +} diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/JsonUtilTest.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/JsonUtilTest.java new file mode 100644 index 0000000000..3e14b3c963 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/JsonUtilTest.java @@ -0,0 +1,56 @@ +package com.baeldung.listvsset; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.baeldung.listvsset.eager.list.fulldomain.Application; +import com.baeldung.listvsset.eager.list.fulldomain.Comment; +import com.baeldung.listvsset.eager.list.fulldomain.Group; +import com.baeldung.listvsset.eager.list.fulldomain.Post; +import com.baeldung.listvsset.eager.list.fulldomain.Profile; +import com.baeldung.listvsset.eager.list.fulldomain.User; +import com.baeldung.listvsset.util.JsonUtils; +import com.baeldung.listvsset.util.TestConfig; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest(classes = {Application.class, TestConfig.class}) +class JsonUtilTest { + + @Autowired + private JsonUtils jsonUtils; + + @Test + void givenFileWhenConvertingToUsersThenConversionIsCorrect() { + List users = jsonUtils.getUsers(User.class); + assertThat(users).isNotEmpty(); + boolean wentThroughEverything = false; + for (User user : users) { + assertThat(user.getGroups()).isNotNull(); + Profile profile = user.getProfile(); + if (profile != null) { + assertThat(user.getId()).isEqualTo(profile.getUser().getId()); + } + for (Post post : user.getPosts()) { + assertThat(user.getId()).isEqualTo(post.getAuthor().getId()); + if (post.getComments() != null) { + wentThroughEverything = true; + for (Comment comment : post.getComments()) { + assertThat(post.getId()).isEqualTo(comment.getPost().getId()); + } + } + } + } + assertTrue(wentThroughEverything); + } + + @Test + void givenFileWhenConvertingToGroupsThenConversionIsCorrect() { + List groups = jsonUtils.getGroups(Group.class); + assertThat(groups).isNotEmpty(); + } + + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerFullDomainIntegrationTest.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerFullDomainIntegrationTest.java new file mode 100644 index 0000000000..3e7c46f47c --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerFullDomainIntegrationTest.java @@ -0,0 +1,129 @@ +package com.baeldung.listvsset.list; + +import static com.vladmihalcea.sql.SQLStatementCountValidator.assertSelectCount; + +import com.baeldung.listvsset.BaseNPlusOneIntegrationTest; +import com.baeldung.listvsset.eager.list.fulldomain.Application; +import com.baeldung.listvsset.eager.list.fulldomain.Comment; +import com.baeldung.listvsset.eager.list.fulldomain.Group; +import com.baeldung.listvsset.eager.list.fulldomain.Post; +import com.baeldung.listvsset.eager.list.fulldomain.User; +import com.baeldung.listvsset.util.TestConfig; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.ToIntFunction; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest(classes = {Application.class, TestConfig.class}, properties = { + "hibernate.show_sql=true", + "logging.level.org.hibernate.SQL=debug", + "logging.level.org.hibernate.orm.jdbc.bind=trace" +}) +class NPlusOneEagerFullDomainIntegrationTest extends BaseNPlusOneIntegrationTest { + + public static final String POSTS = "posts"; + public static final String USERS = "users"; + + @ParameterizedTest + @MethodSource + void givenEagerListBasedUser_WhenFetchingAllUsers_ThenIssueNPlusOneRequests(ToIntFunction> function) { + int numberOfRequests = getService().countNumberOfRequestsWithFunction(function); + assertSelectCount(numberOfRequests); + } + + static Stream givenEagerListBasedUser_WhenFetchingAllUsers_ThenIssueNPlusOneRequests() { + return Stream.of( + Arguments.of((ToIntFunction>) s -> { + int result = 2 * s.size() + 1; + List posts = s.stream().map(User::getPosts) + .flatMap(List::stream) + .toList(); + + result += posts.size(); + return result; + }) + ); + } + + @ParameterizedTest + @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) + void givenEagerListBasedUser_WhenFetchingOneUser_ThenUseDFS(Long id) { + int numberOfRequests = getService().getUserByIdWithFunction(id, this::countNumberOfRequests); + assertSelectCount(numberOfRequests); + } + + private int countNumberOfRequests(User user) { + HashMap> visitedMap = new HashMap<>(); + visitedMap.put(POSTS, new HashSet<>()); + visitedMap.put(USERS, new HashSet<>()); + int result = 1; + visitedMap.get(USERS).add(user.getId()); + List posts = user.getPosts(); + result += 1; + result += explorePosts(posts, visitedMap); + return result; + + } + + private int explorePosts(List posts, HashMap> visitedMap) { + int result = 0; + if (posts == null || posts.isEmpty()) { + return result; + } + for (Post post : posts) { + if (!visitedMap.get(POSTS).contains(post.getId())) { + result++; + visitedMap.get(POSTS).add(post.getId()); + List commenters = post.getComments().stream().map(Comment::getAuthor).toList(); + result += exploreUsers(commenters, visitedMap); + } + } + return result; + } + + private int exploreUsers(List users, HashMap> visitedMap) { + int result = 0; + if (users == null || users.isEmpty()) { + return result; + } + for (User user : users) { + if (!visitedMap.get(USERS).contains(user.getId())) { + ++result; + visitedMap.get(USERS).add(user.getId()); + result += explorePosts(user.getPosts(), visitedMap); + ++result; + } + } + return result; + } + + protected void addUsers() { + List groups = jsonUtils.getGroups(Group.class); + databaseUtil.saveAll(groups); + List users = jsonUtils.getUsers(User.class); + Map> comments = new HashMap<>(); + for (User user : users) { + for (Post post : user.getPosts()) { + if (!comments.containsKey(post.getId())) { + comments.put(post.getId(), new ArrayList<>()); + } + comments.get(post.getId()).addAll(post.getComments()); + post.setComments(Collections.emptyList()); + } + } + databaseUtil.saveAll(users); + // Handle non-existent users while adding comments + databaseUtil.mergeAll(jsonUtils.getUsers(User.class)); + } + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerModerateDomainIntegrationTest.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerModerateDomainIntegrationTest.java new file mode 100644 index 0000000000..5e5549122f --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerModerateDomainIntegrationTest.java @@ -0,0 +1,87 @@ +package com.baeldung.listvsset.list; + +import static com.vladmihalcea.sql.SQLStatementCountValidator.assertDeleteCount; +import static com.vladmihalcea.sql.SQLStatementCountValidator.assertInsertCount; +import static com.vladmihalcea.sql.SQLStatementCountValidator.assertSelectCount; +import static com.vladmihalcea.sql.SQLStatementCountValidator.reset; +import static org.assertj.core.api.Assertions.assertThat; + +import com.baeldung.listvsset.BaseNPlusOneIntegrationTest; +import com.baeldung.listvsset.eager.list.moderatedomain.Application; +import com.baeldung.listvsset.eager.list.moderatedomain.Group; +import com.baeldung.listvsset.eager.list.moderatedomain.GroupService; +import com.baeldung.listvsset.eager.list.moderatedomain.User; +import com.baeldung.listvsset.util.TestConfig; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest(classes = {Application.class, TestConfig.class}, properties = { + "hibernate.show_sql=true", + "logging.level.org.hibernate.SQL=debug", + "logging.level.org.hibernate.orm.jdbc.bind=trace" +}) +class NPlusOneEagerModerateDomainIntegrationTest extends BaseNPlusOneIntegrationTest { + + @Autowired + private GroupService groupService; + + @Test + void givenEagerListBasedUser_whenFetchingAllUsers_thenIssueNPlusOneRequests() { + List users = getService().findAll(); + assertSelectCount(users.size() + 1); + } + + @ParameterizedTest + @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) + void givenEagerListBasedUser_whenFetchingOneUser_thenIssueOneRequest(Long id) { + getService().getUserById(id); + assertSelectCount(1); + } + + @Test + void givenEagerListBasedGroup_whenFetchingAllGroups_thenIssueNPlusMPlusOneRequests() { + List groups = groupService.findAll(); + Set users = groups.stream().map(Group::getMembers).flatMap(List::stream).collect(Collectors.toSet()); + assertSelectCount(groups.size() + users.size() + 1); + } + + @ParameterizedTest + @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) + void givenEagerListBasedGroup_whenFetchingAllGroups_thenIssueNPlusOneRequests(Long groupId) { + Optional group = groupService.findById(groupId); + assertThat(group).isPresent(); + assertSelectCount(1 + group.get().getMembers().size()); + } + @ParameterizedTest + @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) + void givenEagerListBasedGroup_whenRemoveUser_thenRecreateGroup(Long groupId) { + Optional optionalGroup = groupService.findById(groupId); + assertThat(optionalGroup).isPresent(); + Group group = optionalGroup.get(); + List members = group.getMembers(); + assertSelectCount(1 + members.size()); + if (!members.isEmpty()) { + reset(); + members.remove(0); + groupService.save(group); + assertSelectCount(1 + members.size() + 1); + assertDeleteCount(1); + assertInsertCount(members.size()); + } + } + + protected void addUsers() { + List users = jsonUtils.getUsers(User.class); + databaseUtil.saveAll(users); + List groups = jsonUtils.getGroupsWithMembers(Group.class); + databaseUtil.saveAll(groups); + } + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerSimpleDomainIntegrationTest.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerSimpleDomainIntegrationTest.java new file mode 100644 index 0000000000..0c14ce8e50 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerSimpleDomainIntegrationTest.java @@ -0,0 +1,67 @@ +package com.baeldung.listvsset.list; + +import static com.vladmihalcea.sql.SQLStatementCountValidator.assertSelectCount; +import static com.vladmihalcea.sql.SQLStatementCountValidator.assertUpdateCount; +import static com.vladmihalcea.sql.SQLStatementCountValidator.reset; +import static org.assertj.core.api.Assertions.assertThat; + +import com.baeldung.listvsset.BaseNPlusOneIntegrationTest; +import com.baeldung.listvsset.eager.list.simpledomain.Application; +import com.baeldung.listvsset.eager.list.simpledomain.Post; +import com.baeldung.listvsset.eager.list.simpledomain.User; +import com.baeldung.listvsset.util.TestConfig; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest(classes = {Application.class, TestConfig.class}, properties = { + "hibernate.show_sql=true", + "logging.level.org.hibernate.SQL=debug", + "logging.level.org.hibernate.orm.jdbc.bind=trace" +}) +class NPlusOneEagerSimpleDomainIntegrationTest extends BaseNPlusOneIntegrationTest { + + @Test + void givenEagerListBasedUser_WhenFetchingAllUsers_ThenIssueNPlusOneRequests() { + List users = getService().findAll(); + assertSelectCount(users.size() + 1); + } + + @ParameterizedTest + @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) + void givenEagerListBasedUser_WhenFetchingOneUser_ThenIssueOneRequest(Long id) { + getService().getUserById(id); + assertSelectCount(1); + } + + @ParameterizedTest + @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) + void givenEagerListBasedUser_whenDeletePost_ThenIssueSingleUpdate(Long id) { + Optional optionalUser = getService().getUserById(id); + assertSelectCount(1); + optionalUser.ifPresent(user -> { + List posts = user.getPosts(); + int originalNumberOfPosts = posts.size(); + reset(); + if (!posts.isEmpty()) { + posts.get(0).setAuthor(null); + getService().save(user); + assertSelectCount(1); + assertUpdateCount(1); + getService().getUserById(id).ifPresent(updatedUser -> { + assertThat(updatedUser.getPosts()).hasSize(originalNumberOfPosts - 1); + }); + } + + }); + } + + protected void addUsers() { + List users = jsonUtils.getUsers(User.class); + databaseUtil.saveAll(users); + } + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerFullDomainJoinIntegrationTest.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerFullDomainJoinIntegrationTest.java new file mode 100644 index 0000000000..001398607d --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerFullDomainJoinIntegrationTest.java @@ -0,0 +1,106 @@ +package com.baeldung.listvsset.set; + +import static com.vladmihalcea.sql.SQLStatementCountValidator.assertSelectCount; + +import com.baeldung.listvsset.BaseNPlusOneIntegrationTest; +import com.baeldung.listvsset.eager.set.fulldomain.Application; +import com.baeldung.listvsset.eager.set.fulldomain.Comment; +import com.baeldung.listvsset.eager.set.fulldomain.Group; +import com.baeldung.listvsset.eager.set.fulldomain.Post; +import com.baeldung.listvsset.eager.set.fulldomain.User; +import com.baeldung.listvsset.util.TestConfig; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest(classes = {Application.class, TestConfig.class}, properties = { + "hibernate.show_sql=true", + "logging.level.org.hibernate.SQL=debug", + "logging.level.org.hibernate.orm.jdbc.bind=trace" +}) +class NPlusOneEagerFullDomainJoinIntegrationTest extends BaseNPlusOneIntegrationTest { + + public static final String POSTS = "posts"; + public static final String USERS = "users"; + + @Test + void givenEagerSetBasedUser_WhenFetchingAllUsers_ThenIssueNPlusOneRequests() { + List users = getService().findAll(); + assertSelectCount(users.size() + 1); + } + + @ParameterizedTest + @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) + void givenEagerUserWhenFetchingOneUserThenIssueNPlusOneRequestsWithCartesianProduct(Long id) { + HashMap> visitedMap = new HashMap<>(); + visitedMap.put(POSTS, new HashSet<>()); + visitedMap.put(USERS, new HashSet<>()); + int numberOfRequests = getService() + .getUserByIdWithFunction(id, user -> { + int result = 1; + visitedMap.get(USERS).add(user.getId()); + Set posts = user.getPosts(); + result += explorePosts(posts, visitedMap); + return result; + }); + assertSelectCount(numberOfRequests); + } + + private int explorePosts(Set posts, HashMap> visitedMap) { + int result = 0; + if (posts == null || posts.isEmpty()) { + return result; + } + for (Post post : posts) { + if (!visitedMap.get(POSTS).contains(post.getId())) { + visitedMap.get(POSTS).add(post.getId()); + List commenters = post.getComments().stream().map(Comment::getAuthor).toList(); + result += exploreUsers(commenters, visitedMap); + } + } + return result; + } + + private int exploreUsers(List users, HashMap> visitedMap) { + int result = 0; + if (users == null || users.isEmpty()) { + return result; + } + for (User user : users) { + if (!visitedMap.get(USERS).contains(user.getId())) { + ++result; + visitedMap.get(USERS).add(user.getId()); + result += explorePosts(user.getPosts(), visitedMap); + } + } + return result; + } + + protected void addUsers() { + List groups = jsonUtils.getGroups(Group.class); + databaseUtil.saveAll(groups); + List users = jsonUtils.getUsers(User.class); + Map> comments = new HashMap<>(); + for (User user : users) { + for (Post post : user.getPosts()) { + if (!comments.containsKey(post.getId())) { + comments.put(post.getId(), new ArrayList<>()); + } + comments.get(post.getId()).addAll(post.getComments()); + post.setComments(Collections.emptySet()); + } + } + databaseUtil.saveAll(users); + // Handle non-existent users while adding comments + databaseUtil.mergeAll(jsonUtils.getUsers(User.class)); + } + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerModerateDomainIntegrationTest.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerModerateDomainIntegrationTest.java new file mode 100644 index 0000000000..55b7bfb287 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerModerateDomainIntegrationTest.java @@ -0,0 +1,83 @@ +package com.baeldung.listvsset.set; + +import static com.vladmihalcea.sql.SQLStatementCountValidator.assertDeleteCount; +import static com.vladmihalcea.sql.SQLStatementCountValidator.assertSelectCount; +import static com.vladmihalcea.sql.SQLStatementCountValidator.reset; +import static org.assertj.core.api.Assertions.assertThat; + +import com.baeldung.listvsset.BaseNPlusOneIntegrationTest; +import com.baeldung.listvsset.eager.set.moderatedomain.Application; +import com.baeldung.listvsset.eager.set.moderatedomain.Group; +import com.baeldung.listvsset.eager.set.moderatedomain.GroupService; +import com.baeldung.listvsset.eager.set.moderatedomain.User; +import com.baeldung.listvsset.util.TestConfig; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest(classes = {Application.class, TestConfig.class}, properties = { + "hibernate.show_sql=true", + "logging.level.org.hibernate.SQL=debug", + "logging.level.org.hibernate.orm.jdbc.bind=trace" +}) +class NPlusOneEagerModerateDomainIntegrationTest extends BaseNPlusOneIntegrationTest { + + @Autowired + private GroupService groupService; + + @Test + void givenEagerSetBasedUser_whenFetchingAllUsers_thenIssueNPlusOneRequests() { + List users = getService().findAll(); + assertSelectCount(users.size() + 1); + } + + @ParameterizedTest + @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) + void givenEagerSetBasedUser_whenFetchingOneUser_thenIssueOneRequest(Long id) { + getService().getUserById(id); + assertSelectCount(1); + } + + @Test + void givenEagerSetBasedGroup_whenFetchingAllGroups_thenIssueNPlusOneRequests() { + List groups = groupService.findAll(); + assertSelectCount(groups.size() + 1); + } + + @ParameterizedTest + @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) + void givenEagerSetBasedGroup_whenFetchingAllGroups_thenCreateCartesianProductInOneQuery(Long groupId) { + groupService.findById(groupId); + assertSelectCount(1); + } + + @ParameterizedTest + @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) + void givenEagerListBasedGroup_whenRemoveUser_thenIssueOnlyOneDelete(Long groupId) { + Optional optionalGroup = groupService.findById(groupId); + assertThat(optionalGroup).isPresent(); + Group group = optionalGroup.get(); + if (!group.getMembers().isEmpty()) { + reset(); + Set newMembers = group.getMembers().stream().skip(1).collect(Collectors.toSet()); + group.setMembers(newMembers); + groupService.save(group); + assertSelectCount(1); + assertDeleteCount(1); + } + } + + protected void addUsers() { + List users = jsonUtils.getUsers(User.class); + databaseUtil.saveAll(users); + List groups = jsonUtils.getGroupsWithMembers(Group.class); + databaseUtil.saveAll(groups); + } + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerSimpleDomainIntegrationTest.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerSimpleDomainIntegrationTest.java new file mode 100644 index 0000000000..e6161fa57b --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerSimpleDomainIntegrationTest.java @@ -0,0 +1,68 @@ +package com.baeldung.listvsset.set; + +import static com.vladmihalcea.sql.SQLStatementCountValidator.assertSelectCount; +import static com.vladmihalcea.sql.SQLStatementCountValidator.assertUpdateCount; +import static com.vladmihalcea.sql.SQLStatementCountValidator.reset; +import static org.assertj.core.api.Assertions.assertThat; + +import com.baeldung.listvsset.BaseNPlusOneIntegrationTest; +import com.baeldung.listvsset.eager.set.simpledomain.Application; +import com.baeldung.listvsset.eager.set.simpledomain.Post; +import com.baeldung.listvsset.eager.set.simpledomain.User; +import com.baeldung.listvsset.util.TestConfig; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest(classes = {Application.class, TestConfig.class}, properties = { + "hibernate.show_sql=true", + "logging.level.org.hibernate.SQL=debug", + "logging.level.org.hibernate.orm.jdbc.bind=trace" +}) +class NPlusOneEagerSimpleDomainIntegrationTest extends BaseNPlusOneIntegrationTest { + + @Test + void givenEagerSetBasedUser_WhenFetchingAllUsers_ThenIssueNPlusOneRequests() { + List users = getService().findAll(); + assertSelectCount(users.size() + 1); + } + + @ParameterizedTest + @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) + void givenEagerSetBasedUser_WhenFetchingOneUser_ThenIssueOneRequest(Long id) { + getService().getUserById(id); + assertSelectCount(1); + } + + @ParameterizedTest + @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) + void givenEagerListBasedUser_whenDeletePost_ThenIssueSingleUpdate(Long id) { + Optional optionalUser = getService().getUserById(id); + assertSelectCount(1); + optionalUser.ifPresent(user -> { + Set posts = user.getPosts(); + int originalNumberOfPosts = posts.size(); + reset(); + if (!posts.isEmpty()) { + posts.iterator().next().setAuthor(null); + getService().save(user); + assertSelectCount(1); + assertUpdateCount(1); + getService().getUserById(id).ifPresent(updatedUser -> { + assertThat(updatedUser.getPosts()).hasSize(originalNumberOfPosts - 1); + }); + } + + }); + } + + protected void addUsers() { + List users = jsonUtils.getUsers(User.class); + databaseUtil.saveAll(users); + } + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/util/DataSourceWrapper.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/util/DataSourceWrapper.java new file mode 100644 index 0000000000..6ca7c45391 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/util/DataSourceWrapper.java @@ -0,0 +1,35 @@ +package com.baeldung.listvsset.util; + +import io.hypersistence.utils.logging.InlineQueryLogEntryCreator; +import javax.sql.DataSource; +import net.ttddyy.dsproxy.listener.ChainListener; +import net.ttddyy.dsproxy.listener.DataSourceQueryCountListener; +import net.ttddyy.dsproxy.listener.logging.SLF4JQueryLoggingListener; +import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.stereotype.Component; + +@Component +public class DataSourceWrapper implements BeanPostProcessor { + + public Object postProcessBeforeInitialization(Object bean, String beanName) { + return bean; + } + + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof DataSource originalDataSource) { + ChainListener listener = new ChainListener(); + SLF4JQueryLoggingListener loggingListener = new SLF4JQueryLoggingListener(); + loggingListener.setQueryLogEntryCreator(new InlineQueryLogEntryCreator()); + listener.addListener(loggingListener); + listener.addListener(new DataSourceQueryCountListener()); + return ProxyDataSourceBuilder + .create(originalDataSource) + .name("DS-Proxy") + .listener(listener) + .build(); + } + return bean; + } +} diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/util/DatabaseUtil.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/util/DatabaseUtil.java new file mode 100644 index 0000000000..1e6e75511f --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/util/DatabaseUtil.java @@ -0,0 +1,47 @@ +package com.baeldung.listvsset.util; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.transaction.Transactional; +import java.util.List; +import org.springframework.stereotype.Component; + +@Component +public class DatabaseUtil { + + public static final String TRUNCATE_QUERY_FORMAT = "TRUNCATE TABLE %s"; + @PersistenceContext + private EntityManager entityManager; + + @Transactional + public void truncateAllTables() { + switchForeignKeysOff(); + entityManager.createNativeQuery("SHOW TABLES", String.class) + .getResultList() + .forEach(this::truncateTable); + switchForeignKeysOn(); + } + + @Transactional + public void saveAll(List entities) { + entities.forEach(s -> entityManager.persist(s)); + } + + @Transactional + public void mergeAll(List entities) { + entities.forEach(s -> entityManager.merge(s)); + } + + private int truncateTable(Object s) { + return entityManager + .createNativeQuery(TRUNCATE_QUERY_FORMAT.formatted(s)).executeUpdate(); + } + + private void switchForeignKeysOn() { + entityManager.createNativeQuery("SET REFERENTIAL_INTEGRITY TRUE").executeUpdate(); + } + + private void switchForeignKeysOff() { + entityManager.createNativeQuery("SET REFERENTIAL_INTEGRITY FALSE").executeUpdate(); + } +} diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/util/JsonUtils.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/util/JsonUtils.java new file mode 100644 index 0000000000..c8577da58d --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/util/JsonUtils.java @@ -0,0 +1,51 @@ +package com.baeldung.listvsset.util; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.File; +import java.io.IOException; +import java.util.List; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class JsonUtils { + + @Value("users.json") + private File userFile; + + @Value("groups.json") + private File groupFile; + + @Value("groups_with_members.json") + private File groupsWithMembersFile; + + private static final ObjectMapper MAPPER = new ObjectMapper(); + + static { + MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + } + + public List getUsers(Class userType) { + return getObjects(userType, userFile); + } + + public List getGroups(Class userType) { + return getObjects(userType, groupFile); + } + + public List getGroupsWithMembers(Class groupType) { + return getObjects(groupType, groupsWithMembersFile); + } + + private List getObjects(Class userType, File userFile1) { + try { + return MAPPER.readValue(userFile1, MAPPER.getTypeFactory() + .constructCollectionType(List.class, userType)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/util/TestConfig.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/util/TestConfig.java new file mode 100644 index 0000000000..82ee56b35b --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/util/TestConfig.java @@ -0,0 +1,24 @@ +package com.baeldung.listvsset.util; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class TestConfig { + + @Bean + public DataSourceWrapper dataSourceWrapper() { + return new DataSourceWrapper(); + } + + @Bean + public DatabaseUtil databaseUtil() { + return new DatabaseUtil(); + } + + @Bean + JsonUtils jsonUtils() { + return new JsonUtils(); + } + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/test/resources/groups.json b/persistence-modules/spring-boot-persistence-4/src/test/resources/groups.json new file mode 100644 index 0000000000..9ccad3f79a --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/test/resources/groups.json @@ -0,0 +1,402 @@ +[ + { + "id": 1, + "name": "Bitwolf" + }, + { + "id": 2, + "name": "Solarbreeze" + }, + { + "id": 3, + "name": "Bamity" + }, + { + "id": 4, + "name": "Hatity" + }, + { + "id": 5, + "name": "Veribet" + }, + { + "id": 6, + "name": "Tampflex" + }, + { + "id": 7, + "name": "Zontrax" + }, + { + "id": 8, + "name": "Aerified" + }, + { + "id": 9, + "name": "Konklab" + }, + { + "id": 10, + "name": "Tampflex" + }, + { + "id": 11, + "name": "Mat Lam Tam" + }, + { + "id": 12, + "name": "Alpha" + }, + { + "id": 13, + "name": "Quo Lux" + }, + { + "id": 14, + "name": "Kanlam" + }, + { + "id": 15, + "name": "Veribet" + }, + { + "id": 16, + "name": "Ventosanzap" + }, + { + "id": 17, + "name": "Opela" + }, + { + "id": 18, + "name": "Alphazap" + }, + { + "id": 19, + "name": "Lotlux" + }, + { + "id": 20, + "name": "Alpha" + }, + { + "id": 21, + "name": "Andalax" + }, + { + "id": 22, + "name": "Bitchip" + }, + { + "id": 23, + "name": "Cookley" + }, + { + "id": 24, + "name": "Konklab" + }, + { + "id": 25, + "name": "Konklab" + }, + { + "id": 26, + "name": "Lotstring" + }, + { + "id": 27, + "name": "Konklux" + }, + { + "id": 28, + "name": "Temp" + }, + { + "id": 29, + "name": "Voyatouch" + }, + { + "id": 30, + "name": "Trippledex" + }, + { + "id": 31, + "name": "Sonsing" + }, + { + "id": 32, + "name": "Andalax" + }, + { + "id": 33, + "name": "Voltsillam" + }, + { + "id": 34, + "name": "Stronghold" + }, + { + "id": 35, + "name": "Hatity" + }, + { + "id": 36, + "name": "Andalax" + }, + { + "id": 37, + "name": "Holdlamis" + }, + { + "id": 38, + "name": "Bamity" + }, + { + "id": 39, + "name": "Voltsillam" + }, + { + "id": 40, + "name": "Aerified" + }, + { + "id": 41, + "name": "Regrant" + }, + { + "id": 42, + "name": "Subin" + }, + { + "id": 43, + "name": "Tin" + }, + { + "id": 44, + "name": "Voltsillam" + }, + { + "id": 45, + "name": "Trippledex" + }, + { + "id": 46, + "name": "Solarbreeze" + }, + { + "id": 47, + "name": "Treeflex" + }, + { + "id": 48, + "name": "Fintone" + }, + { + "id": 49, + "name": "Tin" + }, + { + "id": 50, + "name": "It" + }, + { + "id": 51, + "name": "Y-Solowarm" + }, + { + "id": 52, + "name": "Bigtax" + }, + { + "id": 53, + "name": "Flowdesk" + }, + { + "id": 54, + "name": "Vagram" + }, + { + "id": 55, + "name": "Keylex" + }, + { + "id": 56, + "name": "Zontrax" + }, + { + "id": 57, + "name": "Vagram" + }, + { + "id": 58, + "name": "Lotstring" + }, + { + "id": 59, + "name": "Cookley" + }, + { + "id": 60, + "name": "Zaam-Dox" + }, + { + "id": 61, + "name": "Zoolab" + }, + { + "id": 62, + "name": "Quo Lux" + }, + { + "id": 63, + "name": "Ventosanzap" + }, + { + "id": 64, + "name": "Ventosanzap" + }, + { + "id": 65, + "name": "Lotstring" + }, + { + "id": 66, + "name": "Keylex" + }, + { + "id": 67, + "name": "Stim" + }, + { + "id": 68, + "name": "Alphazap" + }, + { + "id": 69, + "name": "It" + }, + { + "id": 70, + "name": "Cardify" + }, + { + "id": 71, + "name": "Zamit" + }, + { + "id": 72, + "name": "Holdlamis" + }, + { + "id": 73, + "name": "Konklab" + }, + { + "id": 74, + "name": "Ventosanzap" + }, + { + "id": 75, + "name": "Wrapsafe" + }, + { + "id": 76, + "name": "Cookley" + }, + { + "id": 77, + "name": "Y-find" + }, + { + "id": 78, + "name": "Regrant" + }, + { + "id": 79, + "name": "Otcom" + }, + { + "id": 80, + "name": "Cookley" + }, + { + "id": 81, + "name": "Bigtax" + }, + { + "id": 82, + "name": "Holdlamis" + }, + { + "id": 83, + "name": "Bigtax" + }, + { + "id": 84, + "name": "Voltsillam" + }, + { + "id": 85, + "name": "Duobam" + }, + { + "id": 86, + "name": "Flowdesk" + }, + { + "id": 87, + "name": "It" + }, + { + "id": 88, + "name": "Hatity" + }, + { + "id": 89, + "name": "Zathin" + }, + { + "id": 90, + "name": "Hatity" + }, + { + "id": 91, + "name": "Cardify" + }, + { + "id": 92, + "name": "Konklab" + }, + { + "id": 93, + "name": "Treeflex" + }, + { + "id": 94, + "name": "Flexidy" + }, + { + "id": 95, + "name": "Latlux" + }, + { + "id": 96, + "name": "Bitwolf" + }, + { + "id": 97, + "name": "Zontrax" + }, + { + "id": 98, + "name": "Greenlam" + }, + { + "id": 99, + "name": "Asoka" + }, + { + "id": 100, + "name": "Ronstring" + } +] \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/test/resources/groups_with_members.json b/persistence-modules/spring-boot-persistence-4/src/test/resources/groups_with_members.json new file mode 100644 index 0000000000..99e0da9891 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/test/resources/groups_with_members.json @@ -0,0 +1,183 @@ +[ + { + "id": 1, + "name": "Pacocha-Hills", + "members": [ + { + "id": 1 + }, + { + "id": 2 + }, + { + "id": 3 + }, + { + "id": 4 + } + ] + }, + { + "id": 2, + "name": "Windler, Wiegand and Bernhard", + "members": [] + }, + { + "id": 3, + "name": "Flatley-Hilll", + "members": [ + { + "id": 1 + }, + { + "id": 2 + }, + { + "id": 3 + }, + { + "id": 4 + }, + { + "id": 5 + }, + { + "id": 6 + }, + { + "id": 7 + }, + { + "id": 8 + }, + { + "id": 9 + } + ] + }, + { + "id": 4, + "name": "Daugherty and Sons", + "members": [ + { + "id": 1 + }, + { + "id": 2 + }, + { + "id": 3 + }, + { + "id": 4 + }, + { + "id": 5 + }, + { + "id": 6 + }, + { + "id": 7 + } + ] + }, + { + "id": 5, + "name": "Leannon, Kub and Murazik", + "members": [ + { + "id": 1 + }, + { + "id": 2 + }, + { + "id": 3 + }, + { + "id": 4 + }, + { + "id": 5 + }, + { + "id": 6 + } + ] + }, + { + "id": 6, + "name": "Considine-Koss", + "members": [ + { + "id": 1 + }, + { + "id": 2 + }, + { + "id": 3 + }, + { + "id": 4 + }, + { + "id": 5 + }, + { + "id": 6 + }, + { + "id": 7 + } + ] + }, + { + "id": 7, + "name": "Russel LLC", + "members": [ + { + "id": 1 + }, + { + "id": 2 + }, + { + "id": 3 + }, + { + "id": 4 + } + ] + }, + { + "id": 8, + "name": "Wisoky-Grimes", + "members": [ + { + "id": 1 + }, + { + "id": 2 + } + ] + }, + { + "id": 9, + "name": "Larson Inc", + "members": [ + { + "id": 1 + }, + { + "id": 2 + } + ] + }, + { + "id": 10, + "name": "Franecki-Simonis", + "members": [] + } +] \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/test/resources/users.json b/persistence-modules/spring-boot-persistence-4/src/test/resources/users.json new file mode 100644 index 0000000000..1fa6202dd3 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/test/resources/users.json @@ -0,0 +1,899 @@ +[ + { + "id": 1, + "username": "ecrumbleholme0", + "email": "pmerritt0@wordpress.org", + "groups": [ + { + "id": 70 + }, + { + "id": 67 + }, + { + "id": 54 + }, + { + "id": 41 + }, + { + "id": 40 + }, + { + "id": 5 + }, + { + "id": 82 + } + ], + "profile": { + "id": 1, + "biography": "Mauris enim leo, rhoncus sed, vestibulum sit amet, cursus id, turpis. Integer aliquet, massa id lobortis convallis, tortor risus dapibus augue, vel accumsan tellus nisi eu orci. Mauris lacinia sapien quis libero.", + "website": "https://engadget.com/adipiscing/lorem/vitae/mattis.jpg?non=in&mattis=porttitor&pulvinar=pede&nulla", + "profilePictureUrl": "http://dummyimage.com/207x100.png/dddddd/000000" + }, + "posts": [] + }, + { + "id": 2, + "username": "moldred1", + "email": "grichardes1@shareasale.com", + "groups": [ + { + "id": 39 + }, + { + "id": 53 + }, + { + "id": 26 + }, + { + "id": 70 + }, + { + "id": 49 + }, + { + "id": 33 + }, + { + "id": 64 + }, + { + "id": 65 + }, + { + "id": 14 + }, + { + "id": 10 + } + ], + "profile": { + "id": 2, + "biography": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin risus. Praesent lectus.", + "website": "http://arizona.edu/urna/ut.html?erat=pretium&volutpat=iaculis&in=diam&congue", + "profilePictureUrl": "http://dummyimage.com/200x100.png/dddddd/000000" + }, + "posts": [ + { + "id": 1, + "content": "Curabitur in libero ut massa volutpat convallis. Morbi odio odio, elementum eu, interdum eu, tincidunt in, leo. Maecenas pulvinar lobortis est.", + "comments": [ + { + "id": 208446, + "test": { + "id": "Optional empowering attitude" + }, + "author": { + "id": 10 + } + }, + { + "id": 229466, + "test": { + "id": "Customizable multi-tasking encryption" + }, + "author": { + "id": 3 + } + }, + { + "id": 408703, + "test": { + "id": "Re-engineered contextually-based protocol" + }, + "author": { + "id": 9 + } + }, + { + "id": 837433, + "test": { + "id": "Centralized well-modulated pricing structure" + }, + "author": { + "id": 8 + } + } + ] + }, + { + "id": 2, + "content": "Donec diam neque, vestibulum eget, vulputate ut, ultrices vel, augue. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec pharetra, magna vestibulum aliquet ultrices, erat tortor sollicitudin mi, sit amet lobortis sapien sapien non mi. Integer ac neque.", + "comments": [] + }, + { + "id": 3, + "content": "Vestibulum quam sapien, varius ut, blandit non, interdum in, ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis faucibus accumsan odio. Curabitur convallis.\n\nDuis consequat dui nec nisi volutpat eleifend. Donec ut dolor. Morbi vel lectus in quam fringilla rhoncus.\n\nMauris enim leo, rhoncus sed, vestibulum sit amet, cursus id, turpis. Integer aliquet, massa id lobortis convallis, tortor risus dapibus augue, vel accumsan tellus nisi eu orci. Mauris lacinia sapien quis libero.", + "comments": [ + { + "id": 53333, + "test": { + "id": "Cross-platform bi-directional encoding" + }, + "author": { + "id": 6 + } + }, + { + "id": 806260, + "test": { + "id": "Expanded composite neural-net" + }, + "author": { + "id": 1 + } + }, + { + "id": 266068, + "test": { + "id": "Implemented attitude-oriented knowledge user" + }, + "author": { + "id": 3 + } + } + ] + } + ] + }, + { + "id": 3, + "username": "agoodsall2", + "email": "ofellman2@ibm.com", + "groups": [ + { + "id": 36 + }, + { + "id": 7 + }, + { + "id": 77 + }, + { + "id": 28 + }, + { + "id": 32 + } + ], + "profile": { + "id": 3, + "biography": "In hac habitasse platea dictumst. Morbi vestibulum, velit id pretium iaculis, diam erat fermentum justo, nec condimentum neque sapien placerat ante. Nulla justo.", + "website": "http://cargocollective.com/consequat/in/consequat/ut/nulla/sed.png?dictumst=faucibus", + "profilePictureUrl": "http://dummyimage.com/224x100.png/cc0000/ffffff" + }, + "posts": [ + { + "id": 4, + "content": "Nam ultrices, libero non mattis pulvinar, nulla pede ullamcorper augue, a suscipit nulla elit ac nulla. Sed vel enim sit amet nunc viverra dapibus. Nulla suscipit ligula in lacus.\n\nCurabitur at ipsum ac tellus semper interdum. Mauris ullamcorper purus sit amet nulla. Quisque arcu libero, rutrum ac, lobortis vel, dapibus at, diam.", + "comments": [ + { + "id": 349493, + "test": { + "id": "Operative actuating budgetary management" + }, + "author": { + "id": 2 + } + }, + { + "id": 909598, + "test": { + "id": "Profound next generation product" + }, + "author": { + "id": 4 + } + }, + { + "id": 247072, + "test": { + "id": "Team-oriented multimedia analyzer" + }, + "author": { + "id": 9 + } + } + ] + }, + { + "id": 5, + "content": "Integer ac leo. Pellentesque ultrices mattis odio. Donec vitae nisi.", + "comments": [ + { + "id": 572489, + "test": { + "id": "Open-source optimizing focus group" + }, + "author": { + "id": 5 + } + }, + { + "id": 133947, + "test": { + "id": "Self-enabling attitude-oriented success" + }, + "author": { + "id": 1 + } + }, + { + "id": 496573, + "test": { + "id": "Profit-focused multimedia firmware" + }, + "author": { + "id": 8 + } + }, + { + "id": 137780, + "test": { + "id": "Self-enabling intermediate info-mediaries" + }, + "author": { + "id": 2 + } + } + ] + }, + { + "id": 6, + "content": "Maecenas tristique, est et tempus semper, est quam pharetra magna, ac consequat metus sapien ut nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris viverra diam vitae quam. Suspendisse potenti.\n\nNullam porttitor lacus at turpis. Donec posuere metus vitae ipsum. Aliquam non mauris.", + "comments": [] + } + ] + }, + { + "id": 4, + "username": "cpourvoieur3", + "email": "mlisimore3@unicef.org", + "groups": [ + { + "id": 27 + }, + { + "id": 49 + }, + { + "id": 21 + }, + { + "id": 48 + }, + { + "id": 90 + }, + { + "id": 57 + }, + { + "id": 19 + }, + { + "id": 10 + } + ], + "profile": { + "id": 4, + "biography": "Curabitur gravida nisi at nibh. In hac habitasse platea dictumst. Aliquam augue quam, sollicitudin vitae, consectetuer eget, rutrum at, lorem.", + "website": "http://slideshare.net/rutrum/nulla/tellus/in/sagittis/dui.png?duis=volutpat&at=erat", + "profilePictureUrl": "http://dummyimage.com/167x100.png/cc0000/ffffff" + }, + "posts": [ + { + "id": 7, + "content": "Vestibulum ac est lacinia nisi venenatis tristique. Fusce congue, diam id ornare imperdiet, sapien urna pretium nisl, ut volutpat sapien arcu sed augue. Aliquam erat volutpat.\n\nIn congue. Etiam justo. Etiam pretium iaculis justo.\n\nIn hac habitasse platea dictumst. Etiam faucibus cursus urna. Ut tellus.", + "comments": [] + }, + { + "id": 8, + "content": "Sed ante. Vivamus tortor. Duis mattis egestas metus.\n\nAenean fermentum. Donec ut mauris eget massa tempor convallis. Nulla neque libero, convallis eget, eleifend luctus, ultricies eu, nibh.\n\nQuisque id justo sit amet sapien dignissim vestibulum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla dapibus dolor vel est. Donec odio justo, sollicitudin ut, suscipit a, feugiat et, eros.", + "comments": [] + }, + { + "id": 9, + "content": "Duis aliquam convallis nunc. Proin at turpis a pede posuere nonummy. Integer non velit.\n\nDonec diam neque, vestibulum eget, vulputate ut, ultrices vel, augue. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec pharetra, magna vestibulum aliquet ultrices, erat tortor sollicitudin mi, sit amet lobortis sapien sapien non mi. Integer ac neque.\n\nDuis bibendum. Morbi non quam nec dui luctus rutrum. Nulla tellus.", + "comments": [ + { + "id": 727396, + "test": { + "id": "Business-focused maximized framework" + }, + "author": { + "id": 6 + } + }, + { + "id": 529333, + "test": { + "id": "Fully-configurable client-driven Graphic Interface" + }, + "author": { + "id": 1 + } + }, + { + "id": 698528, + "test": { + "id": "Diverse methodical framework" + }, + "author": { + "id": 1 + } + }, + { + "id": 570927, + "test": { + "id": "Profound interactive infrastructure" + }, + "author": { + "id": 5 + } + } + ] + }, + { + "id": 10, + "content": "Proin interdum mauris non ligula pellentesque ultrices. Phasellus id sapien in sapien iaculis congue. Vivamus metus arcu, adipiscing molestie, hendrerit at, vulputate vitae, nisl.\n\nAenean lectus. Pellentesque eget nunc. Donec quis orci eget orci vehicula condimentum.", + "comments": [ + { + "id": 374234, + "test": { + "id": "Profit-focused fresh-thinking success" + }, + "author": { + "id": 6 + } + }, + { + "id": 266342, + "test": { + "id": "Advanced optimizing Graphic Interface" + }, + "author": { + "id": 6 + } + }, + { + "id": 970877, + "test": { + "id": "Multi-lateral web-enabled synergy" + }, + "author": { + "id": 8 + } + }, + { + "id": 635357, + "test": { + "id": "Centralized real-time time-frame" + }, + "author": { + "id": 5 + } + }, + { + "id": 818761, + "test": { + "id": "Profit-focused secondary middleware" + }, + "author": { + "id": 2 + } + } + ] + } + ] + }, + { + "id": 5, + "username": "driddoch4", + "email": "hfreake4@simplemachines.org", + "groups": [ + { + "id": 68 + }, + { + "id": 52 + }, + { + "id": 18 + }, + { + "id": 82 + }, + { + "id": 29 + }, + { + "id": 55 + }, + { + "id": 95 + } + ], + "profile": { + "id": 5, + "biography": "Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus vestibulum sagittis sapien. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.", + "website": "http://jiathis.com/turpis/enim/blandit/mi/in.html?duis=augue&mattis=vel&egestas", + "profilePictureUrl": "http://dummyimage.com/181x100.png/5fa2dd/ffffff" + }, + "posts": [ + { + "id": 11, + "content": "Phasellus sit amet erat. Nulla tempus. Vivamus in felis eu sapien cursus vestibulum.\n\nProin eu mi. Nulla ac enim. In tempor, turpis nec euismod scelerisque, quam turpis adipiscing lorem, vitae mattis nibh ligula nec sem.\n\nDuis aliquam convallis nunc. Proin at turpis a pede posuere nonummy. Integer non velit.", + "comments": [ + { + "id": 668167, + "test": { + "id": "Decentralized static application" + }, + "author": { + "id": 2 + } + }, + { + "id": 645021, + "test": { + "id": "Progressive cohesive complexity" + }, + "author": { + "id": 8 + } + }, + { + "id": 904836, + "test": { + "id": "Right-sized human-resource middleware" + }, + "author": { + "id": 2 + } + }, + { + "id": 193482, + "test": { + "id": "Organized bottom-line monitoring" + }, + "author": { + "id": 3 + } + } + ] + }, + { + "id": 12, + "content": "Donec diam neque, vestibulum eget, vulputate ut, ultrices vel, augue. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec pharetra, magna vestibulum aliquet ultrices, erat tortor sollicitudin mi, sit amet lobortis sapien sapien non mi. Integer ac neque.", + "comments": [ + { + "id": 820497, + "test": { + "id": "Open-architected well-modulated structure" + }, + "author": { + "id": 10 + } + } + ] + }, + { + "id": 13, + "content": "Nulla ut erat id mauris vulputate elementum. Nullam varius. Nulla facilisi.\n\nCras non velit nec nisi vulputate nonummy. Maecenas tincidunt lacus at velit. Vivamus vel nulla eget eros elementum pellentesque.\n\nQuisque porta volutpat erat. Quisque erat eros, viverra eget, congue eget, semper rutrum, nulla. Nunc purus.", + "comments": [ + { + "id": 214834, + "test": { + "id": "Face to face content-based contingency" + }, + "author": { + "id": 4 + } + }, + { + "id": 361052, + "test": { + "id": "Vision-oriented client-driven emulation" + }, + "author": { + "id": 10 + } + }, + { + "id": 819369, + "test": { + "id": "Decentralized clear-thinking projection" + }, + "author": { + "id": 9 + } + } + ] + }, + { + "id": 14, + "content": "Integer ac leo. Pellentesque ultrices mattis odio. Donec vitae nisi.\n\nNam ultrices, libero non mattis pulvinar, nulla pede ullamcorper augue, a suscipit nulla elit ac nulla. Sed vel enim sit amet nunc viverra dapibus. Nulla suscipit ligula in lacus.", + "comments": [] + } + ] + }, + { + "id": 6, + "username": "dvelte5", + "email": "shuke5@canalblog.com", + "groups": [ + { + "id": 86 + }, + { + "id": 28 + }, + { + "id": 8 + }, + { + "id": 22 + } + ], + "profile": { + "id": 6, + "biography": "Maecenas leo odio, condimentum id, luctus nec, molestie sed, justo. Pellentesque viverra pede ac diam. Cras pellentesque volutpat dui.", + "website": "http://amazon.co.jp/eget/semper.aspx?faucibus=habitasse&cursus=platea&urna", + "profilePictureUrl": "http://dummyimage.com/179x100.png/dddddd/000000" + }, + "posts": [] + }, + { + "id": 7, + "username": "mhallor6", + "email": "gpetters6@tiny.cc", + "groups": [ + { + "id": 49 + }, + { + "id": 56 + }, + { + "id": 24 + } + ], + "profile": { + "id": 7, + "biography": "Nam ultrices, libero non mattis pulvinar, nulla pede ullamcorper augue, a suscipit nulla elit ac nulla. Sed vel enim sit amet nunc viverra dapibus. Nulla suscipit ligula in lacus.", + "website": "https://globo.com/eget/nunc.js?justo=nulla&eu=neque&massa=libero&donec=convallis&dapibus", + "profilePictureUrl": "http://dummyimage.com/122x100.png/ff4444/ffffff" + }, + "posts": [ + { + "id": 15, + "content": "Nulla ut erat id mauris vulputate elementum. Nullam varius. Nulla facilisi.", + "comments": [ + { + "id": 380358, + "test": { + "id": "Optimized user-facing software" + }, + "author": { + "id": 1 + } + } + ] + } + ] + }, + { + "id": 8, + "username": "nbergeau7", + "email": "mkibbel7@tmall.com", + "groups": [ + { + "id": 24 + }, + { + "id": 54 + }, + { + "id": 95 + } + ], + "profile": { + "id": 8, + "biography": "Suspendisse potenti. In eleifend quam a odio. In hac habitasse platea dictumst.", + "website": "http://people.com.cn/odio/consequat/varius.jsp?eros=nullam&vestibulum=varius&ac=nulla", + "profilePictureUrl": "http://dummyimage.com/230x100.png/5fa2dd/ffffff" + }, + "posts": [ + { + "id": 16, + "content": "Pellentesque at nulla. Suspendisse potenti. Cras in purus eu magna vulputate luctus.\n\nCum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus vestibulum sagittis sapien. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.\n\nEtiam vel augue. Vestibulum rutrum rutrum neque. Aenean auctor gravida sem.", + "comments": [] + }, + { + "id": 17, + "content": "Sed ante. Vivamus tortor. Duis mattis egestas metus.\n\nAenean fermentum. Donec ut mauris eget massa tempor convallis. Nulla neque libero, convallis eget, eleifend luctus, ultricies eu, nibh.", + "comments": [ + { + "id": 886087, + "test": { + "id": "Total demand-driven infrastructure" + }, + "author": { + "id": 9 + } + }, + { + "id": 235353, + "test": { + "id": "Versatile mobile monitoring" + }, + "author": { + "id": 4 + } + }, + { + "id": 264476, + "test": { + "id": "Future-proofed static initiative" + }, + "author": { + "id": 2 + } + } + ] + }, + { + "id": 18, + "content": "Praesent id massa id nisl venenatis lacinia. Aenean sit amet justo. Morbi ut odio.", + "comments": [ + { + "id": 299869, + "test": { + "id": "Pre-emptive 3rd generation pricing structure" + }, + "author": { + "id": 5 + } + }, + { + "id": 82649, + "test": { + "id": "Public-key holistic pricing structure" + }, + "author": { + "id": 2 + } + }, + { + "id": 675757, + "test": { + "id": "Function-based homogeneous monitoring" + }, + "author": { + "id": 4 + } + }, + { + "id": 321146, + "test": { + "id": "Proactive intangible ability" + }, + "author": { + "id": 1 + } + }, + { + "id": 754321, + "test": { + "id": "Operative zero tolerance complexity" + }, + "author": { + "id": 3 + } + } + ] + } + ] + }, + { + "id": 9, + "username": "ddebruin8", + "email": "zdavidovits8@aol.com", + "groups": [ + { + "id": 40 + }, + { + "id": 67 + }, + { + "id": 67 + }, + { + "id": 13 + }, + { + "id": 50 + }, + { + "id": 34 + }, + { + "id": 53 + } + ], + "profile": { + "id": 9, + "biography": "Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus vestibulum sagittis sapien. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.", + "website": "http://shinystat.com/nec/sem/duis/aliquam/convallis/nunc.json?eget=facilisi&semper=cras", + "profilePictureUrl": "http://dummyimage.com/229x100.png/5fa2dd/ffffff" + }, + "posts": [ + { + "id": 19, + "content": "Proin interdum mauris non ligula pellentesque ultrices. Phasellus id sapien in sapien iaculis congue. Vivamus metus arcu, adipiscing molestie, hendrerit at, vulputate vitae, nisl.\n\nAenean lectus. Pellentesque eget nunc. Donec quis orci eget orci vehicula condimentum.", + "comments": [ + { + "id": 246330, + "test": { + "id": "Cross-platform needs-based firmware" + }, + "author": { + "id": 10 + } + }, + { + "id": 340531, + "test": { + "id": "Total content-based data-warehouse" + }, + "author": { + "id": 9 + } + }, + { + "id": 145457, + "test": { + "id": "Programmable transitional budgetary management" + }, + "author": { + "id": 3 + } + }, + { + "id": 13492, + "test": { + "id": "Switchable encompassing archive" + }, + "author": { + "id": 8 + } + }, + { + "id": 310239, + "test": { + "id": "Self-enabling attitude-oriented strategy" + }, + "author": { + "id": 4 + } + } + ] + }, + { + "id": 20, + "content": "Morbi porttitor lorem id ligula. Suspendisse ornare consequat lectus. In est risus, auctor sed, tristique in, tempus sit amet, sem.\n\nFusce consequat. Nulla nisl. Nunc nisl.", + "comments": [] + }, + { + "id": 21, + "content": "Donec diam neque, vestibulum eget, vulputate ut, ultrices vel, augue. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec pharetra, magna vestibulum aliquet ultrices, erat tortor sollicitudin mi, sit amet lobortis sapien sapien non mi. Integer ac neque.\n\nDuis bibendum. Morbi non quam nec dui luctus rutrum. Nulla tellus.\n\nIn sagittis dui vel nisl. Duis ac nibh. Fusce lacus purus, aliquet at, feugiat non, pretium quis, lectus.", + "comments": [ + { + "id": 909627, + "test": { + "id": "Expanded intangible forecast" + }, + "author": { + "id": 7 + } + } + ] + } + ] + }, + { + "id": 10, + "username": "lwoodrooffe9", + "email": "mhowatt9@kickstarter.com", + "groups": [ + { + "id": 31 + }, + { + "id": 44 + }, + { + "id": 38 + }, + { + "id": 14 + } + ], + "profile": { + "id": 10, + "biography": "Nulla ut erat id mauris vulputate elementum. Nullam varius. Nulla facilisi.", + "website": "https://blinklist.com/semper/est/quam/pharetra/magna/ac.png?sagittis=eu&nam=tincidunt", + "profilePictureUrl": "http://dummyimage.com/121x100.png/5fa2dd/ffffff" + }, + "posts": [ + { + "id": 22, + "content": "Sed ante. Vivamus tortor. Duis mattis egestas metus.\n\nAenean fermentum. Donec ut mauris eget massa tempor convallis. Nulla neque libero, convallis eget, eleifend luctus, ultricies eu, nibh.\n\nQuisque id justo sit amet sapien dignissim vestibulum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla dapibus dolor vel est. Donec odio justo, sollicitudin ut, suscipit a, feugiat et, eros.", + "comments": [ + { + "id": 831777, + "test": { + "id": "Open-source non-volatile help-desk" + }, + "author": { + "id": 7 + } + }, + { + "id": 883941, + "test": { + "id": "Fully-configurable mission-critical emulation" + }, + "author": { + "id": 6 + } + }, + { + "id": 759548, + "test": { + "id": "Right-sized bifurcated strategy" + }, + "author": { + "id": 10 + } + }, + { + "id": 294894, + "test": { + "id": "Balanced explicit paradigm" + }, + "author": { + "id": 3 + } + } + ] + } + ] + } +] \ No newline at end of file From c97e529deb2d24b6a2051614b4a27a31617a8d57 Mon Sep 17 00:00:00 2001 From: DiegoMarti2 <150871541+DiegoMarti2@users.noreply.github.com> Date: Thu, 18 Jan 2024 22:26:30 +0200 Subject: [PATCH 024/132] baeldung-articles : BAEL - 6592 (#15682) Difference between ZoneOffset.UTC and ZoneId.of("UTC") --- .../ZoneOffSetAndZoneIdOfUnitTest.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java new file mode 100644 index 0000000000..84f40c3cd5 --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java @@ -0,0 +1,25 @@ +package com.baeldung.zoneoffsetandzoneidof; + +import org.junit.jupiter.api.Test; + +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ZoneOffSetAndZoneIdOfUnitTest { + + @Test + public void givenOffsetDateTimeWithUTCZoneOffset_thenOffsetShouldBeUTC() { + OffsetDateTime dateTimeWithOffset = OffsetDateTime.now(ZoneOffset.UTC); + assertEquals(dateTimeWithOffset.getOffset(), ZoneOffset.UTC); + } + + @Test + public void givenZonedDateTimeWithUTCZoneId_thenZoneShouldBeUTC() { + ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("UTC")); + assertEquals(zonedDateTime.getZone(), ZoneId.of("UTC")); + } +} From 5b76e4eace44067de30037f13c82f9c5218fb38e Mon Sep 17 00:00:00 2001 From: Mo Helmy <135069400+BenHelmyBen@users.noreply.github.com> Date: Thu, 18 Jan 2024 22:27:04 +0200 Subject: [PATCH 025/132] This PR is related to BAEL-7174 (#15681) * This PR is related to BAEL-7174 This PR aims to add a new test class "CheckIfStringContainsInvalidEncodedCharactersUnitTest". * Update CheckIfStringContainsInvalidEncodedCharactersUnitTest.java Updating if-else with ternary operator --- ...tainsInvalidEncodedCharactersUnitTest.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/checkifstringcontainsinvalidcharacters/CheckIfStringContainsInvalidEncodedCharactersUnitTest.java diff --git a/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/checkifstringcontainsinvalidcharacters/CheckIfStringContainsInvalidEncodedCharactersUnitTest.java b/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/checkifstringcontainsinvalidcharacters/CheckIfStringContainsInvalidEncodedCharactersUnitTest.java new file mode 100644 index 0000000000..ffa7f54dd3 --- /dev/null +++ b/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/checkifstringcontainsinvalidcharacters/CheckIfStringContainsInvalidEncodedCharactersUnitTest.java @@ -0,0 +1,33 @@ +package com.baeldung.checkifstringcontainsinvalidcharacters; + +import org.junit.jupiter.api.Test; + +import java.nio.charset.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class CheckIfStringContainsInvalidEncodedCharactersUnitTest { + + public String input = "HÆllo, World!"; + + @Test + public void givenInputString_whenUsingRegexPattern_thenFindIfInvalidCharacters() { + String regexPattern = "[^\\x00-\\x7F]+"; + Pattern pattern = Pattern.compile(regexPattern); + Matcher matcher = pattern.matcher(input); + assertTrue(matcher.find() ? true : false); + } + + @Test + public void givenInputString_whenUsingStringEncoding_thenFindIfInvalidCharacters() { + byte[] bytes = input.getBytes(StandardCharsets.UTF_8); + boolean found = false; + for (byte b : bytes) { + found = (b & 0xFF) > 127 ? true : found; + } + assertTrue(found ? true : false); + } +} From e72e72790c8599124406f95bcdeff98e045900df Mon Sep 17 00:00:00 2001 From: Maiklins Date: Thu, 18 Jan 2024 22:19:34 +0100 Subject: [PATCH 026/132] Update README.md --- core-java-modules/core-java-numbers-conversions/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-numbers-conversions/README.md b/core-java-modules/core-java-numbers-conversions/README.md index b5f02a9d47..99326360e4 100644 --- a/core-java-modules/core-java-numbers-conversions/README.md +++ b/core-java-modules/core-java-numbers-conversions/README.md @@ -6,3 +6,4 @@ - [Converting from float to BigDecimal in Java](https://www.baeldung.com/java-convert-float-bigdecimal) - [Convert Positive Integer to Negative and Vice Versa in Java](https://www.baeldung.com/java-negating-integer) - [Rounding Up a Number to Nearest Multiple of 5 in Java](https://www.baeldung.com/java-round-nearest-multiple-five) +- [Convert byte to int Type in Java](https://www.baeldung.com/java-byte-to-int-conversion) From 82d2112665378ae956f173bc8e2eb827f388ec7e Mon Sep 17 00:00:00 2001 From: Rajat Garg Date: Fri, 19 Jan 2024 06:07:35 +0530 Subject: [PATCH 027/132] Add code for rotating a vertex around certain point (#15683) Co-authored-by: rajatgarg --- .../math/rotatevertex/VertexRotation.java | 26 ++++++++++++++++ .../rotatevertex/VertexRotationUnitTest.java | 31 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/rotatevertex/VertexRotation.java create mode 100644 core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/rotatevertex/VertexRotationUnitTest.java diff --git a/core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/rotatevertex/VertexRotation.java b/core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/rotatevertex/VertexRotation.java new file mode 100644 index 0000000000..b8ec6a9065 --- /dev/null +++ b/core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/rotatevertex/VertexRotation.java @@ -0,0 +1,26 @@ +package com.baeldung.math.rotatevertex; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; + +public class VertexRotation { + public static Point2D.Double usingOriginAsRotationPoint(Point2D.Double vertex, Point2D.Double rotationPoint, double angle) { + double translatedToOriginX = vertex.x - rotationPoint.x; + double translatedToOriginY = vertex.y - rotationPoint.y; + + double rotatedX = translatedToOriginX * Math.cos(angle) - translatedToOriginY * Math.sin(angle); + double rotatedY = translatedToOriginX * Math.sin(angle) + translatedToOriginY * Math.cos(angle); + + double reverseTranslatedX = rotatedX + rotationPoint.x; + double reverseTranslatedY = rotatedY + rotationPoint.y; + + return new Point2D.Double(reverseTranslatedX, reverseTranslatedY); + } + + public static Point2D.Double usingAffineTransform(Point2D.Double vertex, Point2D.Double rotationPoint, double angle) { + AffineTransform affineTransform = AffineTransform.getRotateInstance(angle, rotationPoint.x, rotationPoint.y); + Point2D.Double rotatedVertex = new Point2D.Double(); + affineTransform.transform(vertex, rotatedVertex); + return rotatedVertex; + } +} diff --git a/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/rotatevertex/VertexRotationUnitTest.java b/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/rotatevertex/VertexRotationUnitTest.java new file mode 100644 index 0000000000..50b1aaf196 --- /dev/null +++ b/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/rotatevertex/VertexRotationUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.math.rotatevertex; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.awt.geom.Point2D; + +import org.junit.jupiter.api.Test; + +public class VertexRotationUnitTest { + @Test + void givenRotationPoint_whenUseOrigin_thenRotateVertex() { + Point2D.Double vertex = new Point2D.Double(2.0, 2.0); + Point2D.Double rotationPoint = new Point2D.Double(0.0, 1.0); + double angle = Math.toRadians(45.0); + Point2D.Double rotatedVertex = VertexRotation.usingOriginAsRotationPoint(vertex, rotationPoint, angle); + + assertEquals(0.707, rotatedVertex.getX(), 0.001); + assertEquals(3.121, rotatedVertex.getY(), 0.001); + } + + @Test + void givenRotationPoint_whenUseAffineTransform_thenRotateVertex() { + Point2D.Double vertex = new Point2D.Double(2.0, 2.0); + Point2D.Double rotationPoint = new Point2D.Double(0.0, 1.0); + double angle = Math.toRadians(45.0); + Point2D.Double rotatedVertex = VertexRotation.usingAffineTransform(vertex, rotationPoint, angle); + + assertEquals(0.707, rotatedVertex.getX(), 0.001); + assertEquals(3.121, rotatedVertex.getY(), 0.001); + } +} From 9014d3007b449cc1005e409f932dea5fbed953f4 Mon Sep 17 00:00:00 2001 From: Roger <587230+rojyates@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:41:46 +1000 Subject: [PATCH 028/132] Bael 7312 spock data pipes (#15684) * BAEL-7312 Add source for tests backing Spock Data Pipes article. * BAEL-7312 Add source for tests backing Spock Data Pipes article. * BAEL-7312 Delete non-compliant code --- testing-modules/groovy-spock/pom.xml | 1 + .../baeldung/spock/data/DataPipesSubject.java | 13 + .../spock/data/DataPipesUnitTest.groovy | 265 ++++++++++++++++++ 3 files changed, 279 insertions(+) create mode 100644 testing-modules/groovy-spock/src/main/java/com/baeldung/spock/data/DataPipesSubject.java create mode 100644 testing-modules/groovy-spock/src/test/groovy/com/baeldung/spock/data/DataPipesUnitTest.groovy diff --git a/testing-modules/groovy-spock/pom.xml b/testing-modules/groovy-spock/pom.xml index 7920713810..3e0ad45612 100644 --- a/testing-modules/groovy-spock/pom.xml +++ b/testing-modules/groovy-spock/pom.xml @@ -69,6 +69,7 @@ src/test/groovy **/*Specification.groovy + **/*Spec.groovy **/*Test.groovy diff --git a/testing-modules/groovy-spock/src/main/java/com/baeldung/spock/data/DataPipesSubject.java b/testing-modules/groovy-spock/src/main/java/com/baeldung/spock/data/DataPipesSubject.java new file mode 100644 index 0000000000..9d689a8347 --- /dev/null +++ b/testing-modules/groovy-spock/src/main/java/com/baeldung/spock/data/DataPipesSubject.java @@ -0,0 +1,13 @@ +package com.baeldung.spock.data; +public class DataPipesSubject { + long addWithATwist(final long first, final long second) { + if (first == 42 || second == 42) { + return 42; + } + return first + second; + } + + String addExclamation(final String first) { + return first + '!'; + } +} diff --git a/testing-modules/groovy-spock/src/test/groovy/com/baeldung/spock/data/DataPipesUnitTest.groovy b/testing-modules/groovy-spock/src/test/groovy/com/baeldung/spock/data/DataPipesUnitTest.groovy new file mode 100644 index 0000000000..1a1e3c0873 --- /dev/null +++ b/testing-modules/groovy-spock/src/test/groovy/com/baeldung/spock/data/DataPipesUnitTest.groovy @@ -0,0 +1,265 @@ +package com.baeldung.spock.data + +import spock.lang.Shared +import spock.lang.Specification +import spock.lang.Subject +import spock.lang.Title + +@Title("Test various ways of using data pipes") +class DataPipesUnitTest extends Specification { + + @Subject + def dataPipesSubject = new DataPipesSubject() + + def "given two numbers when we add them then our result is the sum of the inputs"() { + given: "some inputs" + def first = 1 + def second = 2 + + and: "an expected expectedResult" + def expectedResult = 3 + + when: "we add them together" + def result = dataPipesSubject.addWithATwist(first, second) + + then: "we get our expected answer" + result == expectedResult + } + + + def "given a where clause with our inputs when we add them then our result is the sum of the inputs"() { + when: "we add our inputs together" + def result = dataPipesSubject.addWithATwist(first, second) + + then: "we get our expected answer" + result == expectedResult + + where: "we have various inputs" + first = 1 + second = 2 + expectedResult = 3 + } + + + def "given an expect block to simplify our test when we add our inputs then our result is the sum of the two numbers"() { + expect: "our addition to get the right result" + dataPipesSubject.addWithATwist(first, second) == expectedResult + + where: "we have various inputs" + first = 1 + second = 2 + expectedResult = 3 + } + + + def "given some declared method parameters when we add our inputs then those types are used"(int first, int second, int expectedResult) { + expect: "our addition to get the right result" + dataPipesSubject.addWithATwist(first, second) == expectedResult + + where: "we have various inputs" + first = 1 + second = 2 + expectedResult = 3 + } + + + def "given data pipes when we add our inputs then our inputs are supplied from the data pipes"() { + expect: "our addition to get the right result" + dataPipesSubject.addWithATwist(first, second) == expectedResult + + where: "we have various inputs" + first << [1] + second << [2] + expectedResult << [3] + } + + + def "given two numbers from a combined data pipe, #first and #second, when we add our inputs then the result is matches the value from our expectedResult data pipe: #expectedResult"() { + expect: "our addition to get the right result" + dataPipesSubject.addWithATwist(first, second) == expectedResult + + where: "we have various inputs" + [first, second] << [ + [1, 2], + [2, 2], + [3, 5] + ] + + and: "an expected expectedResult" + expectedResult << [3, 4, 8] + } + + + def "given two numbers from a combined data pipe, #first and #second, when we add our inputs then our test runs for each set of numbers"() { + expect: "our addition to get the right result" + dataPipesSubject.addWithATwist(first, second) == expectedResult + + where: "we have various inputs" + [first, second] << [ + [1, 2], + [2, 2], + [3, 5] + ] + + and: "an expected expectedResult" + expectedResult = first + second + } + + + def "given multiple scenarios in our data pipes when we add our inputs then our test runs for each set of numbers"() { + expect: "our addition to get the right result" + dataPipesSubject.addWithATwist(first, second) == expectedResult + + where: "we have various inputs" + first << [1, 2, 3] + second << [2, 2, 5] + expectedResult << [3, 4, 8] + } + + + def "given a combined data feed when we add our numbers then our test runs for each set of numbers, #first and #second"() { + expect: "our addition to get the right result" + dataPipesSubject.addWithATwist(first, second) == expectedResult + + where: "we have various inputs" + [first, second, expectedResult] << [ + [1, 2, 3], + [2, 2, 4], + [3, 5, 8] + ] + } + + + def "given a map with our data when we add our inputs from a map then our test runs for each set of numbers, #first and #second"() { + expect: "our addition to get the right result" + dataPipesSubject.addWithATwist(first, second) == expectedResult + + where: "we have various inputs in the form of a map" + [first, second, expectedResult] << [ + [ + first : 1, + second : 2, + expectedResult: 3 + ], + [ + first : 2, + second : 2, + expectedResult: 4 + ] + ] + } + + + def "given a method to supply our data when we add our inputs then our test runs for each set of numbers, #first and #second"() { + expect: "our addition to get the right result" + dataPipesSubject.addWithATwist(first, second) == expectedResult + + where: "we have various inputs in the form of a map" + [first, second, expectedResult] << dataFeed() + } + + def dataFeed() { + [ + [ + first : 1, + second : 2, + expectedResult: 3 + ], + [ + first : 2, + second : 2, + expectedResult: 4 + ] + ] + } + + + def "given a table to supply our data when we add our inputs then our test runs for each set of numbers, #first and #second"() { + expect: "our addition to get the right result" + dataPipesSubject.addWithATwist(first, second) == expectedResult + + where: "we have various inputs" + first | second || expectedResult + 1 | 2 || 3 + 2 | 2 || 4 + 3 | 5 || 8 + } + + + def "given a semi-colon as table separator when we add our inputs then our test runs for each set of numbers, #first and #second"() { + expect: "our addition to get the right result" + dataPipesSubject.addWithATwist(first, second) == expectedResult + + where: "we have various inputs" + first; second; expectedResult + 1; 2; 3 + 2; 2; 4 + 3; 5; 8 + // Since IDE Code formatting doesn't understand Spock's use of ';' separator + // and inserts an extra space between ';;' it breaks the table syntax, + // so, to avoid this formatting issue we've just used a single ';' separator between inputs and outputs + // instead of our preferred double ';;' + } + + + def "given a larger table split into two tables when we add our inputs then our test runs for each set of numbers, #first and #second\"() {"() { + expect: "our addition to get the right result" + dataPipesSubject.addWithATwist(first, second) == expectedResult + + where: "we have various inputs" + first | second + 1 | 2 + 2 | 2 + 3 | 5 + __ + expectedResult | _ + 3 | _ + 4 | _ + 8 | _ + } + + + def "given some additional scenarios when we add our inputs then our code coverage increases"() { + expect: "our addition to get the right result" + dataPipesSubject.addWithATwist(first, second) == expectedResult + + where: "we have various inputs" + first | second || expectedResult + 1 | 2 || 3 + 2 | 2 || 4 + 3 | 5 || 8 + 42 | 10 || 42 + 1 | 42 || 42 + } + + static def STATIC_VARIABLE = 'When we have a very long string we can use a static variable' + @Shared + def SHARED_VARIABLE = 'When we have a very long string we can annotate our variable with @Shared' + + def "given long strings when our tables our too big then we can use shared or static variables to shorten the table"() { + expect: "our addition to get the right result" + dataPipesSubject.addExclamation(longString) == expectedResult + + where: "we have various inputs" + longString || expectedResult + 'When we have a very long string we can use a static or @Shared variable to make our tables easier to read' || 'When we have a very long string we can use a static or @Shared variable to make our tables easier to read!' + STATIC_VARIABLE || "$STATIC_VARIABLE!" + SHARED_VARIABLE || "$SHARED_VARIABLE!" + } + + + def "given a #scenario case when we add our inputs, #first and #second, then we get our expected result: #expectedResult"() { + expect: "our addition to get the right result" + dataPipesSubject.addWithATwist(first, second) == expectedResult + + where: "we have various inputs" + scenario | first | second || expectedResult + "simple" | 1 | 2 || 3 + "double 2" | 2 | 2 || 4 + "double 2 referenced" | 2 | first || first + second + "three plus eight" | 3 | 5 || 8 + "first special" | 42 | 10 || 42 + "second special" | 1 | 42 || 42 + } + +} From 7f1cb82f850bf508e7feda6dd03fda4b5867f84a Mon Sep 17 00:00:00 2001 From: Eugene Kovko <37694937+eukovko@users.noreply.github.com> Date: Fri, 19 Jan 2024 01:43:24 +0100 Subject: [PATCH 029/132] BAEL 7436: Updated improvement (#15674) --- .../java/com/baeldung/nullconversion/Delivery.java | 3 +++ .../OnePersonDeliveryServiceUnitTest.java | 10 +--------- .../com/baeldung/nullconversion/PersonProvider.java | 8 ++++---- .../service/MockOnePersonDeliveryServiceBase.java | 6 +++--- .../service/OnePersonExplicitDeliveryService.java | 2 +- .../service/OnePersonGuavaOptionalDeliveryService.java | 2 +- .../service/OnePersonOptionalDeliveryService.java | 2 +- 7 files changed, 14 insertions(+), 19 deletions(-) diff --git a/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/nullconversion/Delivery.java b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/nullconversion/Delivery.java index 3c584d9566..7f18cfd9bc 100644 --- a/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/nullconversion/Delivery.java +++ b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/nullconversion/Delivery.java @@ -32,4 +32,7 @@ public class Delivery { public static Delivery freeDelivery() { return new Delivery("Free delivery"); } + public static Delivery defaultDelivery() { + return new Delivery("Default delivery"); + } } diff --git a/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/OnePersonDeliveryServiceUnitTest.java b/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/OnePersonDeliveryServiceUnitTest.java index 01cd658bd1..304458b213 100644 --- a/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/OnePersonDeliveryServiceUnitTest.java +++ b/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/OnePersonDeliveryServiceUnitTest.java @@ -7,6 +7,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import com.baeldung.nullconversion.service.OnePersonExplicitDeliveryService; import com.baeldung.nullconversion.service.OnePersonGuavaOptionalDeliveryService; import com.baeldung.nullconversion.service.OnePersonOptionalDeliveryService; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ArgumentsSource; @@ -27,13 +28,4 @@ class OnePersonDeliveryServiceUnitTest { Delivery actual = deliveryService.calculateDeliveryForPerson(1L); assertThat(actual).isEqualTo(expected); } - - @ParameterizedTest - @ArgumentsSource(NullReturningPersonChainProvider.class) - void givenMockDeliverServiceWhenNullValuesThenGuavaOptionalServiceThrowsException(Person person) { - DeliveryService deliveryService = new OnePersonGuavaOptionalDeliveryService(person); - assertThatExceptionOfType(NullPointerException.class) - .isThrownBy(() -> deliveryService.calculateDeliveryForPerson(1L)); - - } } \ No newline at end of file diff --git a/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/PersonProvider.java b/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/PersonProvider.java index d31d9d8ec4..301e859fe7 100644 --- a/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/PersonProvider.java +++ b/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/PersonProvider.java @@ -18,10 +18,10 @@ public class PersonProvider implements ArgumentsProvider { return Stream.of( Arguments.of(person, Delivery.freeDelivery()), - Arguments.of(cloneAndMutate(person, p -> p.getAddress().getZipCode().setCode("")), null), - Arguments.of(cloneAndMutate(person, p -> p.getAddress().setZipCode(null)), null), - Arguments.of(cloneAndMutate(person, p -> p.setAddress(null)), null), - Arguments.of(null, null) + Arguments.of(cloneAndMutate(person, p -> p.getAddress().getZipCode().setCode("")), Delivery.defaultDelivery()), + Arguments.of(cloneAndMutate(person, p -> p.getAddress().setZipCode(null)), Delivery.defaultDelivery()), + Arguments.of(cloneAndMutate(person, p -> p.setAddress(null)), Delivery.defaultDelivery()), + Arguments.of(null, Delivery.defaultDelivery()) ); } diff --git a/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/service/MockOnePersonDeliveryServiceBase.java b/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/service/MockOnePersonDeliveryServiceBase.java index 973f8bce97..1080f69d97 100644 --- a/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/service/MockOnePersonDeliveryServiceBase.java +++ b/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/service/MockOnePersonDeliveryServiceBase.java @@ -23,7 +23,7 @@ public abstract class MockOnePersonDeliveryServiceBase implements DeliveryServic String code = zipCode.getCode(); return calculateDeliveryForZipCode(code); } - return null; + return Delivery.defaultDelivery(); } public Delivery calculateDeliveryForPersonWithOptional(Long id) { @@ -32,7 +32,7 @@ public abstract class MockOnePersonDeliveryServiceBase implements DeliveryServic .map(Address::getZipCode) .map(ZipCode::getCode) .map(this::calculateDeliveryForZipCode) - .orElse(null); + .orElse(Delivery.defaultDelivery()); } protected Person getPersonById(Long id) { @@ -41,7 +41,7 @@ public abstract class MockOnePersonDeliveryServiceBase implements DeliveryServic protected Delivery calculateDeliveryForZipCode(String zipCode) { if (zipCode == null || zipCode.isEmpty()) { - return null; + return Delivery.defaultDelivery(); } else { return Delivery.freeDelivery(); } diff --git a/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/service/OnePersonExplicitDeliveryService.java b/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/service/OnePersonExplicitDeliveryService.java index 652d0a002b..7d81d3cf51 100644 --- a/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/service/OnePersonExplicitDeliveryService.java +++ b/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/service/OnePersonExplicitDeliveryService.java @@ -19,6 +19,6 @@ public class OnePersonExplicitDeliveryService extends MockOnePersonDeliveryServi String code = zipCode.getCode(); return calculateDeliveryForZipCode(code); } - return null; + return Delivery.defaultDelivery(); } } diff --git a/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/service/OnePersonGuavaOptionalDeliveryService.java b/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/service/OnePersonGuavaOptionalDeliveryService.java index 29d42789a0..f495576e87 100644 --- a/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/service/OnePersonGuavaOptionalDeliveryService.java +++ b/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/service/OnePersonGuavaOptionalDeliveryService.java @@ -20,7 +20,7 @@ public class OnePersonGuavaOptionalDeliveryService extends MockOnePersonDelivery .transform(Address::getZipCode) .transform(ZipCode::getCode) .transform(this::calculateDeliveryForZipCode) - .orNull(); + .or(Delivery.defaultDelivery()); } } diff --git a/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/service/OnePersonOptionalDeliveryService.java b/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/service/OnePersonOptionalDeliveryService.java index 586f0009ea..1a7ab5d870 100644 --- a/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/service/OnePersonOptionalDeliveryService.java +++ b/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/nullconversion/service/OnePersonOptionalDeliveryService.java @@ -20,7 +20,7 @@ public class OnePersonOptionalDeliveryService extends MockOnePersonDeliveryServi .map(Address::getZipCode) .map(ZipCode::getCode) .map(this::calculateDeliveryForZipCode) - .orElse(null); + .orElse(Delivery.defaultDelivery()); } } From 96e4a42e2820598591fea510bcd7d3ca8595358e Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 09:39:10 +0800 Subject: [PATCH 030/132] Update README.md --- persistence-modules/hibernate-exceptions/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/hibernate-exceptions/README.md b/persistence-modules/hibernate-exceptions/README.md index 0225d3a753..bc635bc31e 100644 --- a/persistence-modules/hibernate-exceptions/README.md +++ b/persistence-modules/hibernate-exceptions/README.md @@ -7,3 +7,4 @@ - [EntityNotFoundException in Hibernate](https://www.baeldung.com/hibernate-entitynotfoundexception) - [Hibernate’s “Not-Null Property References a Null or Transient Value” Error](https://www.baeldung.com/hibernate-not-null-error) - [Hibernate’s “Detached Entity Passed to Persist” Error](https://www.baeldung.com/hibernate-detached-entity-passed-to-persist) +- [Fixing Hibernate QueryException: Named Parameter Not Bound](https://www.baeldung.com/hibernate-queryexception-named-parameter-not-bound-fix) From 30b1f2cc0c018122ba2ab54718669b932c7a18fb Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 09:40:56 +0800 Subject: [PATCH 031/132] Update README.md --- spring-boot-modules/spring-boot-properties-4/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot-modules/spring-boot-properties-4/README.md b/spring-boot-modules/spring-boot-properties-4/README.md index 3033b8725c..ffff3ac236 100644 --- a/spring-boot-modules/spring-boot-properties-4/README.md +++ b/spring-boot-modules/spring-boot-properties-4/README.md @@ -7,4 +7,5 @@ - [Using Environment Variables in Spring Boot’s Properties Files](https://www.baeldung.com/spring-boot-properties-env-variables) - [Spring Boot Properties Prefix Must Be in Canonical Form](https://www.baeldung.com/spring-boot-properties-canonical-form) +- [Bind Case Insensitive @Value to Enum in Spring Boot](https://www.baeldung.com/spring-boot-enum-bind-case-insensitive-value) - More articles: [[<-- Prev]](../spring-boot-properties-3) From 36d34de0b604984277ea9de5744b35434620d2b1 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 09:46:40 +0800 Subject: [PATCH 032/132] Update README.md --- persistence-modules/spring-data-jpa-repo-4/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/spring-data-jpa-repo-4/README.md b/persistence-modules/spring-data-jpa-repo-4/README.md index a8afbbe733..0df332a109 100644 --- a/persistence-modules/spring-data-jpa-repo-4/README.md +++ b/persistence-modules/spring-data-jpa-repo-4/README.md @@ -4,4 +4,5 @@ - [Unidirectional One-to-Many and Cascading Delete in JPA](https://www.baeldung.com/spring-jpa-unidirectional-one-to-many-and-cascading-delete) - [TRUNCATE TABLE in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-truncate-table) +- [When to Use the getReferenceById() and findById() Methods in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-getreferencebyid-findbyid-methods) - More articles: [[<-- prev]](../spring-data-jpa-repo-3) From a70ae5f8ac13543d9fc21d1e5e93657f809d5114 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 09:48:27 +0800 Subject: [PATCH 033/132] Update README.md --- core-java-modules/core-java-lang-6/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-lang-6/README.md b/core-java-modules/core-java-lang-6/README.md index 214409dd04..3e28d58094 100644 --- a/core-java-modules/core-java-lang-6/README.md +++ b/core-java-modules/core-java-lang-6/README.md @@ -10,4 +10,5 @@ This module contains articles about core features in the Java language - [Stop Executing Further Code in Java](https://www.baeldung.com/java-stop-running-code) - [Using the Apache Commons Lang 3 for Comparing Objects in Java](https://www.baeldung.com/java-apache-commons-lang-3-compare-objects) - [Return First Non-null Value in Java](https://www.baeldung.com/java-first-non-null) +- [Compress and Uncompress Byte Array Using Deflater/Inflater](https://www.baeldung.com/java-compress-uncompress-byte-array) - [Static Final Variables in Java](https://www.baeldung.com/java-static-final-variables) From f1ea7001d89cdc90f6ccd46fa40a4d1919a3a489 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 09:49:41 +0800 Subject: [PATCH 034/132] Update README.md --- core-java-modules/core-java-string-algorithms-4/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-string-algorithms-4/README.md b/core-java-modules/core-java-string-algorithms-4/README.md index 19eac0a38c..4ce76f8c6e 100644 --- a/core-java-modules/core-java-string-algorithms-4/README.md +++ b/core-java-modules/core-java-string-algorithms-4/README.md @@ -4,3 +4,4 @@ This module contains articles about string-related algorithms. ### Relevant Articles: - [Rotating a Java String By n Characters](https://www.baeldung.com/java-rotate-string-by-n-characters) +- [Remove Characters From a String That Are in the Other String](https://www.baeldung.com/java-strings-character-difference) From 655e30949c7f699cf6cc12f0c43dddd58412e57f Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 09:52:02 +0800 Subject: [PATCH 035/132] Update README.md --- apache-kafka-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/apache-kafka-2/README.md b/apache-kafka-2/README.md index 3aa8fcf4ad..bc3a8885bf 100644 --- a/apache-kafka-2/README.md +++ b/apache-kafka-2/README.md @@ -15,3 +15,4 @@ You can build the project from the command line using: *mvn clean install*, or i - [bootstrap-server in Kafka Configuration](https://www.baeldung.com/java-kafka-bootstrap-server) - [Introduction to Apache Kafka](https://www.baeldung.com/apache-kafka) - [Ensuring Message Ordering in Kafka: Strategies and Configurations](https://www.baeldung.com/kafka-message-ordering) +- [Read Multiple Messages with Apache Kafka](https://www.baeldung.com/kafka-read-multiple-messages) From 11f5e0e768f914d385ffd7025793a6cbb8b4077f Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 09:53:03 +0800 Subject: [PATCH 036/132] Update README.md --- spring-boot-modules/spring-boot-data-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot-modules/spring-boot-data-3/README.md b/spring-boot-modules/spring-boot-data-3/README.md index 7130d25118..94516a506c 100644 --- a/spring-boot-modules/spring-boot-data-3/README.md +++ b/spring-boot-modules/spring-boot-data-3/README.md @@ -2,3 +2,4 @@ - [Spring Data JPA – Run an App Without a Database](https://www.baeldung.com/spring-data-jpa-run-app-without-db) - [Integrate AWS Secrets Manager in Spring Boot](https://www.baeldung.com/spring-boot-integrate-aws-secrets-manager) - [Fix Spring Data JPA Exception: No Property Found for Type](https://www.baeldung.com/spring-data-jpa-exception-no-property-found-for-type) +- [Remove Null Objects in JSON Response When Using Spring and Jackson](https://www.baeldung.com/spring-remove-null-objects-json-response-jackson) From 7b2ecb977a8cab44da48fbfea1b4a8cd118c7dc9 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 09:54:05 +0800 Subject: [PATCH 037/132] Update README.md --- algorithms-modules/algorithms-miscellaneous-7/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/algorithms-modules/algorithms-miscellaneous-7/README.md b/algorithms-modules/algorithms-miscellaneous-7/README.md index 87a1ee15ec..ac761c3db6 100644 --- a/algorithms-modules/algorithms-miscellaneous-7/README.md +++ b/algorithms-modules/algorithms-miscellaneous-7/README.md @@ -5,4 +5,5 @@ - [Getting Pixel Array From Image in Java](https://www.baeldung.com/java-getting-pixel-array-from-image) - [Calculate Distance Between Two Coordinates in Java](https://www.baeldung.com/java-find-distance-between-points) - [Rotate Arrays in Java](https://www.baeldung.com/java-rotate-arrays) +- [Find Missing Number From a Given Array in Java](https://www.baeldung.com/java-array-find-missing-number) - More articles: [[<-- prev]](/algorithms-miscellaneous-6) From 2292469842bb7c372a94c63a0d15e8a870dcda3f Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 09:55:18 +0800 Subject: [PATCH 038/132] Update README.md --- spring-kafka/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-kafka/README.md b/spring-kafka/README.md index 49b19ed448..97f459f534 100644 --- a/spring-kafka/README.md +++ b/spring-kafka/README.md @@ -11,6 +11,7 @@ This module contains articles about Spring with Kafka - [Configuring Kafka SSL Using Spring Boot](https://www.baeldung.com/spring-boot-kafka-ssl) - [Kafka Streams With Spring Boot](https://www.baeldung.com/spring-boot-kafka-streams) - [Get the Number of Messages in an Apache Kafka Topic](https://www.baeldung.com/java-kafka-count-topic-messages) +- [Sending Data to a Specific Partition in Kafka](https://www.baeldung.com/kafka-send-data-partition) ### Intro From 2703827ea90f8cd6d7e488eb637e770b869c35ec Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 09:56:47 +0800 Subject: [PATCH 039/132] Update README.md --- core-java-modules/core-java-string-operations-7/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-string-operations-7/README.md b/core-java-modules/core-java-string-operations-7/README.md index a0460f26d2..186c217656 100644 --- a/core-java-modules/core-java-string-operations-7/README.md +++ b/core-java-modules/core-java-string-operations-7/README.md @@ -7,3 +7,4 @@ - [Check if a String Contains a Number Value in Java](https://www.baeldung.com/java-string-number-presence) - [Difference Between String isEmpty() and isBlank()](https://www.baeldung.com/java-string-isempty-vs-isblank) - [String’s Maximum Length in Java](https://www.baeldung.com/java-strings-maximum-length) +- [Java’s String.length() and String.getBytes().length](https://www.baeldung.com/java-string-length-vs-getbytes-length) From c7bd604f51e1c25a70efbd243ef9972e21412e8b Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 09:58:22 +0800 Subject: [PATCH 040/132] Update README.md --- core-java-modules/core-java-string-conversions-3/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-string-conversions-3/README.md b/core-java-modules/core-java-string-conversions-3/README.md index ea328c208f..144773b7c3 100644 --- a/core-java-modules/core-java-string-conversions-3/README.md +++ b/core-java-modules/core-java-string-conversions-3/README.md @@ -5,4 +5,4 @@ - [Split Java String Into Key-Value Pairs](https://www.baeldung.com/java-split-string-map) - [How to Center Text Output in Java](https://www.baeldung.com/java-center-text-output) - [How to Convert an Object to String](https://www.baeldung.com/java-object-string-representation) -- [Convert String to long or Long in Java](https://www.baeldung.com/java-convert-string-to-long) +- [Convert String to long or Long in Java](https://www.baeldung.com/java-convert-string-long) From bfa76d7e66481ecde18fee23756ffb8b2ae429cf Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 09:59:55 +0800 Subject: [PATCH 041/132] Update README.md --- core-java-modules/core-java-numbers-conversions/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-numbers-conversions/README.md b/core-java-modules/core-java-numbers-conversions/README.md index 99326360e4..e2031f0ee1 100644 --- a/core-java-modules/core-java-numbers-conversions/README.md +++ b/core-java-modules/core-java-numbers-conversions/README.md @@ -7,3 +7,4 @@ - [Convert Positive Integer to Negative and Vice Versa in Java](https://www.baeldung.com/java-negating-integer) - [Rounding Up a Number to Nearest Multiple of 5 in Java](https://www.baeldung.com/java-round-nearest-multiple-five) - [Convert byte to int Type in Java](https://www.baeldung.com/java-byte-to-int-conversion) +- [Converting Integer to BigDecimal in Java](https://www.baeldung.com/java-integer-bigdecimal-conversion) From a7e76aaeaa51a5220bfaec722eb9b74938570d22 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:00:55 +0800 Subject: [PATCH 042/132] Update README.md --- core-java-modules/core-java-string-operations-7/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-string-operations-7/README.md b/core-java-modules/core-java-string-operations-7/README.md index 186c217656..e2ab509d8e 100644 --- a/core-java-modules/core-java-string-operations-7/README.md +++ b/core-java-modules/core-java-string-operations-7/README.md @@ -8,3 +8,4 @@ - [Difference Between String isEmpty() and isBlank()](https://www.baeldung.com/java-string-isempty-vs-isblank) - [String’s Maximum Length in Java](https://www.baeldung.com/java-strings-maximum-length) - [Java’s String.length() and String.getBytes().length](https://www.baeldung.com/java-string-length-vs-getbytes-length) +- [Replace Non-Printable Unicode Characters in Java](https://www.baeldung.com/java-replace-non-printable-unicode-characters) From 3b2efb2ed2fdea26fef6b0b18d52a92845101233 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:08:39 +0800 Subject: [PATCH 043/132] Update README.md --- core-java-modules/core-java-concurrency-basic-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-concurrency-basic-2/README.md b/core-java-modules/core-java-concurrency-basic-2/README.md index 91b84e3749..6d0b708644 100644 --- a/core-java-modules/core-java-concurrency-basic-2/README.md +++ b/core-java-modules/core-java-concurrency-basic-2/README.md @@ -12,4 +12,5 @@ This module contains articles about basic Java concurrency - [How to Get the Number of Threads in a Java Process](https://www.baeldung.com/java-get-number-of-threads) - [Set the Name of a Thread in Java](https://www.baeldung.com/java-set-thread-name) - [Thread vs. Single Thread Executor Service](https://www.baeldung.com/java-single-thread-executor-service) +- [Difference Between a Future and a Promise in Java](https://www.baeldung.com/java-future-vs-promise-comparison) - [[<-- Prev]](../core-java-concurrency-basic)[[Next -->]](../core-java-concurrency-basic-3) From 37c73560d60d0890712aded615ea1a0693bd9acf Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:09:36 +0800 Subject: [PATCH 044/132] Update README.md --- persistence-modules/spring-data-jpa-repo-4/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/spring-data-jpa-repo-4/README.md b/persistence-modules/spring-data-jpa-repo-4/README.md index 0df332a109..f0cfdedab0 100644 --- a/persistence-modules/spring-data-jpa-repo-4/README.md +++ b/persistence-modules/spring-data-jpa-repo-4/README.md @@ -5,4 +5,5 @@ - [Unidirectional One-to-Many and Cascading Delete in JPA](https://www.baeldung.com/spring-jpa-unidirectional-one-to-many-and-cascading-delete) - [TRUNCATE TABLE in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-truncate-table) - [When to Use the getReferenceById() and findById() Methods in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-getreferencebyid-findbyid-methods) +- [Implementing Persistable-Only Entities in Spring Data JPA](https://www.baeldung.com/spring-data-persistable-only-entities) - More articles: [[<-- prev]](../spring-data-jpa-repo-3) From cb2a5ee50021b5d30e88408fbf5722d09dcfa35c Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:10:35 +0800 Subject: [PATCH 045/132] Update README.md --- web-modules/jakarta-ee/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/web-modules/jakarta-ee/README.md b/web-modules/jakarta-ee/README.md index 54f372f736..bf4bef93c4 100644 --- a/web-modules/jakarta-ee/README.md +++ b/web-modules/jakarta-ee/README.md @@ -1,3 +1,4 @@ ### Relevant Articles: - [Introduction to Jakarta EE MVC / Eclipse Krazo](https://www.baeldung.com/java-ee-mvc-eclipse-krazo) +- [Get Specific Part From SOAP Message in Java](https://www.baeldung.com/java-soap-msg-specific-part) From 2dd3290bdbf012bae20ad0334366e1efcb5351c8 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:11:51 +0800 Subject: [PATCH 046/132] Update README.md --- core-java-modules/core-java-lang-math-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-lang-math-3/README.md b/core-java-modules/core-java-lang-math-3/README.md index 37027970b6..97d99ad468 100644 --- a/core-java-modules/core-java-lang-math-3/README.md +++ b/core-java-modules/core-java-lang-math-3/README.md @@ -13,4 +13,5 @@ - [Java Money and the Currency API](http://www.baeldung.com/java-money-and-currency) - [Clamp Function in Java](https://www.baeldung.com/java-clamp-function) - [Creating a Magic Square in Java](https://www.baeldung.com/java-magic-square) +- [Check if a Point Is Between Two Points Drawn on a Straight Line in Java](https://www.baeldung.com/java-check-point-straight-line) - More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2) From dc90912c6bb4f3126a2df7d59f8b6a57d4ed5c59 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:13:17 +0800 Subject: [PATCH 047/132] Update README.md --- patterns-modules/design-patterns-behavioral-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/patterns-modules/design-patterns-behavioral-2/README.md b/patterns-modules/design-patterns-behavioral-2/README.md index 2afa7b9eb6..80c8a62728 100644 --- a/patterns-modules/design-patterns-behavioral-2/README.md +++ b/patterns-modules/design-patterns-behavioral-2/README.md @@ -2,3 +2,4 @@ - [Memento Design Pattern in Java](https://www.baeldung.com/java-memento-design-pattern) - [Difference Between Fluent Interface and Builder Pattern in Java](https://www.baeldung.com/java-fluent-interface-vs-builder-pattern) - [Smart Batching in Java](https://www.baeldung.com/java-smart-batching) +- [Convert Null Value to a Default Value in Java](https://www.baeldung.com/java-convert-null-default-value) From 10fc9b0de228d2ff6b6470a72fc0dc448a742714 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:14:37 +0800 Subject: [PATCH 048/132] Update README.md --- core-java-modules/core-java-collections-list-6/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-collections-list-6/README.md b/core-java-modules/core-java-collections-list-6/README.md index fd162743dc..fef2c31c54 100644 --- a/core-java-modules/core-java-collections-list-6/README.md +++ b/core-java-modules/core-java-collections-list-6/README.md @@ -1,2 +1,3 @@ ## Relevant Articles - [Check if a List Contains a String Element While Ignoring Case](https://www.baeldung.com/java-list-search-case-insensitive) +- [Removing the Last Node in a Linked List](https://www.baeldung.com/java-linked-list-remove-last-element) From 81f72be32901a82a15ce364301689e81389b8bcb Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:15:48 +0800 Subject: [PATCH 049/132] Update README.md --- core-java-modules/core-java-collections-5/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-collections-5/README.md b/core-java-modules/core-java-collections-5/README.md index c9fce58ac2..a3f4371ca5 100644 --- a/core-java-modules/core-java-collections-5/README.md +++ b/core-java-modules/core-java-collections-5/README.md @@ -11,4 +11,5 @@ - [Intro to Vector Class in Java](https://www.baeldung.com/java-vector-guide) - [HashSet toArray() Method in Java](https://www.baeldung.com/java-hashset-toarray) - [Time Complexity of Java Collections Sort in Java](https://www.baeldung.com/java-time-complexity-collections-sort) +- [Check if List Contains at Least One Enum](https://www.baeldung.com/java-list-check-enum-presence) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-4) From 258a0bce53bc54b13fda450be490ee26d82e19c1 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:17:24 +0800 Subject: [PATCH 050/132] Update README.md --- core-java-modules/core-java-io-apis-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-io-apis-2/README.md b/core-java-modules/core-java-io-apis-2/README.md index 043e0c1ee3..7fbd3fd197 100644 --- a/core-java-modules/core-java-io-apis-2/README.md +++ b/core-java-modules/core-java-io-apis-2/README.md @@ -9,3 +9,4 @@ This module contains articles about core Java input/output(IO) APIs. - [Converting Relative to Absolute Paths in Java](https://www.baeldung.com/java-from-relative-to-absolute-paths) - [Detect EOF in Java](https://www.baeldung.com/java-file-detect-end-of-file) - [PrintWriter vs. FileWriter in Java](https://www.baeldung.com/java-printwriter-filewriter-difference) +- [Read Input Character-by-Character in Java](https://www.baeldung.com/java-read-input-character) From eadcceb0938280a7db2b6a41f8e54793c1dcd362 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:18:31 +0800 Subject: [PATCH 051/132] Update README.md --- core-java-modules/core-java-io-apis-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-io-apis-2/README.md b/core-java-modules/core-java-io-apis-2/README.md index 7fbd3fd197..29666826a8 100644 --- a/core-java-modules/core-java-io-apis-2/README.md +++ b/core-java-modules/core-java-io-apis-2/README.md @@ -10,3 +10,4 @@ This module contains articles about core Java input/output(IO) APIs. - [Detect EOF in Java](https://www.baeldung.com/java-file-detect-end-of-file) - [PrintWriter vs. FileWriter in Java](https://www.baeldung.com/java-printwriter-filewriter-difference) - [Read Input Character-by-Character in Java](https://www.baeldung.com/java-read-input-character) +- [Difference Between flush() and close() in Java FileWriter](https://www.baeldung.com/java-filewriter-flush-vs-close) From 47d5fd11cbbd1c00228db57c75e6160c456b73ab Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:19:44 +0800 Subject: [PATCH 052/132] Update README.md --- core-java-modules/core-java-lang-6/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-lang-6/README.md b/core-java-modules/core-java-lang-6/README.md index 3e28d58094..6343f38e91 100644 --- a/core-java-modules/core-java-lang-6/README.md +++ b/core-java-modules/core-java-lang-6/README.md @@ -12,3 +12,4 @@ This module contains articles about core features in the Java language - [Return First Non-null Value in Java](https://www.baeldung.com/java-first-non-null) - [Compress and Uncompress Byte Array Using Deflater/Inflater](https://www.baeldung.com/java-compress-uncompress-byte-array) - [Static Final Variables in Java](https://www.baeldung.com/java-static-final-variables) +- [What Is the Error: “Non-static method cannot be referenced from a static context”?](https://www.baeldung.com/java-non-static-method-cannot-be-referenced-from-a-static-context) From 03da03f115a41a4cb108b51963daa9ea610c653d Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:20:41 +0800 Subject: [PATCH 053/132] Update README.md --- core-java-modules/core-java-security-4/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-security-4/README.md b/core-java-modules/core-java-security-4/README.md index 3c910e50be..8f5ee308bd 100644 --- a/core-java-modules/core-java-security-4/README.md +++ b/core-java-modules/core-java-security-4/README.md @@ -6,4 +6,5 @@ This module contains articles about core Java Security - [Check if Certificate Is Self-Signed or CA-Signed With Java](https://www.baeldung.com/java-check-certificate-sign) - [Extract CN From X509 Certificate in Java](https://www.baeldung.com/java-extract-common-name-x509-certificate) - [Check Certificate Name and Alias in Keystore File](https://www.baeldung.com/java-keystore-check-certificate-name-alias) +- [Using a Custom TrustStore in Java](https://www.baeldung.com/java-custom-truststore) - More articles: [[<-- prev]](/core-java-modules/core-java-security-3) From 3c07d26ab02614ca2b242d8c8e5a826037ced6e1 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:27:19 +0800 Subject: [PATCH 054/132] Update README.md --- core-java-modules/core-java-datetime-conversion/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-datetime-conversion/README.md b/core-java-modules/core-java-datetime-conversion/README.md index f30a21f84c..ecb9298da1 100644 --- a/core-java-modules/core-java-datetime-conversion/README.md +++ b/core-java-modules/core-java-datetime-conversion/README.md @@ -12,3 +12,4 @@ This module contains articles about converting between Java date and time object - [Convert Epoch Time to LocalDate and LocalDateTime](https://www.baeldung.com/java-convert-epoch-localdate) - [Convert Timestamp String to Long in Java](https://www.baeldung.com/java-convert-timestamp-string-long) - [Convert Long Timestamp to LocalDateTime in Java](https://www.baeldung.com/java-convert-long-timestamp-localdatetime) +- [Convert Joda-Time DateTime to Date and Vice Versa](https://www.baeldung.com/java-convert-joda-time-datetime-to-date) From 258db28a1ee2029073e098d2d71ff9c71591f28f Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:31:03 +0800 Subject: [PATCH 055/132] Update README.md --- core-java-modules/core-java-collections-list-6/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-collections-list-6/README.md b/core-java-modules/core-java-collections-list-6/README.md index fef2c31c54..c9e4bb7ecd 100644 --- a/core-java-modules/core-java-collections-list-6/README.md +++ b/core-java-modules/core-java-collections-list-6/README.md @@ -1,3 +1,4 @@ ## Relevant Articles - [Check if a List Contains a String Element While Ignoring Case](https://www.baeldung.com/java-list-search-case-insensitive) - [Removing the Last Node in a Linked List](https://www.baeldung.com/java-linked-list-remove-last-element) +- [Call a Method on Each Element of a List in Java](https://www.baeldung.com/java-call-method-each-list-item) From 05e5e82299ef3daf80286fcac3a6138faa568ce0 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:48:43 +0800 Subject: [PATCH 056/132] Update README.md --- persistence-modules/spring-data-jpa-query-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/spring-data-jpa-query-3/README.md b/persistence-modules/spring-data-jpa-query-3/README.md index 8b094e66b2..a10bdadd60 100644 --- a/persistence-modules/spring-data-jpa-query-3/README.md +++ b/persistence-modules/spring-data-jpa-query-3/README.md @@ -8,6 +8,7 @@ This module contains articles about querying data using Spring Data JPA. - [Joining Tables With Spring Data JPA Specifications](https://www.baeldung.com/spring-jpa-joining-tables) - [NonUniqueResultException in Spring Data JPA](https://www.baeldung.com/spring-jpa-non-unique-result-exception) - [Spring Data Repositories – Collections vs. Stream](https://www.baeldung.com/spring-data-collections-vs-stream) +- [Return Map Instead of List in Spring Data JPA](https://www.baeldung.com/spring-data-return-map-instead-of-list) - [Converting List to Page Using Spring Data JPA](https://www.baeldung.com/spring-data-jpa-convert-list-page) - More articles: [[<-- prev]](../spring-data-jpa-query-2) From 29b839f0ec54ddc6853cdb1541edafac802bce84 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:50:03 +0800 Subject: [PATCH 057/132] Update README.md --- spring-web-modules/spring-rest-http-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-web-modules/spring-rest-http-3/README.md b/spring-web-modules/spring-rest-http-3/README.md index a5b3d51e93..fe4cfaa269 100644 --- a/spring-web-modules/spring-rest-http-3/README.md +++ b/spring-web-modules/spring-rest-http-3/README.md @@ -7,4 +7,5 @@ The "REST With Spring 3" Classes: http://bit.ly/restwithspring ### Relevant Articles: - [Send Array as Part of x-www-form-urlencoded Using Postman](https://www.baeldung.com/java-postman-send-array) +- [Using XML in @RequestBody in Spring REST](https://www.baeldung.com/spring-xml-requestbody) - More articles: [[<-- prev]](../spring-rest-http) From 36c612926590f75f01e94e8b33865a79a0259aef Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:51:56 +0800 Subject: [PATCH 058/132] Update README.md --- spring-kafka-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-kafka-2/README.md b/spring-kafka-2/README.md index 250927314c..f9e07d4893 100644 --- a/spring-kafka-2/README.md +++ b/spring-kafka-2/README.md @@ -10,3 +10,4 @@ This module contains articles about Spring with Kafka - [How to Subscribe a Kafka Consumer to Multiple Topics](https://www.baeldung.com/kafka-subscribe-consumer-multiple-topics) - [Splitting Streams in Kafka](https://www.baeldung.com/kafka-splitting-streams) - [Manage Kafka Consumer Groups](https://www.baeldung.com/kafka-manage-consumer-groups) +- [Dead Letter Queue for Kafka With Spring](https://www.baeldung.com/kafka-spring-dead-letter-queue) From cc79f440156020ee8b77b90d4d0ffc0a62ee353a Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:53:59 +0800 Subject: [PATCH 059/132] Update README.md --- core-java-modules/core-java-time-measurements/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-time-measurements/README.md b/core-java-modules/core-java-time-measurements/README.md index a3e8b71ae8..2bdc9f059e 100644 --- a/core-java-modules/core-java-time-measurements/README.md +++ b/core-java-modules/core-java-time-measurements/README.md @@ -7,3 +7,4 @@ This module contains articles about the measurement of time in Java. - [Measure Elapsed Time in Java](http://www.baeldung.com/java-measure-elapsed-time) - [Overriding System Time for Testing in Java](https://www.baeldung.com/java-override-system-time) - [Java Timer](http://www.baeldung.com/java-timer-and-timertask) +- [Java System.currentTimeMillis() Vs. System.nanoTime()](https://www.baeldung.com/java-system-currenttimemillis-vs-system-nanotime) From 26ff2dd0f80d3c816af1bbaf055a8d65ddfe53f0 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:56:52 +0800 Subject: [PATCH 060/132] Update README.md --- core-java-modules/core-java-lang-oop-generics/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-lang-oop-generics/README.md b/core-java-modules/core-java-lang-oop-generics/README.md index 3e33ba5315..f230208851 100644 --- a/core-java-modules/core-java-lang-oop-generics/README.md +++ b/core-java-modules/core-java-lang-oop-generics/README.md @@ -10,3 +10,4 @@ This module contains articles about generics in Java - [Java Warning “unchecked conversion”](https://www.baeldung.com/java-unchecked-conversion) - [Java Warning “Unchecked Cast”](https://www.baeldung.com/java-warning-unchecked-cast) - [What Does the Holder Class Do in Java?](https://www.baeldung.com/java-holder-class) +- [Determine the Class of a Generic Type in Java](https://www.baeldung.com/java-generic-type-find-class-runtime) From 305b8bc8955bb5ff2c5ac2711466f2475796019f Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:58:16 +0800 Subject: [PATCH 061/132] Update README.md --- persistence-modules/spring-data-jpa-query-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/spring-data-jpa-query-3/README.md b/persistence-modules/spring-data-jpa-query-3/README.md index a10bdadd60..99032138a6 100644 --- a/persistence-modules/spring-data-jpa-query-3/README.md +++ b/persistence-modules/spring-data-jpa-query-3/README.md @@ -10,6 +10,7 @@ This module contains articles about querying data using Spring Data JPA. - [Spring Data Repositories – Collections vs. Stream](https://www.baeldung.com/spring-data-collections-vs-stream) - [Return Map Instead of List in Spring Data JPA](https://www.baeldung.com/spring-data-return-map-instead-of-list) - [Converting List to Page Using Spring Data JPA](https://www.baeldung.com/spring-data-jpa-convert-list-page) +- [@Query Definitions With SpEL Support in Spring Data JPA](https://www.baeldung.com/spring-data-query-definitions-spel) - More articles: [[<-- prev]](../spring-data-jpa-query-2) ### Eclipse Config From f19b0df6e5be33af72d57a9548cb3639e78d5c81 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 11:00:18 +0800 Subject: [PATCH 062/132] Update README.md --- core-java-modules/core-java-string-operations-7/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-string-operations-7/README.md b/core-java-modules/core-java-string-operations-7/README.md index e2ab509d8e..7a15163c4a 100644 --- a/core-java-modules/core-java-string-operations-7/README.md +++ b/core-java-modules/core-java-string-operations-7/README.md @@ -9,3 +9,4 @@ - [String’s Maximum Length in Java](https://www.baeldung.com/java-strings-maximum-length) - [Java’s String.length() and String.getBytes().length](https://www.baeldung.com/java-string-length-vs-getbytes-length) - [Replace Non-Printable Unicode Characters in Java](https://www.baeldung.com/java-replace-non-printable-unicode-characters) +- [Check If a Java StringBuilder Object Contains a Character](https://www.baeldung.com/java-check-stringbuilder-object-contains-character) From 4fcc885c257a83308a84fbe01c06ef88d4dd740d Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 11:02:57 +0800 Subject: [PATCH 063/132] Update README.md --- core-java-modules/core-java-collections-list-6/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-collections-list-6/README.md b/core-java-modules/core-java-collections-list-6/README.md index c9e4bb7ecd..30ae5eb2dd 100644 --- a/core-java-modules/core-java-collections-list-6/README.md +++ b/core-java-modules/core-java-collections-list-6/README.md @@ -2,3 +2,4 @@ - [Check if a List Contains a String Element While Ignoring Case](https://www.baeldung.com/java-list-search-case-insensitive) - [Removing the Last Node in a Linked List](https://www.baeldung.com/java-linked-list-remove-last-element) - [Call a Method on Each Element of a List in Java](https://www.baeldung.com/java-call-method-each-list-item) +- [Sorting One List Based on Another List in Java](https://www.baeldung.com/java-sorting-one-list-using-another) From 2b3a28f13cd4beaf2bcef367a64f5fbd7c201f4e Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 11:04:21 +0800 Subject: [PATCH 064/132] Update README.md --- web-modules/javax-servlets-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/web-modules/javax-servlets-2/README.md b/web-modules/javax-servlets-2/README.md index 179264f90a..17420e8fd8 100644 --- a/web-modules/javax-servlets-2/README.md +++ b/web-modules/javax-servlets-2/README.md @@ -6,3 +6,4 @@ This module contains articles about Servlets. - [Check if a User Is Logged-in With Servlets and JSP](https://www.baeldung.com/servlets-jsp-check-user-login) - [How to Mock HttpServletRequest](https://www.baeldung.com/java-httpservletrequest-mock) - [Set a Parameter in an HttpServletRequest in Java](https://www.baeldung.com/java-servlet-request-set-parameter) +- [Get Client Information From HTTP Request in Java](https://www.baeldung.com/java-http-request-client-info) From d77d4012fe6d844dd40265eb7ac4e02f259ac0b0 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 11:07:00 +0800 Subject: [PATCH 065/132] Update README.md --- core-java-modules/core-java-numbers-7/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-numbers-7/README.md b/core-java-modules/core-java-numbers-7/README.md index 42a43fd1fd..af5334eea6 100644 --- a/core-java-modules/core-java-numbers-7/README.md +++ b/core-java-modules/core-java-numbers-7/README.md @@ -1,2 +1,3 @@ ## Relevant Articles - [Check if a double Is an Integer in Java](https://www.baeldung.com/java-check-double-integer) +- [Print a Double Value Without Scientific Notation in Java](https://www.baeldung.com/java-print-double-number-no-scientific-notation) From 12ec2874df474c22dfb64e770f10bc8d7a5c65d3 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 11:08:33 +0800 Subject: [PATCH 066/132] Update README.md --- core-java-modules/core-java-concurrency-basic-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-concurrency-basic-3/README.md b/core-java-modules/core-java-concurrency-basic-3/README.md index 1021544e11..823c5cea8d 100644 --- a/core-java-modules/core-java-concurrency-basic-3/README.md +++ b/core-java-modules/core-java-concurrency-basic-3/README.md @@ -13,4 +13,5 @@ This module contains articles about basic Java concurrency. - [Retry Logic with CompletableFuture](https://www.baeldung.com/java-completablefuture-retry-logic) - [Convert From List of CompletableFuture to CompletableFuture List](https://www.baeldung.com/java-completablefuture-list-convert) - [Synchronize a Static Variable Among Different Threads](https://www.baeldung.com/java-synchronize-static-variable-different-threads) +- [Difference Between execute() and submit() in Executor Service](https://www.baeldung.com/java-execute-vs-submit-executor-service) - [[<-- Prev]](../core-java-concurrency-basic-2) From 1ab7993a3828ebd865926dd111596b3a73116851 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 11:09:58 +0800 Subject: [PATCH 067/132] Update README.md --- core-java-modules/core-java-string-operations-7/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-string-operations-7/README.md b/core-java-modules/core-java-string-operations-7/README.md index 7a15163c4a..de45ee0cec 100644 --- a/core-java-modules/core-java-string-operations-7/README.md +++ b/core-java-modules/core-java-string-operations-7/README.md @@ -10,3 +10,4 @@ - [Java’s String.length() and String.getBytes().length](https://www.baeldung.com/java-string-length-vs-getbytes-length) - [Replace Non-Printable Unicode Characters in Java](https://www.baeldung.com/java-replace-non-printable-unicode-characters) - [Check If a Java StringBuilder Object Contains a Character](https://www.baeldung.com/java-check-stringbuilder-object-contains-character) +- [UTF-8 Validation in Java](https://www.baeldung.com/java-utf-8-validation) From 8eb237ad732593c9576f7f81d7ddc7d9895ed02a Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 11:11:31 +0800 Subject: [PATCH 068/132] Update README.md --- core-java-modules/core-java-sun/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-sun/README.md b/core-java-modules/core-java-sun/README.md index 82977bca6c..83bf34bb8a 100644 --- a/core-java-modules/core-java-sun/README.md +++ b/core-java-modules/core-java-sun/README.md @@ -8,3 +8,4 @@ This module contains articles about the sun package - [Guide to sun.misc.Unsafe](http://www.baeldung.com/java-unsafe) - [Why Is sun.misc.Unsafe.park Actually Unsafe?](https://www.baeldung.com/java-sun-misc-unsafe-park-reason) - [Sharing Memory Between JVMs](https://www.baeldung.com/java-sharing-memory-between-jvms) +- [Parse Java Source Code and Extract Methods](https://www.baeldung.com/java-parse-code-extract-methods) From 87b2779371d26edb89c6c0c4b4c439e514b1b81b Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 11:12:28 +0800 Subject: [PATCH 069/132] Update README.md --- core-java-modules/core-java-io-5/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-io-5/README.md b/core-java-modules/core-java-io-5/README.md index 4578cf3777..141d840498 100644 --- a/core-java-modules/core-java-io-5/README.md +++ b/core-java-modules/core-java-io-5/README.md @@ -6,5 +6,6 @@ This module contains articles about core Java input and output (IO) - [Get File Extension From MIME Type in Java](https://www.baeldung.com/java-mime-type-file-extension) - [How to Remove Line Breaks From a File in Java](https://www.baeldung.com/java-file-remove-line-breaks) - [Difference Between ZipFile and ZipInputStream in Java](https://www.baeldung.com/java-zipfile-vs-zipinputstream) +- [How to Write Strings to OutputStream in Java](https://www.baeldung.com/java-write-string-outputstream) - [[<-- Prev]](/core-java-modules/core-java-io-4) From c43d14ca7d9280e949f47297e9c8c8ff6ac027b2 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 11:13:27 +0800 Subject: [PATCH 070/132] Update README.md --- core-java-modules/core-java-collections-5/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-collections-5/README.md b/core-java-modules/core-java-collections-5/README.md index a3f4371ca5..cf731e8f09 100644 --- a/core-java-modules/core-java-collections-5/README.md +++ b/core-java-modules/core-java-collections-5/README.md @@ -12,4 +12,5 @@ - [HashSet toArray() Method in Java](https://www.baeldung.com/java-hashset-toarray) - [Time Complexity of Java Collections Sort in Java](https://www.baeldung.com/java-time-complexity-collections-sort) - [Check if List Contains at Least One Enum](https://www.baeldung.com/java-list-check-enum-presence) +- [Comparison of for Loops and Iterators](https://www.baeldung.com/java-for-loops-vs-iterators) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-4) From a0e8ad086029728340ea2e0b60cca210a2310918 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 11:14:37 +0800 Subject: [PATCH 071/132] Update README.md --- json-modules/json-conversion/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/json-modules/json-conversion/README.md b/json-modules/json-conversion/README.md index a0cf0f6246..a1851d9b7a 100644 --- a/json-modules/json-conversion/README.md +++ b/json-modules/json-conversion/README.md @@ -5,3 +5,4 @@ This module contains articles about JSON Conversions ### Relevant Articles: - [Convert JSON Array to Java List](https://www.baeldung.com/java-convert-json-array-to-list) - [Reading JSON Documents as Maps and Comparing Them](https://www.baeldung.com/java-json-maps-comparison) +- [Convert Byte Array to JSON and Vice Versa in Java](https://www.baeldung.com/java-json-byte-array-conversion) From 8efca6014e19a75b4e26141b5c27c16f5b89a090 Mon Sep 17 00:00:00 2001 From: rcalago <149600319+rcalago@users.noreply.github.com> Date: Fri, 19 Jan 2024 11:17:06 +0800 Subject: [PATCH 072/132] Update README.md --- core-java-modules/core-java-8-datetime-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-8-datetime-2/README.md b/core-java-modules/core-java-8-datetime-2/README.md index 6fe450816e..799e5f6a49 100644 --- a/core-java-modules/core-java-8-datetime-2/README.md +++ b/core-java-modules/core-java-8-datetime-2/README.md @@ -9,4 +9,5 @@ - [Round the Date in Java](https://www.baeldung.com/java-round-the-date) - [Representing Furthest Possible Date in Java](https://www.baeldung.com/java-date-represent-max) - [Retrieving Unix Time in Java](https://www.baeldung.com/java-retrieve-unix-time) +- [Calculate Months Between Two Dates in Java](https://www.baeldung.com/java-months-difference-two-dates) - [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1) From cebe2cbb62f20e7e03683a61586dce3cbf483a7a Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Fri, 19 Jan 2024 19:25:21 +0530 Subject: [PATCH 073/132] JAVA-29069 Add not-fixed comment for spring-data-cassandra for JDK17 (#15676) --- persistence-modules/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index bb7c01984f..4b7a5522da 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -69,7 +69,7 @@ spring-boot-persistence-mongodb-2 spring-boot-persistence-mongodb-3 spring-data-arangodb - + spring-data-cassandra-test spring-data-cosmosdb spring-data-couchbase-2 From 1cb6e41c85d3e006177aa313ac6bc9591634cbe9 Mon Sep 17 00:00:00 2001 From: parthiv39731 <70740707+parthiv39731@users.noreply.github.com> Date: Fri, 19 Jan 2024 23:57:04 +0530 Subject: [PATCH 074/132] BAEL-7388, Builder Pattern and Inheritance --- .../builder/inheritance/withgenerics/Car.java | 42 ++++++++++++++ .../inheritance/withgenerics/ElectricCar.java | 28 ++++++++++ .../inheritance/withgenerics/Vehicle.java | 44 +++++++++++++++ .../inheritance/withoutgenerics/Car.java | 53 ++++++++++++++++++ .../inheritance/withoutgenerics/Vehicle.java | 41 ++++++++++++++ .../src/main/resources/builder-pattern.puml | 56 +++++++++++++++++++ .../BuilderInheritanceUnitTest.java | 19 +++++++ .../BuilderInheritanceUnitTest.java | 36 ++++++++++++ 8 files changed, 319 insertions(+) create mode 100644 patterns-modules/design-patterns-creational-2/src/main/java/com/baeldung/builder/inheritance/withgenerics/Car.java create mode 100644 patterns-modules/design-patterns-creational-2/src/main/java/com/baeldung/builder/inheritance/withgenerics/ElectricCar.java create mode 100644 patterns-modules/design-patterns-creational-2/src/main/java/com/baeldung/builder/inheritance/withgenerics/Vehicle.java create mode 100644 patterns-modules/design-patterns-creational-2/src/main/java/com/baeldung/builder/inheritance/withoutgenerics/Car.java create mode 100644 patterns-modules/design-patterns-creational-2/src/main/java/com/baeldung/builder/inheritance/withoutgenerics/Vehicle.java create mode 100644 patterns-modules/design-patterns-creational-2/src/main/resources/builder-pattern.puml create mode 100644 patterns-modules/design-patterns-creational-2/src/test/java/com/baeldung/builder/inheritance/withoutgenerics/BuilderInheritanceUnitTest.java create mode 100644 patterns-modules/design-patterns-creational-2/src/test/java/com/baledung/builder/inheritance/withgenerics/BuilderInheritanceUnitTest.java diff --git a/patterns-modules/design-patterns-creational-2/src/main/java/com/baeldung/builder/inheritance/withgenerics/Car.java b/patterns-modules/design-patterns-creational-2/src/main/java/com/baeldung/builder/inheritance/withgenerics/Car.java new file mode 100644 index 0000000000..c80f5dcd07 --- /dev/null +++ b/patterns-modules/design-patterns-creational-2/src/main/java/com/baeldung/builder/inheritance/withgenerics/Car.java @@ -0,0 +1,42 @@ +package com.baeldung.builder.inheritance.withgenerics; + +public class Car extends Vehicle { + + private String make; + private String model; + + public String getModel() { + return model; + } + + public Car(Builder builder) { + super(builder); + this.make = builder.make; + this.model = builder.model; + } + + public String getMake() { + return make; + } + + public static class Builder> extends Vehicle.Builder { + + protected String make; + protected String model; + + public T make(String make) { + this.make = make; + return self(); + } + + public T model(String model) { + this.model = model; + return self(); + } + + @Override + public Car build() { + return new Car(this); + } + } +} diff --git a/patterns-modules/design-patterns-creational-2/src/main/java/com/baeldung/builder/inheritance/withgenerics/ElectricCar.java b/patterns-modules/design-patterns-creational-2/src/main/java/com/baeldung/builder/inheritance/withgenerics/ElectricCar.java new file mode 100644 index 0000000000..2b22cf27c7 --- /dev/null +++ b/patterns-modules/design-patterns-creational-2/src/main/java/com/baeldung/builder/inheritance/withgenerics/ElectricCar.java @@ -0,0 +1,28 @@ +package com.baeldung.builder.inheritance.withgenerics; + +public class ElectricCar extends Car { + private String batteryType; + + public String getBatteryType() { + return batteryType; + } + + public ElectricCar(Builder builder) { + super(builder); + this.batteryType = builder.batteryType; + } + + public static class Builder> extends Car.Builder { + protected String batteryType; + + public T batteryType(String batteryType) { + this.batteryType = batteryType; + return self(); + } + + @Override + public ElectricCar build() { + return new ElectricCar(this); + } + } +} diff --git a/patterns-modules/design-patterns-creational-2/src/main/java/com/baeldung/builder/inheritance/withgenerics/Vehicle.java b/patterns-modules/design-patterns-creational-2/src/main/java/com/baeldung/builder/inheritance/withgenerics/Vehicle.java new file mode 100644 index 0000000000..c530e042fb --- /dev/null +++ b/patterns-modules/design-patterns-creational-2/src/main/java/com/baeldung/builder/inheritance/withgenerics/Vehicle.java @@ -0,0 +1,44 @@ +package com.baeldung.builder.inheritance.withgenerics; + +public class Vehicle { + + private String colour; + private String fuelType; + + public Vehicle(Builder builder) { + this.colour = builder.colour; + this.fuelType = builder.fuelType; + } + + public String getColour() { + return colour; + } + + public String getFuelType() { + return fuelType; + } + + public static class Builder { + + protected String colour; + protected String fuelType; + + T self() { + return (T) this; + } + + public T colour(String colour) { + this.colour = colour; + return self(); + } + + public T fuelType(String fuelType) { + this.fuelType = fuelType; + return self(); + } + + public Vehicle build() { + return new Vehicle(this); + } + } +} diff --git a/patterns-modules/design-patterns-creational-2/src/main/java/com/baeldung/builder/inheritance/withoutgenerics/Car.java b/patterns-modules/design-patterns-creational-2/src/main/java/com/baeldung/builder/inheritance/withoutgenerics/Car.java new file mode 100644 index 0000000000..bde5d63e07 --- /dev/null +++ b/patterns-modules/design-patterns-creational-2/src/main/java/com/baeldung/builder/inheritance/withoutgenerics/Car.java @@ -0,0 +1,53 @@ +package com.baeldung.builder.inheritance.withoutgenerics; + +public class Car extends Vehicle { + + private String make; + private String model; + + public String getMake() { + return make; + } + + public String getModel() { + return model; + } + + public Car(CarBuilder builder) { + super(builder); + this.make = builder.make; + this.model = builder.model; + } + + public static class CarBuilder extends VehicleBuilder { + + protected String make; + protected String model; + + @Override + public CarBuilder colour(String colour) { + this.colour = colour; + return this; + } + + @Override + public CarBuilder fuelType(String fuelType) { + this.fuelType = fuelType; + return this; + } + + public CarBuilder make(String make) { + this.make = make; + return this; + } + + public CarBuilder model(String model) { + this.model = model; + return this; + } + + public Car build() { + return new Car(this); + } + } +} diff --git a/patterns-modules/design-patterns-creational-2/src/main/java/com/baeldung/builder/inheritance/withoutgenerics/Vehicle.java b/patterns-modules/design-patterns-creational-2/src/main/java/com/baeldung/builder/inheritance/withoutgenerics/Vehicle.java new file mode 100644 index 0000000000..c0bcd8641b --- /dev/null +++ b/patterns-modules/design-patterns-creational-2/src/main/java/com/baeldung/builder/inheritance/withoutgenerics/Vehicle.java @@ -0,0 +1,41 @@ +package com.baeldung.builder.inheritance.withoutgenerics; + +public class Vehicle { + + private String fuelType; + private String colour; + + public String getFuelType() { + return fuelType; + } + + public String getColour() { + return colour; + } + + public Vehicle(VehicleBuilder builder) { + this.colour = builder.colour; + this.fuelType = builder.fuelType; + + } + + public static class VehicleBuilder { + + protected String fuelType; + protected String colour; + + public VehicleBuilder fuelType(String fuelType) { + this.fuelType = fuelType; + return this; + } + + public VehicleBuilder colour(String colour) { + this.colour = colour; + return this; + } + + public Vehicle build() { + return new Vehicle(this); + } + } +} diff --git a/patterns-modules/design-patterns-creational-2/src/main/resources/builder-pattern.puml b/patterns-modules/design-patterns-creational-2/src/main/resources/builder-pattern.puml new file mode 100644 index 0000000000..dbc9297ede --- /dev/null +++ b/patterns-modules/design-patterns-creational-2/src/main/resources/builder-pattern.puml @@ -0,0 +1,56 @@ +@startuml +'https://plantuml.com/class-diagram +'skinparam Handwritten true +skinparam ClassBorderColor black/#63b175 +skinparam BackgroundColor #fdf8f6 +skinparam class { + ArrowColor #63b175 +} + +hide empty methods +hide empty attributes + +class Vehicle { + +fuelType : String + +colour : String +} + +class VehicleBuilder { + +fuelType : String + +colour : String + +build() : Vehicle + +fuelType(String fuelType) : VehicleBuilder + +colour(String colour) : VehicleBuilder +} +class Car { + +make : String + +model : String +} +class CarBuilder { + +make : String + +model : String + +build() : Car + +make(String make): CarBuilder + +model(String make): CarBuilder +} + +class ElectricCar { + +batteryType : String + +} + +class ElectricCarBuilder { + +batteryType : String + +build() : ElectricCar + +batteryType(String batteryType): ElectricCarBuilder +} +CarBuilder -left-|> VehicleBuilder: extends +ElectricCarBuilder <|-left- CarBuilder: extends +VehicleBuilder -down-> Vehicle: builds +CarBuilder -down-> Car:builds +ElectricCarBuilder -down-> ElectricCar: builds + +Vehicle -right-|> Car: extends +Car <|-right- ElectricCar: extends + +@enduml \ No newline at end of file diff --git a/patterns-modules/design-patterns-creational-2/src/test/java/com/baeldung/builder/inheritance/withoutgenerics/BuilderInheritanceUnitTest.java b/patterns-modules/design-patterns-creational-2/src/test/java/com/baeldung/builder/inheritance/withoutgenerics/BuilderInheritanceUnitTest.java new file mode 100644 index 0000000000..397cc25a01 --- /dev/null +++ b/patterns-modules/design-patterns-creational-2/src/test/java/com/baeldung/builder/inheritance/withoutgenerics/BuilderInheritanceUnitTest.java @@ -0,0 +1,19 @@ +package com.baeldung.builder.inheritance.withoutgenerics; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + +public class BuilderInheritanceUnitTest { + + @Test + void givenNonGenericImpl_whenBuild_thenReturnObject() { + Car car = new Car.CarBuilder().colour("red") + .fuelType("Petrol") + .make("Ford") + .model("F") + .build(); + assertEquals("red", car.getColour()); + assertEquals("Ford", car.getMake()); + } + +} diff --git a/patterns-modules/design-patterns-creational-2/src/test/java/com/baledung/builder/inheritance/withgenerics/BuilderInheritanceUnitTest.java b/patterns-modules/design-patterns-creational-2/src/test/java/com/baledung/builder/inheritance/withgenerics/BuilderInheritanceUnitTest.java new file mode 100644 index 0000000000..d1bc0b1e85 --- /dev/null +++ b/patterns-modules/design-patterns-creational-2/src/test/java/com/baledung/builder/inheritance/withgenerics/BuilderInheritanceUnitTest.java @@ -0,0 +1,36 @@ +package com.baledung.builder.inheritance.withgenerics; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +import com.baeldung.builder.inheritance.withgenerics.Car; +import com.baeldung.builder.inheritance.withgenerics.ElectricCar; + +public class BuilderInheritanceUnitTest { + + @Test + void givenGenericImpl_whenBuild_thenReturnObject() { + Car.Builder carBuilder1 = new Car.Builder(); + Car car = carBuilder1.colour("red") + .fuelType("Petrol") + .make("Ford") + .model("F") + .build(); + + ElectricCar.Builder ElectricCarBuilder = new ElectricCar.Builder(); + ElectricCar eCar = ElectricCarBuilder.make("Mercedes") + .colour("White") + .model("G") + .fuelType("Electric") + .batteryType("Lithium") + .build(); + + assertEquals("red", car.getColour()); + assertEquals("Ford", car.getMake()); + + assertEquals("Electric", eCar.getFuelType()); + assertEquals("Lithium", eCar.getBatteryType()); + } + +} From 1724f67a3934817860b8ee69d61cacd32da4c9ce Mon Sep 17 00:00:00 2001 From: timis1 <12120641+timis1@users.noreply.github.com> Date: Sat, 20 Jan 2024 01:03:25 +0200 Subject: [PATCH 075/132] JAVA-29312 Upgrade spring-security-web-mvc (#15687) Co-authored-by: timis1 --- .../spring-security-web-mvc/.gitignore | 2 +- .../spring-security-web-mvc/pom.xml | 23 +++---- .../clearsitedata/SpringSecurityConfig.java | 24 ++++---- ...SimpleUrlAuthenticationSuccessHandler.java | 10 ++-- .../session/filter/SessionFilter.java | 18 +++--- .../security/config/SecSecurityConfig.java | 60 +++++++++---------- .../baeldung/session/web/FooController.java | 2 +- .../session/web/SessionRestController.java | 2 +- .../web/config/MainWebAppInitializer.java | 5 +- .../session/web/config/MvcConfig.java | 15 ++--- .../web/SessionListenerWithMetrics.java | 4 +- .../templates}/mvc-servlet.xml | 0 .../resources/templates/view/anonymous.html | 9 +++ .../resources/templates/view/console.html | 20 +++++++ .../resources/templates/view/homepage.html | 20 +++++++ .../templates/view/invalidSession.html | 9 +++ .../templates/view/login.html} | 0 .../templates/view/sessionExpired.html | 9 +++ .../WEB-INF => resources/templates}/web.xml | 0 .../main/webapp/WEB-INF/view/anonymous.jsp | 10 ---- .../src/main/webapp/WEB-INF/view/console.jsp | 22 ------- .../src/main/webapp/WEB-INF/view/homepage.jsp | 22 ------- .../webapp/WEB-INF/view/invalidSession.jsp | 10 ---- .../webapp/WEB-INF/view/sessionExpired.jsp | 10 ---- ...LogoutClearSiteDataControllerUnitTest.java | 2 +- .../session/SessionConfigurationLiveTest.java | 6 +- 26 files changed, 153 insertions(+), 161 deletions(-) rename spring-security-modules/spring-security-web-mvc/src/main/{webapp/WEB-INF => resources/templates}/mvc-servlet.xml (100%) create mode 100644 spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/anonymous.html create mode 100644 spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/console.html create mode 100644 spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/homepage.html create mode 100644 spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/invalidSession.html rename spring-security-modules/spring-security-web-mvc/src/main/{webapp/WEB-INF/view/login.jsp => resources/templates/view/login.html} (100%) create mode 100644 spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/sessionExpired.html rename spring-security-modules/spring-security-web-mvc/src/main/{webapp/WEB-INF => resources/templates}/web.xml (100%) delete mode 100644 spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/anonymous.jsp delete mode 100644 spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/console.jsp delete mode 100644 spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/homepage.jsp delete mode 100644 spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/invalidSession.jsp delete mode 100644 spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/sessionExpired.jsp diff --git a/spring-security-modules/spring-security-web-mvc/.gitignore b/spring-security-modules/spring-security-web-mvc/.gitignore index 83c05e60c8..32d2932000 100644 --- a/spring-security-modules/spring-security-web-mvc/.gitignore +++ b/spring-security-modules/spring-security-web-mvc/.gitignore @@ -4,7 +4,7 @@ /target /neoDb* /data -/src/main/webapp/WEB-INF/classes +/src/main/resources/templates/classes */META-INF/* # Packaged files # diff --git a/spring-security-modules/spring-security-web-mvc/pom.xml b/spring-security-modules/spring-security-web-mvc/pom.xml index 10dd89f618..857865267c 100644 --- a/spring-security-modules/spring-security-web-mvc/pom.xml +++ b/spring-security-modules/spring-security-web-mvc/pom.xml @@ -10,7 +10,8 @@ com.baeldung - spring-security-modules + parent-boot-3 + ../../parent-boot-3 0.0.1-SNAPSHOT @@ -38,11 +39,6 @@ org.springframework.boot spring-boot-starter-tomcat - - javax.servlet - jstl - runtime - io.dropwizard.metrics @@ -55,9 +51,16 @@ test - javax.servlet - javax.servlet-api - ${javax.version} + io.rest-assured + rest-assured + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.thymeleaf.extras + thymeleaf-extras-springsecurity6 @@ -67,7 +70,7 @@ org.springframework.boot spring-boot-maven-plugin - com.baeldung.SpringSessionApplication + com.baeldung.session.SpringSessionApplication JAR diff --git a/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/clearsitedata/SpringSecurityConfig.java b/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/clearsitedata/SpringSecurityConfig.java index 9138c6fd7b..225f627434 100644 --- a/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/clearsitedata/SpringSecurityConfig.java +++ b/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/clearsitedata/SpringSecurityConfig.java @@ -1,36 +1,34 @@ package com.baeldung.clearsitedata; - import static org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter.Directive.CACHE; import static org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter.Directive.COOKIES; import static org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter.Directive.STORAGE; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.logout.HeaderWriterLogoutHandler; import org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter; @Configuration @EnableWebSecurity -@EnableGlobalMethodSecurity(prePostEnabled = true) +@EnableMethodSecurity public class SpringSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http.csrf() - .disable() - .formLogin() - .loginPage("/login.html") - .loginProcessingUrl("/perform_login") - .defaultSuccessUrl("/homepage.html", true) - .and() - .logout() - .logoutUrl("/baeldung/logout") - .addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(CACHE, COOKIES, STORAGE))); + http.csrf(AbstractHttpConfigurer::disable) + .formLogin(httpSecurityFormLoginConfigurer -> + httpSecurityFormLoginConfigurer.loginPage("/login") + .loginProcessingUrl("/perform_login") + .defaultSuccessUrl("/homepage", true)) + .logout(httpSecurityLogoutConfigurer -> + httpSecurityLogoutConfigurer.logoutUrl("/baeldung/logout") + .addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(CACHE, COOKIES, STORAGE)))); return http.build(); } } diff --git a/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/security/MySimpleUrlAuthenticationSuccessHandler.java b/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/security/MySimpleUrlAuthenticationSuccessHandler.java index 9d4fc19098..e3e8c54306 100644 --- a/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/security/MySimpleUrlAuthenticationSuccessHandler.java +++ b/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/security/MySimpleUrlAuthenticationSuccessHandler.java @@ -3,9 +3,9 @@ package com.baeldung.security; import java.io.IOException; import java.util.Collection; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -61,9 +61,9 @@ public class MySimpleUrlAuthenticationSuccessHandler implements AuthenticationSu } if (isUser) { - return "/homepage.html"; + return "/homepage"; } else if (isAdmin) { - return "/console.html"; + return "/console"; } else { throw new IllegalStateException(); } diff --git a/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/filter/SessionFilter.java b/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/filter/SessionFilter.java index c30bfa5506..f61e240a05 100644 --- a/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/filter/SessionFilter.java +++ b/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/filter/SessionFilter.java @@ -3,15 +3,15 @@ package com.baeldung.session.filter; import java.io.IOException; import java.util.Arrays; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; public class SessionFilter implements Filter{ diff --git a/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/security/config/SecSecurityConfig.java b/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/security/config/SecSecurityConfig.java index 1dfb72eca9..86cdccfa46 100644 --- a/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/security/config/SecSecurityConfig.java +++ b/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/security/config/SecSecurityConfig.java @@ -3,6 +3,7 @@ package com.baeldung.session.security.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; @@ -11,7 +12,9 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher; import org.springframework.security.web.session.HttpSessionEventPublisher; +import org.springframework.web.servlet.handler.HandlerMappingIntrospector; import com.baeldung.security.MySimpleUrlAuthenticationSuccessHandler; @@ -35,37 +38,28 @@ public class SecSecurityConfig { } @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http.csrf() - .disable() - .authorizeRequests() - .antMatchers("/anonymous*") - .anonymous() - .antMatchers("/login*", "/invalidSession*", "/sessionExpired*", "/foo/**") - .permitAll() - .anyRequest() - .authenticated() - .and() - .formLogin() - .loginPage("/login.html") - .loginProcessingUrl("/login") - .successHandler(successHandler()) - .failureUrl("/login.html?error=true") - .and() - .logout() - .deleteCookies("JSESSIONID") - .and() - .rememberMe() - .key("uniqueAndSecret") - .tokenValiditySeconds(86400) - .and() - .sessionManagement() - .sessionFixation() - .migrateSession() - .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) - .invalidSessionUrl("/invalidSession.html") - .maximumSessions(2) - .expiredUrl("/sessionExpired.html"); + public SecurityFilterChain filterChain(HttpSecurity http, MvcRequestMatcher.Builder mvc) throws Exception { + http.csrf(AbstractHttpConfigurer::disable) + .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> + authorizationManagerRequestMatcherRegistry + .requestMatchers(mvc.pattern("/anonymous*")).anonymous() + .requestMatchers(mvc.pattern("/login*"), mvc.pattern("/invalidSession*"), mvc.pattern("/sessionExpired*"), + mvc.pattern("/foo/**")).permitAll() + .anyRequest().authenticated()) + .formLogin(httpSecurityFormLoginConfigurer -> httpSecurityFormLoginConfigurer.loginPage("/login") + .loginProcessingUrl("/login") + .successHandler(successHandler()) + .failureUrl("/login?error=true")) + .logout(httpSecurityLogoutConfigurer -> httpSecurityLogoutConfigurer.deleteCookies("JSESSIONID")) + .rememberMe(httpSecurityRememberMeConfigurer -> + httpSecurityRememberMeConfigurer.key("uniqueAndSecret") + .tokenValiditySeconds(86400)) + .sessionManagement(httpSecuritySessionManagementConfigurer -> + httpSecuritySessionManagementConfigurer.sessionFixation() + .migrateSession().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) + .invalidSessionUrl("/invalidSession") + .maximumSessions(2) + .expiredUrl("/sessionExpired")); return http.build(); } @@ -83,4 +77,8 @@ public class SecSecurityConfig { return new BCryptPasswordEncoder(); } + @Bean + MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) { + return new MvcRequestMatcher.Builder(introspector); + } } diff --git a/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/web/FooController.java b/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/web/FooController.java index 7c3385dcbd..e8295fc8da 100644 --- a/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/web/FooController.java +++ b/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/web/FooController.java @@ -1,6 +1,6 @@ package com.baeldung.session.web; -import javax.servlet.http.HttpSession; +import jakarta.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; diff --git a/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/web/SessionRestController.java b/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/web/SessionRestController.java index 79f57246a9..1211362d8c 100644 --- a/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/web/SessionRestController.java +++ b/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/web/SessionRestController.java @@ -1,6 +1,6 @@ package com.baeldung.session.web; -import javax.servlet.http.HttpSession; +import jakarta.servlet.http.HttpSession; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; diff --git a/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/web/config/MainWebAppInitializer.java b/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/web/config/MainWebAppInitializer.java index f85f9f3fb0..5c2bbe01ee 100644 --- a/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/web/config/MainWebAppInitializer.java +++ b/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/web/config/MainWebAppInitializer.java @@ -1,14 +1,13 @@ package com.baeldung.session.web.config; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; +import jakarta.servlet.ServletContext; import org.springframework.web.WebApplicationInitializer; public class MainWebAppInitializer implements WebApplicationInitializer { @Override - public void onStartup(ServletContext sc) throws ServletException { + public void onStartup(ServletContext sc) { sc.getSessionCookieConfig().setHttpOnly(true); sc.getSessionCookieConfig().setSecure(true); } diff --git a/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/web/config/MvcConfig.java b/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/web/config/MvcConfig.java index 4db6d07872..885f02798b 100644 --- a/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/web/config/MvcConfig.java +++ b/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/session/web/config/MvcConfig.java @@ -9,13 +9,13 @@ public class MvcConfig implements WebMvcConfigurer { @Override public void addViewControllers(final ViewControllerRegistry registry) { - registry.addViewController("/anonymous.html"); + registry.addViewController("/anonymous").setViewName("view/anonymous"); - registry.addViewController("/login.html"); - registry.addViewController("/homepage.html"); - registry.addViewController("/sessionExpired.html"); - registry.addViewController("/invalidSession.html"); - registry.addViewController("/console.html"); + registry.addViewController("/login").setViewName("view/login"); + registry.addViewController("/homepage").setViewName("view/homepage"); + registry.addViewController("/sessionExpired").setViewName("view/sessionExpired"); + registry.addViewController("/invalidSession").setViewName("view/invalidSession"); + registry.addViewController("/console").setViewName("view/console"); } @@ -27,7 +27,8 @@ public class MvcConfig implements WebMvcConfigurer { // final InternalResourceViewResolver bean = new InternalResourceViewResolver(); // // bean.setViewClass(JstlView.class); -// bean.setPrefix("/WEB-INF/view/"); +// bean.setPrefix("/templates/view/"); // bean.setSuffix(".jsp"); +// return bean; // } } diff --git a/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/web/SessionListenerWithMetrics.java b/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/web/SessionListenerWithMetrics.java index fb1a81744e..10baa1c561 100644 --- a/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/web/SessionListenerWithMetrics.java +++ b/spring-security-modules/spring-security-web-mvc/src/main/java/com/baeldung/web/SessionListenerWithMetrics.java @@ -2,8 +2,8 @@ package com.baeldung.web; import java.util.concurrent.atomic.AtomicInteger; -import javax.servlet.http.HttpSessionEvent; -import javax.servlet.http.HttpSessionListener; +import jakarta.servlet.http.HttpSessionEvent; +import jakarta.servlet.http.HttpSessionListener; import com.baeldung.monitoring.MetricRegistrySingleton; import com.codahale.metrics.Counter; diff --git a/spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/mvc-servlet.xml b/spring-security-modules/spring-security-web-mvc/src/main/resources/templates/mvc-servlet.xml similarity index 100% rename from spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/mvc-servlet.xml rename to spring-security-modules/spring-security-web-mvc/src/main/resources/templates/mvc-servlet.xml diff --git a/spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/anonymous.html b/spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/anonymous.html new file mode 100644 index 0000000000..d8ec862901 --- /dev/null +++ b/spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/anonymous.html @@ -0,0 +1,9 @@ + + + + +

Anonymous page

+ + To Login + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/console.html b/spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/console.html new file mode 100644 index 0000000000..4c15ffc1fe --- /dev/null +++ b/spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/console.html @@ -0,0 +1,20 @@ + + + + +

This is the landing page for the admin

+ +
+ This text is only visible to a user +
+
+ +
+ This text is only visible to an admin +
+
+ + Logout + + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/homepage.html b/spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/homepage.html new file mode 100644 index 0000000000..83a1dff376 --- /dev/null +++ b/spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/homepage.html @@ -0,0 +1,20 @@ + + + + +

This is the homepage for the user

+ +
+ This text is only visible to a user +
+
+ +
+ This text is only visible to an admin +
+
+ + Logout + + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/invalidSession.html b/spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/invalidSession.html new file mode 100644 index 0000000000..06a4761335 --- /dev/null +++ b/spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/invalidSession.html @@ -0,0 +1,9 @@ + + + + +

Invalid Session Page

+ + To Login + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/login.jsp b/spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/login.html similarity index 100% rename from spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/login.jsp rename to spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/login.html diff --git a/spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/sessionExpired.html b/spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/sessionExpired.html new file mode 100644 index 0000000000..94d1286f74 --- /dev/null +++ b/spring-security-modules/spring-security-web-mvc/src/main/resources/templates/view/sessionExpired.html @@ -0,0 +1,9 @@ + + + + +

Session Expired Page

+ + To Login + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/web.xml b/spring-security-modules/spring-security-web-mvc/src/main/resources/templates/web.xml similarity index 100% rename from spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/web.xml rename to spring-security-modules/spring-security-web-mvc/src/main/resources/templates/web.xml diff --git a/spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/anonymous.jsp b/spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/anonymous.jsp deleted file mode 100644 index d4e9c0289b..0000000000 --- a/spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/anonymous.jsp +++ /dev/null @@ -1,10 +0,0 @@ -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> - - - - -

Anonymous page

- - ">To Login - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/console.jsp b/spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/console.jsp deleted file mode 100644 index 5a58d8892f..0000000000 --- a/spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/console.jsp +++ /dev/null @@ -1,22 +0,0 @@ -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> -<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %> - - - - -

This is the landing page for the admin

- - - This text is only visible to a user -
-
- - - This text is only visible to an admin -
-
- - ">Logout - - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/homepage.jsp b/spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/homepage.jsp deleted file mode 100644 index 2568adec66..0000000000 --- a/spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/homepage.jsp +++ /dev/null @@ -1,22 +0,0 @@ -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> -<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags"%> - - - - -

This is the homepage for the user

- - - This text is only visible to a user -
-
- - - This text is only visible to an admin -
-
- - ">Logout - - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/invalidSession.jsp b/spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/invalidSession.jsp deleted file mode 100644 index e8455ee118..0000000000 --- a/spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/invalidSession.jsp +++ /dev/null @@ -1,10 +0,0 @@ -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> - - - - -

Invalid Session Page

- - ">To Login - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/sessionExpired.jsp b/spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/sessionExpired.jsp deleted file mode 100644 index ab0f1c8c63..0000000000 --- a/spring-security-modules/spring-security-web-mvc/src/main/webapp/WEB-INF/view/sessionExpired.jsp +++ /dev/null @@ -1,10 +0,0 @@ -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> - - - - -

Session Expired Page

- - ">To Login - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-mvc/src/test/java/com/baeldung/clearsitedata/LogoutClearSiteDataControllerUnitTest.java b/spring-security-modules/spring-security-web-mvc/src/test/java/com/baeldung/clearsitedata/LogoutClearSiteDataControllerUnitTest.java index 30036eea89..22fdd2351d 100644 --- a/spring-security-modules/spring-security-web-mvc/src/test/java/com/baeldung/clearsitedata/LogoutClearSiteDataControllerUnitTest.java +++ b/spring-security-modules/spring-security-web-mvc/src/test/java/com/baeldung/clearsitedata/LogoutClearSiteDataControllerUnitTest.java @@ -13,7 +13,7 @@ import org.springframework.test.web.servlet.result.MockMvcResultHandlers; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import javax.servlet.Filter; +import jakarta.servlet.Filter; @ExtendWith(SpringExtension.class) @WebAppConfiguration diff --git a/spring-security-modules/spring-security-web-mvc/src/test/java/com/baeldung/session/SessionConfigurationLiveTest.java b/spring-security-modules/spring-security-web-mvc/src/test/java/com/baeldung/session/SessionConfigurationLiveTest.java index 7d9a03d5f6..90342592f8 100644 --- a/spring-security-modules/spring-security-web-mvc/src/test/java/com/baeldung/session/SessionConfigurationLiveTest.java +++ b/spring-security-modules/spring-security-web-mvc/src/test/java/com/baeldung/session/SessionConfigurationLiveTest.java @@ -35,11 +35,11 @@ public class SessionConfigurationLiveTest { Response resp3 = simpleResponseRequestUsingSessionNotFollowingRedirects(sessionFilter); assertThat(resp3.getStatusCode()).isEqualTo(HttpStatus.FOUND.value()); - assertThat(resp3.getHeader("Location")).isEqualTo("http://localhost:8080/invalidSession.html"); + assertThat(resp3.getHeader("Location")).isEqualTo("http://localhost:8080/invalidSession"); } @Test - public void givenValidUser_whenLoginMoreThanMaxValidSession_thenRedirectedToExpiredSessionUri() throws Exception { + public void givenValidUser_whenLoginMoreThanMaxValidSession_thenRedirectedToExpiredSessionUri() { SessionFilter sessionFilter = new SessionFilter(); simpleSvcRequestLoggingIn(sessionFilter); simpleSvcRequestLoggingIn(); @@ -56,7 +56,7 @@ public class SessionConfigurationLiveTest { .get(SESSION_SVC_URL); assertThat(resp4.getStatusCode()).isEqualTo(HttpStatus.FOUND.value()); - assertThat(resp4.getHeader("Location")).isEqualTo("http://localhost:8080/sessionExpired.html"); + assertThat(resp4.getHeader("Location")).isEqualTo("http://localhost:8080/sessionExpired"); } private static void simpleSvcRequestLoggingIn() { From 900ff584fea9d67c9746dbed7e6aeea76d2bfb52 Mon Sep 17 00:00:00 2001 From: Kai Yuan Date: Sat, 20 Jan 2024 16:59:41 +0100 Subject: [PATCH 076/132] [reset-listiterator] reset listiterator (#15645) --- .../ResetListIteratorUnitTest.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 core-java-modules/core-java-collections-list-6/src/test/java/com/baeldung/resetlistiterator/ResetListIteratorUnitTest.java diff --git a/core-java-modules/core-java-collections-list-6/src/test/java/com/baeldung/resetlistiterator/ResetListIteratorUnitTest.java b/core-java-modules/core-java-collections-list-6/src/test/java/com/baeldung/resetlistiterator/ResetListIteratorUnitTest.java new file mode 100644 index 0000000000..2b033e3061 --- /dev/null +++ b/core-java-modules/core-java-collections-list-6/src/test/java/com/baeldung/resetlistiterator/ResetListIteratorUnitTest.java @@ -0,0 +1,46 @@ +package com.baeldung.resetlistiterator; + +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.ListIterator; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +public class ResetListIteratorUnitTest { + + private static final List MY_LIST = List.of("A", "B", "C", "D", "E", "F", "G"); + + @Test + void whenRecreateAnListIterator_thenGetTheExpectedResult() { + ListIterator lit = MY_LIST.listIterator(); + lit.next(); + lit.next(); + lit.next(); + lit.next(); + + lit = MY_LIST.listIterator(); + + assertFalse(lit.hasPrevious()); + assertEquals("A", lit.next()); + } + + @Test + void whenBackwardIterationToTheFirst_thenGetTheExpectedResult() { + ListIterator lit = MY_LIST.listIterator(); + lit.next(); + lit.next(); + lit.next(); + lit.next(); + + + while (lit.hasPrevious()) { + lit.previous(); + } + + assertFalse(lit.hasPrevious()); + assertEquals("A", lit.next()); + } + +} \ No newline at end of file From 238e5fb4731781592a2834c6a8fcc0705b0f0984 Mon Sep 17 00:00:00 2001 From: Bhaskar Ghosh Dastidar Date: Sat, 20 Jan 2024 22:22:42 +0530 Subject: [PATCH 077/132] [BAEL-7323] JFR EXAMPLE (#15650) Co-authored-by: Bhaskar --- .../java/com/baeldung/jfrview/JFRExample.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 core-java-modules/core-java-21/src/main/java/com/baeldung/jfrview/JFRExample.java diff --git a/core-java-modules/core-java-21/src/main/java/com/baeldung/jfrview/JFRExample.java b/core-java-modules/core-java-21/src/main/java/com/baeldung/jfrview/JFRExample.java new file mode 100644 index 0000000000..98eb29fe15 --- /dev/null +++ b/core-java-modules/core-java-21/src/main/java/com/baeldung/jfrview/JFRExample.java @@ -0,0 +1,21 @@ +package com.baeldung.jfrview; + +import java.util.ArrayList; +import java.util.List; + +public class JFRExample { + public static void main(String[] args) { + JFRExample se = new JFRExample(); + se.insertToList(new ArrayList<>()); + } + + private void insertToList(List list) { + try { + while (true) { + list.add(new Object()); + } + } catch (OutOfMemoryError e) { + System.out.println("Out of Memory. Exiting"); + } + } +} From 4021e9861e0ed1549e5e6f3b4e2f7999b68ed942 Mon Sep 17 00:00:00 2001 From: emanueltrandafir1993 Date: Sat, 20 Jan 2024 19:23:38 +0100 Subject: [PATCH 078/132] BAEL-7140: spring modulith evt externalization --- .../spring-boot-libraries-3/README.md | 5 ++ .../spring-boot-libraries-3/pom.xml | 89 +++++++++++++++++++ .../baeldung/springmodulith/Application.java | 13 +++ .../events/externalization/Article.java | 45 ++++++++++ .../ArticlePublishedEvent.java | 7 ++ .../externalization/ArticleRepository.java | 8 ++ .../events/externalization/Baeldung.java | 37 ++++++++ .../EventExternalizationConfig.java | 41 +++++++++ .../infra/ArticlePublishedKafkaProducer.java | 34 +++++++ .../src/main/resources/application.yml | 12 +++ .../EventsExternalizationLiveTest.java | 89 +++++++++++++++++++ .../listener/TestKafkaListenerConfig.java | 31 +++++++ .../listener/TestListener.java | 25 ++++++ 13 files changed, 436 insertions(+) create mode 100644 spring-boot-modules/spring-boot-libraries-3/README.md create mode 100644 spring-boot-modules/spring-boot-libraries-3/pom.xml create mode 100644 spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/Application.java create mode 100644 spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/Article.java create mode 100644 spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/ArticlePublishedEvent.java create mode 100644 spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/ArticleRepository.java create mode 100644 spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/Baeldung.java create mode 100644 spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/EventExternalizationConfig.java create mode 100644 spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/infra/ArticlePublishedKafkaProducer.java create mode 100644 spring-boot-modules/spring-boot-libraries-3/src/main/resources/application.yml create mode 100644 spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/events/externalization/EventsExternalizationLiveTest.java create mode 100644 spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/events/externalization/listener/TestKafkaListenerConfig.java create mode 100644 spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/events/externalization/listener/TestListener.java diff --git a/spring-boot-modules/spring-boot-libraries-3/README.md b/spring-boot-modules/spring-boot-libraries-3/README.md new file mode 100644 index 0000000000..1458e3ef39 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/README.md @@ -0,0 +1,5 @@ +## Spring Boot Libraries + +This module contains articles about various Spring Boot libraries + +### Relevant Articles: \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-3/pom.xml b/spring-boot-modules/spring-boot-libraries-3/pom.xml new file mode 100644 index 0000000000..43d8be84a4 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/pom.xml @@ -0,0 +1,89 @@ + + + 4.0.0 + spring-boot-libraries-3 + + + spring-boot-modules + com.baeldung.spring-boot-modules + 1.0.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.kafka + spring-kafka + + + + org.springframework.modulith + spring-modulith-events-api + ${spring-modulith-events-kafka.version} + + + org.springframework.modulith + spring-modulith-events-kafka + ${spring-modulith-events-kafka.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-testcontainers + test + + + + org.testcontainers + kafka + ${testcontainers.version} + test + + + org.testcontainers + testcontainers + ${testcontainers.version} + test + + + org.testcontainers + junit-jupiter + ${testcontainers.version} + test + + + + com.h2database + h2 + 2.2.224 + test + + + + org.awaitility + awaitility + ${awaitility.version} + test + + + + + + 17 + 3.1.5 + 1.1.2 + 1.19.3 + 4.2.0 + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/Application.java b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/Application.java new file mode 100644 index 0000000000..aeaf57becd --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/Application.java @@ -0,0 +1,13 @@ +package com.baeldung.springmodulith; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run( Application.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/Article.java b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/Article.java new file mode 100644 index 0000000000..d52ed5afe5 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/Article.java @@ -0,0 +1,45 @@ +package com.baeldung.springmodulith.events.externalization; + +import static jakarta.persistence.GenerationType.*; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; + +@Entity +public class Article { + @Id + @GeneratedValue(strategy = AUTO) + private Long id; + + private String slug; + private String title; + private String author; + private String content; + + public Article(String slug, String title, String author, String content) { + this.slug = slug; + this.title = title; + this.author = author; + this.content = content; + } + + public Article() { + } + + public String author() { + return author; + } + + public String content() { + return content; + } + + public String slug() { + return slug; + } + + public String title() { + return title; + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/ArticlePublishedEvent.java b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/ArticlePublishedEvent.java new file mode 100644 index 0000000000..e12b6dafe5 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/ArticlePublishedEvent.java @@ -0,0 +1,7 @@ +package com.baeldung.springmodulith.events.externalization; + +import org.springframework.modulith.events.Externalized; + +@Externalized("baeldung.article.published::#{slug()}") +public record ArticlePublishedEvent(String slug, String title) { +} diff --git a/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/ArticleRepository.java b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/ArticleRepository.java new file mode 100644 index 0000000000..f6351b6262 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/ArticleRepository.java @@ -0,0 +1,8 @@ +package com.baeldung.springmodulith.events.externalization; + +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +interface ArticleRepository extends CrudRepository { +} diff --git a/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/Baeldung.java b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/Baeldung.java new file mode 100644 index 0000000000..1d309a8653 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/Baeldung.java @@ -0,0 +1,37 @@ +package com.baeldung.springmodulith.events.externalization; + +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class Baeldung { + + private final ApplicationEventPublisher applicationEvents; + private final ArticleRepository articleRepository; + + + public Baeldung(ApplicationEventPublisher applicationEvents, ArticleRepository articleRepository) { + this.applicationEvents = applicationEvents; + this.articleRepository = articleRepository; + } + + @Transactional + public void createArticle(Article article) { + // ... business logic + validateArticle(article); + article = addArticleTags(article); + article = articleRepository.save(article); + + applicationEvents.publishEvent(new ArticlePublishedEvent(article.slug(), article.title())); + } + + + private Article addArticleTags(Article article) { + return article; + } + + private void validateArticle(Article article) { + } + +} diff --git a/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/EventExternalizationConfig.java b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/EventExternalizationConfig.java new file mode 100644 index 0000000000..9564696d92 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/EventExternalizationConfig.java @@ -0,0 +1,41 @@ +package com.baeldung.springmodulith.events.externalization; + +import org.springframework.boot.autoconfigure.kafka.KafkaProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.core.ProducerFactory; +import org.springframework.kafka.core.KafkaOperations; +import org.springframework.modulith.events.EventExternalizationConfiguration; +import org.springframework.modulith.events.RoutingTarget; + +@Configuration +class EventExternalizationConfig { + + @Bean + EventExternalizationConfiguration eventExternalizationConfiguration() { + return EventExternalizationConfiguration.externalizing() + .select(EventExternalizationConfiguration.annotatedAsExternalized()) + .route( + ArticlePublishedEvent.class, + it -> RoutingTarget.forTarget("baeldung.articles.published").andKey(it.slug()) + ) + .mapping( + ArticlePublishedEvent.class, + it -> new ArticlePublishedKafkaEvent(it.slug(), it.title()) + ) + .build(); + } + + record ArticlePublishedKafkaEvent(String slug, String title) { + } + + + @Bean + KafkaOperations kafkaOperations(KafkaProperties kafkaProperties) { + ProducerFactory producerFactory = new DefaultKafkaProducerFactory<>(kafkaProperties.buildProducerProperties()); + return new KafkaTemplate<>(producerFactory); + } +} + diff --git a/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/infra/ArticlePublishedKafkaProducer.java b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/infra/ArticlePublishedKafkaProducer.java new file mode 100644 index 0000000000..17a88a73f7 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/events/externalization/infra/ArticlePublishedKafkaProducer.java @@ -0,0 +1,34 @@ +package com.baeldung.springmodulith.events.externalization.infra; + +import org.springframework.context.event.EventListener; +import org.springframework.kafka.core.KafkaOperations; +import org.springframework.scheduling.annotation.Async; +import org.springframework.transaction.event.TransactionalEventListener; +import org.springframework.util.Assert; + +import com.baeldung.springmodulith.events.externalization.ArticlePublishedEvent; + +//@Component +// this is used in sections 3 and 4 of tha article +// but it will cause the tests to fail if it used together with the @Externalized annotation +class ArticlePublishedKafkaProducer { + + private final KafkaOperations messageProducer; + + public ArticlePublishedKafkaProducer(KafkaOperations messageProducer) { + this.messageProducer = messageProducer; + } + + @EventListener + public void publish(ArticlePublishedEvent event) { + Assert.notNull(event.slug(), "Article Slug must not be null!"); + messageProducer.send("baeldung.articles.published", event); + } + + @Async + @TransactionalEventListener + public void publishAsync(ArticlePublishedEvent article) { + Assert.notNull(article.slug(), "Article Slug must not be null!"); + messageProducer.send("baeldung.articles.published", article.slug(), article); + } +} diff --git a/spring-boot-modules/spring-boot-libraries-3/src/main/resources/application.yml b/spring-boot-modules/spring-boot-libraries-3/src/main/resources/application.yml new file mode 100644 index 0000000000..ad8f7ab4e6 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/main/resources/application.yml @@ -0,0 +1,12 @@ +logging.level.org.springframework.orm.jpa: TRACE + +spring.kafka: + bootstrap-servers: localhost:9092 + producer: + key-serializer: org.apache.kafka.common.serialization.StringSerializer + value-serializer: org.springframework.kafka.support.serializer.JsonSerializer + type-mapping: com.baeldung.annotation.events.externalization.producer.ArticlePublished + consumer: + key-deserializer: org.apache.kafka.common.serialization.StringDeserializer + value-deserializer: org.apache.kafka.common.serialization.StringDeserializer + auto-offset-reset: earliest diff --git a/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/events/externalization/EventsExternalizationLiveTest.java b/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/events/externalization/EventsExternalizationLiveTest.java new file mode 100644 index 0000000000..7f4f7a8224 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/events/externalization/EventsExternalizationLiveTest.java @@ -0,0 +1,89 @@ +package com.baeldung.springmodulith.events.externalization; + +import static java.time.Duration.ofMillis; +import static java.time.Duration.ofSeconds; +import static org.assertj.core.api.Assertions.assertThat; +import static org.testcontainers.shaded.org.awaitility.Awaitility.await; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.testcontainers.containers.KafkaContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.shaded.org.awaitility.Awaitility; +import org.testcontainers.utility.DockerImageName; + +import com.baeldung.springmodulith.Application; +import com.baeldung.springmodulith.events.externalization.listener.TestKafkaListenerConfig; +import com.baeldung.springmodulith.events.externalization.listener.TestListener; + +@Testcontainers +@SpringBootTest(classes = { Application.class, TestKafkaListenerConfig.class }) +class EventsExternalizationLiveTest { + + @Autowired + private Baeldung baeldung; + @Autowired + private TestListener listener; + @Autowired + private ArticleRepository repository; + + @Container + static KafkaContainer kafkaContainer = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); + + @DynamicPropertySource + static void dynamicProperties(DynamicPropertyRegistry registry) { + registry.add("spring.kafka.bootstrap-servers", kafkaContainer::getBootstrapServers); + } + + static { + Awaitility.setDefaultTimeout(ofSeconds(3)); + Awaitility.setDefaultPollDelay(ofMillis(100)); + } + + @BeforeEach + void beforeEach() { + listener.reset(); + repository.deleteAll(); + } + + @Test + void whenArticleIsSavedToDB_thenItIsAlsoPublishedToKafka() { + var article = new Article("introduction-to-spring-boot", "Introduction to Spring Boot", "John Doe", "

Spring Boot is [...]

"); + + baeldung.createArticle(article); + + await().untilAsserted(() -> + assertThat(listener.getEvents()) + .hasSize(1) + .first().asString() + .contains("\"slug\":\"introduction-to-spring-boot\"") + .contains("\"title\":\"Introduction to Spring Boot\"")); + + assertThat(repository.findAll()) + .hasSize(1) + .first() + .extracting(Article::slug, Article::title) + .containsExactly("introduction-to-spring-boot", "Introduction to Spring Boot"); + } + + @Test + void whenPublishingMessageFails_thenArticleIsStillSavedToDB() { + var article = new Article(null, "Introduction to Spring Boot", "John Doe", "

Spring Boot is [...]

"); + + baeldung.createArticle(article); + + assertThat(listener.getEvents()) + .isEmpty(); + + assertThat(repository.findAll()) + .hasSize(1) + .first() + .extracting(Article::title, Article::author) + .containsExactly("Introduction to Spring Boot", "John Doe"); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/events/externalization/listener/TestKafkaListenerConfig.java b/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/events/externalization/listener/TestKafkaListenerConfig.java new file mode 100644 index 0000000000..c2ee9b24a2 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/events/externalization/listener/TestKafkaListenerConfig.java @@ -0,0 +1,31 @@ +package com.baeldung.springmodulith.events.externalization.listener; + +import org.springframework.boot.autoconfigure.kafka.KafkaProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.annotation.EnableKafka; +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; +import org.springframework.kafka.config.KafkaListenerContainerFactory; +import org.springframework.kafka.core.ConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.listener.ConcurrentMessageListenerContainer; + +@EnableKafka +@Configuration +public class TestKafkaListenerConfig { + + @Bean + KafkaListenerContainerFactory> kafkaListenerContainerFactory( + ConsumerFactory consumerFactory + ) { + var factory = new ConcurrentKafkaListenerContainerFactory(); + factory.setConsumerFactory(consumerFactory); + return factory; + } + + @Bean + ConsumerFactory consumerFactory(KafkaProperties kafkaProperties) { + return new DefaultKafkaConsumerFactory<>(kafkaProperties.buildConsumerProperties()); + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/events/externalization/listener/TestListener.java b/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/events/externalization/listener/TestListener.java new file mode 100644 index 0000000000..bf5a36f66f --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/events/externalization/listener/TestListener.java @@ -0,0 +1,25 @@ +package com.baeldung.springmodulith.events.externalization.listener; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.stereotype.Component; + +@Component +public class TestListener { + private List events = new ArrayList<>(); + + @KafkaListener(id = "test-id", topics = "baeldung.articles.published") + public void listen(String event) { + events.add(event); + } + + public List getEvents() { + return events; + } + + public void reset() { + events = new ArrayList<>(); + } +} \ No newline at end of file From 320c1f306490ee3a777bc512f8407e1dc4f92f78 Mon Sep 17 00:00:00 2001 From: Diegom203 <153622681+Diegom203@users.noreply.github.com> Date: Sun, 21 Jan 2024 03:04:11 +0200 Subject: [PATCH 079/132] baeldung-articles : BAEL - 6856 (#15693) Calculating the Power of a Number in Java Without Using Math pow() Method (commit) --- ...indPowerInsteadOfUsingMathPowUnitTest.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/com.baeldung.powerinsteadofmathpow/FindPowerInsteadOfUsingMathPowUnitTest.java diff --git a/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/com.baeldung.powerinsteadofmathpow/FindPowerInsteadOfUsingMathPowUnitTest.java b/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/com.baeldung.powerinsteadofmathpow/FindPowerInsteadOfUsingMathPowUnitTest.java new file mode 100644 index 0000000000..537b361971 --- /dev/null +++ b/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/com.baeldung.powerinsteadofmathpow/FindPowerInsteadOfUsingMathPowUnitTest.java @@ -0,0 +1,57 @@ +package com.baeldung.powerinsteadofmathpow; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class FindPowerInsteadOfUsingMathPowUnitTest { + double result = 1; + double base = 2; + int exponent = 3; + + @Test + public void givenBaseAndExponentNumbers_whenUtilizingIterativeApproach_thenReturnThePower() { + + for (int i = 0; i < exponent; i++) { + result *= base; + } + + assertEquals(8, result); + } + + @Test + public void givenBaseAndExponentNumbers_whenUtilizingRecursionApproach_thenReturnThePower() { + + result = calculatePowerRecursively(base, exponent); + + assertEquals(8, result); + } + + private double calculatePowerRecursively(double base, int exponent) { + if (exponent == 0) { + return 1; + } else { + return base * calculatePowerRecursively(base, exponent - 1); + } + } + + @Test + public void givenBaseAndExponentNumbers_whenUtilizingFastApproach_thenReturnThePower() { + result = calculatePowerFast(base, exponent); + + assertEquals(8, result); + } + + private double calculatePowerFast(double base, int exponent) { + if (exponent == 0) { + return 1; + } + + double halfPower = calculatePowerFast(base, exponent / 2); + if (exponent % 2 == 0) { + return halfPower * halfPower; + } else { + return base * halfPower * halfPower; + } + } +} From f0ef5ef4721a2640754285358267733915c987e9 Mon Sep 17 00:00:00 2001 From: Rajat Garg Date: Sun, 21 Jan 2024 06:44:00 +0530 Subject: [PATCH 080/132] Add code for Gregorian date to a Hijri date conversion (#15696) Co-authored-by: rajatgarg --- .../core-java-datetime-conversion/pom.xml | 7 +++ .../GregorianToHijriDateConverter.java | 34 ++++++++++++ ...GregorianToHijriDateConverterUnitTest.java | 53 +++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/gregoriantohijri/GregorianToHijriDateConverter.java create mode 100644 core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/gregoriantohijri/GregorianToHijriDateConverterUnitTest.java diff --git a/core-java-modules/core-java-datetime-conversion/pom.xml b/core-java-modules/core-java-datetime-conversion/pom.xml index 17b5ff62ab..f415b8a6ce 100644 --- a/core-java-modules/core-java-datetime-conversion/pom.xml +++ b/core-java-modules/core-java-datetime-conversion/pom.xml @@ -25,6 +25,12 @@ commons-lang3 ${commons-lang3.version} + + com.github.msarhan + ummalqura-calendar + ${ummalqura-calendar.version} + + @@ -45,6 +51,7 @@ 2.12.5 + 2.0.2 \ No newline at end of file diff --git a/core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/gregoriantohijri/GregorianToHijriDateConverter.java b/core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/gregoriantohijri/GregorianToHijriDateConverter.java new file mode 100644 index 0000000000..022b43260c --- /dev/null +++ b/core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/gregoriantohijri/GregorianToHijriDateConverter.java @@ -0,0 +1,34 @@ +package com.baeldung.gregoriantohijri; + +import java.text.ParseException; +import java.time.LocalDate; +import java.time.chrono.ChronoLocalDate; +import java.time.chrono.HijrahChronology; +import java.time.chrono.HijrahDate; +import java.util.GregorianCalendar; + +import org.joda.time.chrono.IslamicChronology; + +import com.github.msarhan.ummalqura.calendar.UmmalquraCalendar; + +public class GregorianToHijriDateConverter { + public static HijrahDate usingHijrahChronology(LocalDate gregorianDate) { + HijrahChronology hijrahChronology = HijrahChronology.INSTANCE; + ChronoLocalDate hijriChronoLocalDate = hijrahChronology.date(gregorianDate); + return HijrahDate.from(hijriChronoLocalDate); + } + + public static HijrahDate usingFromMethod(LocalDate gregorianDate) { + return HijrahDate.from(gregorianDate); + } + + public static org.joda.time.DateTime usingJodaDate(org.joda.time.DateTime gregorianDate) { + return gregorianDate.withChronology(IslamicChronology.getInstance()); + } + + public static UmmalquraCalendar usingUmmalquraCalendar(GregorianCalendar gregorianCalendar) throws ParseException { + UmmalquraCalendar hijriCalendar = new UmmalquraCalendar(); + hijriCalendar.setTime(gregorianCalendar.getTime()); + return hijriCalendar; + } +} diff --git a/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/gregoriantohijri/GregorianToHijriDateConverterUnitTest.java b/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/gregoriantohijri/GregorianToHijriDateConverterUnitTest.java new file mode 100644 index 0000000000..bc1ae8d33f --- /dev/null +++ b/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/gregoriantohijri/GregorianToHijriDateConverterUnitTest.java @@ -0,0 +1,53 @@ +package com.baeldung.gregoriantohijri; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.text.ParseException; +import java.time.LocalDate; +import java.time.chrono.HijrahDate; +import java.time.temporal.ChronoField; +import java.util.Calendar; +import java.util.GregorianCalendar; + +import org.joda.time.DateTime; +import org.junit.jupiter.api.Test; + +import com.github.msarhan.ummalqura.calendar.UmmalquraCalendar; + +public class GregorianToHijriDateConverterUnitTest { + @Test + void givenGregorianDate_whenUsingHijrahChronologyClass_thenConvertHijriDate() { + LocalDate gregorianDate = LocalDate.of(2013, 3, 31); + HijrahDate hijriDate = GregorianToHijriDateConverter.usingHijrahChronology(gregorianDate); + assertEquals(1434, hijriDate.get(ChronoField.YEAR)); + assertEquals(5, hijriDate.get(ChronoField.MONTH_OF_YEAR)); + assertEquals(19, hijriDate.get(ChronoField.DAY_OF_MONTH)); + } + + @Test + void givenGregorianDate_whenUsingFromMethod_thenConvertHijriDate() { + LocalDate gregorianDate = LocalDate.of(2013, 3, 31); + HijrahDate hijriDate = GregorianToHijriDateConverter.usingFromMethod(gregorianDate); + assertEquals(1434, hijriDate.get(ChronoField.YEAR)); + assertEquals(5, hijriDate.get(ChronoField.MONTH_OF_YEAR)); + assertEquals(19, hijriDate.get(ChronoField.DAY_OF_MONTH)); + } + + @Test + void givenGregorianDate_whenUsingJodaDate_thenConvertHijriDate() { + DateTime gregorianDate = new DateTime(2013, 3, 31, 0, 0, 0); + DateTime hijriDate = GregorianToHijriDateConverter.usingJodaDate(gregorianDate); + assertEquals(1434, hijriDate.getYear()); + assertEquals(5, hijriDate.getMonthOfYear()); + assertEquals(19, hijriDate.getDayOfMonth()); + } + + @Test + void givenGregorianDate_whenUsingUmmalquraCalendar_thenConvertHijriDate() throws ParseException { + GregorianCalendar gregorianCalendar = new GregorianCalendar(2013, Calendar.MARCH, 31); + UmmalquraCalendar ummalquraCalendar = GregorianToHijriDateConverter.usingUmmalquraCalendar(gregorianCalendar); + assertEquals(1434, ummalquraCalendar.get(Calendar.YEAR)); + assertEquals(5, ummalquraCalendar.get(Calendar.MONTH) + 1); + assertEquals(19, ummalquraCalendar.get(Calendar.DAY_OF_MONTH)); + } +} From 870628f03110f18ab99befb47ecab5de26a8cb35 Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Sun, 21 Jan 2024 05:52:22 -0300 Subject: [PATCH 081/132] BAEL-7129 Apply Bold Text Style for an Entire Row Using Apache POI (#15633) * PR recreated due to repository truncation * review 1 * review 1 - 2 --- apache-poi-3/pom.xml | 2 +- .../com/baeldung/poi/rowstyle/PoiUtils.java | 53 +++++++ .../rowstyle/PoiBoldStyleIntegrationTest.java | 150 ++++++++++++++++++ 3 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 apache-poi-3/src/main/java/com/baeldung/poi/rowstyle/PoiUtils.java create mode 100644 apache-poi-3/src/test/java/com/baeldung/poi/rowstyle/PoiBoldStyleIntegrationTest.java diff --git a/apache-poi-3/pom.xml b/apache-poi-3/pom.xml index 1ac42f13a3..8d0204669f 100644 --- a/apache-poi-3/pom.xml +++ b/apache-poi-3/pom.xml @@ -76,7 +76,7 @@ - 5.2.3 + 5.2.5 4.1.1 0.15.7 2.6.12 diff --git a/apache-poi-3/src/main/java/com/baeldung/poi/rowstyle/PoiUtils.java b/apache-poi-3/src/main/java/com/baeldung/poi/rowstyle/PoiUtils.java new file mode 100644 index 0000000000..f40c3ad821 --- /dev/null +++ b/apache-poi-3/src/main/java/com/baeldung/poi/rowstyle/PoiUtils.java @@ -0,0 +1,53 @@ +package com.baeldung.poi.rowstyle; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Path; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; + +public class PoiUtils { + + private PoiUtils() { + } + + private static void newCell(Row row, String value) { + short cellNum = row.getLastCellNum(); + if (cellNum == -1) + cellNum = 0; + + Cell cell = row.createCell(cellNum); + cell.setCellValue(value); + } + + public static Row newRow(Sheet sheet, String... rowValues) { + Row row = sheet.createRow(sheet.getLastRowNum() + 1); + + for (String value : rowValues) { + newCell(row, value); + } + + return row; + } + + public static CellStyle boldFontStyle(Workbook workbook) { + Font boldFont = workbook.createFont(); + boldFont.setBold(true); + + CellStyle boldStyle = workbook.createCellStyle(); + boldStyle.setFont(boldFont); + + return boldStyle; + } + + public static void write(Workbook workbook, Path path) throws IOException { + try (FileOutputStream fileOut = new FileOutputStream(path.toFile())) { + workbook.write(fileOut); + } + } +} diff --git a/apache-poi-3/src/test/java/com/baeldung/poi/rowstyle/PoiBoldStyleIntegrationTest.java b/apache-poi-3/src/test/java/com/baeldung/poi/rowstyle/PoiBoldStyleIntegrationTest.java new file mode 100644 index 0000000000..dd031cf7cf --- /dev/null +++ b/apache-poi-3/src/test/java/com/baeldung/poi/rowstyle/PoiBoldStyleIntegrationTest.java @@ -0,0 +1,150 @@ +package com.baeldung.poi.rowstyle; + +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.apache.poi.hssf.usermodel.HSSFCellStyle; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFCellStyle; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.junit.jupiter.api.Test; + +class PoiBoldStyleIntegrationTest { + + private void writeSampleSheet(Path destination, Workbook workbook) throws IOException { + Sheet sheet = workbook.createSheet(); + CellStyle boldStyle = PoiUtils.boldFontStyle(workbook); + + Row header = PoiUtils.newRow(sheet, "Name", "Value", "Details"); + header.setRowStyle(boldStyle); + + PoiUtils.newRow(sheet, "Albert", "A", "First"); + PoiUtils.newRow(sheet, "Jane", "B", "Second"); + PoiUtils.newRow(sheet, "Zack", "C", "Third"); + + PoiUtils.write(workbook, destination); + } + + private void assertRowStyleAppliedAndDefaultCellStylesDontMatch(Path sheetFile) throws IOException, InvalidFormatException { + try (Workbook workbook = new XSSFWorkbook(sheetFile.toFile())) { + Sheet sheet = workbook.getSheetAt(0); + Row row0 = sheet.getRow(0); + + XSSFCellStyle rowStyle = (XSSFCellStyle) row0.getRowStyle(); + assertTrue(rowStyle.getFont() + .getBold()); + + row0.forEach(cell -> { + XSSFCellStyle style = (XSSFCellStyle) cell.getCellStyle(); + assertNotEquals(rowStyle, style); + }); + + Row row1 = sheet.getRow(1); + XSSFCellStyle row1Style = (XSSFCellStyle) row1.getRowStyle(); + assertNull(row1Style); + + Files.delete(sheetFile); + } + } + + @Test + void givenXssfWorkbook_whenSetRowStyle1stRow_thenOnly1stRowStyled() throws IOException, InvalidFormatException { + Path sheetFile = Files.createTempFile("xssf-row-style", ".xlsx"); + + try (Workbook workbook = new XSSFWorkbook()) { + writeSampleSheet(sheetFile, workbook); + } + + assertRowStyleAppliedAndDefaultCellStylesDontMatch(sheetFile); + } + + @Test + void givenSxssfWorkbook_whenSetRowStyle_thenOnly1stRowStyled() throws IOException, InvalidFormatException { + Path sheetFile = Files.createTempFile("sxssf-row-style", ".xlsx"); + + try (Workbook workbook = new SXSSFWorkbook()) { + writeSampleSheet(sheetFile, workbook); + } + + assertRowStyleAppliedAndDefaultCellStylesDontMatch(sheetFile); + } + + @Test + void givenHssfWorkbook_whenSetRowStyle_thenOnly1stRowStyled() throws IOException { + Path sheetFile = Files.createTempFile("hssf-row-style", ".xls"); + + try (Workbook workbook = new HSSFWorkbook()) { + writeSampleSheet(sheetFile, workbook); + } + + try (Workbook workbook = new HSSFWorkbook(Files.newInputStream(sheetFile))) { + Sheet sheet = workbook.getSheetAt(0); + Row row0 = sheet.getRow(0); + + HSSFCellStyle rowStyle = (HSSFCellStyle) row0.getRowStyle(); + assertTrue(rowStyle.getFont(workbook) + .getBold()); + + row0.forEach(cell -> { + HSSFCellStyle style = (HSSFCellStyle) cell.getCellStyle(); + assertNotEquals(rowStyle, style); + }); + + Row row1 = sheet.getRow(1); + HSSFCellStyle row1Style = (HSSFCellStyle) row1.getRowStyle(); + assertNull(row1Style); + + Files.delete(sheetFile); + } + } + + @Test + void givenXssfWorkbook_whenSetCellStyleForEachRow_thenAllCellsContainStyle() throws IOException, InvalidFormatException { + Path sheetFile = Files.createTempFile("xssf-cell-style", ".xlsx"); + + try (Workbook workbook = new XSSFWorkbook()) { + Sheet sheet = workbook.createSheet(); + CellStyle boldStyle = PoiUtils.boldFontStyle(workbook); + + Row header = PoiUtils.newRow(sheet, "Name", "Value", "Details"); + header.forEach(cell -> cell.setCellStyle(boldStyle)); + + PoiUtils.newRow(sheet, "Albert", "A", "First"); + PoiUtils.newRow(sheet, "Jane", "B", "Second"); + PoiUtils.newRow(sheet, "Zack", "C", "Third"); + + PoiUtils.write(workbook, sheetFile); + } + + try (Workbook workbook = new XSSFWorkbook(sheetFile.toFile())) { + Sheet sheet = workbook.getSheetAt(0); + Row row0 = sheet.getRow(0); + + XSSFCellStyle rowStyle = (XSSFCellStyle) row0.getRowStyle(); + assertNull(rowStyle); + + row0.forEach(cell -> { + XSSFCellStyle style = (XSSFCellStyle) cell.getCellStyle(); + assertTrue(style.getFont() + .getBold()); + }); + + Row row1 = sheet.getRow(1); + rowStyle = (XSSFCellStyle) row1.getRowStyle(); + assertNull(rowStyle); + + Files.delete(sheetFile); + } + } +} From cc1b43e554f27c7d074f404bd6f9d236b9eef6ea Mon Sep 17 00:00:00 2001 From: Harry9656 Date: Sun, 21 Jan 2024 21:26:29 +0100 Subject: [PATCH 082/132] [JAVA-28963] Migrate spring-mvc-java to Spring Boot 3(#15640) --- spring-web-modules/spring-mvc-java/pom.xml | 51 ++++++++++--------- .../baeldung/filters/EmptyParamFilter.java | 14 ++--- .../com/baeldung/listeners/AppListener.java | 8 +-- .../baeldung/listeners/RequestListener.java | 10 ++-- .../com/baeldung/servlets/CounterServlet.java | 8 +-- .../baeldung/servlets/UppercaseServlet.java | 8 +-- .../web/config/MainWebAppInitializer.java | 22 ++++---- .../baeldung/spring/web/config/WebConfig.java | 9 ++-- .../web/controller/ImageController.java | 2 +- .../GreetControllerIntegrationTest.java | 2 +- .../GreetControllerRealIntegrationTest.java | 8 +-- 11 files changed, 70 insertions(+), 72 deletions(-) diff --git a/spring-web-modules/spring-mvc-java/pom.xml b/spring-web-modules/spring-mvc-java/pom.xml index d4c8f24431..213d44f350 100644 --- a/spring-web-modules/spring-mvc-java/pom.xml +++ b/spring-web-modules/spring-mvc-java/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-boot-2 + parent-boot-3 0.0.1-SNAPSHOT - ../../parent-boot-2 + ../../parent-boot-3 @@ -25,18 +25,19 @@ spring-boot-starter-tomcat - javax.servlet - javax.servlet-api - ${javax.version} + jakarta.servlet + jakarta.servlet-api + ${jakarta.version} - javax.servlet.jsp - javax.servlet.jsp-api - ${javax-servlet-api.version} + jakarta.servlet.jsp + jakarta.servlet.jsp-api + ${jakarta-servlet-api.version} - javax.servlet - jstl + jakarta.servlet.jsp.jstl + jakarta.servlet.jsp.jstl-api + ${jakarta-servlet-jstl-version} org.apache.tomcat.embed @@ -50,11 +51,6 @@ commons-io ${commons-io.version} - - commons-fileupload - commons-fileupload - ${commons-fileupload.version} - org.thymeleaf @@ -77,6 +73,13 @@ spring-boot-starter-test test + + io.rest-assured + rest-assured + ${rest.assured.version} + test + + @@ -85,9 +88,10 @@ org.glassfish - javax.el - ${javax.el.version} + jakarta.el + ${jakarta.el.version} + @@ -115,12 +119,10 @@ cargo-maven2-plugin ${cargo-maven2-plugin.version} - true jetty8x embedded - @@ -167,9 +169,6 @@ org.codehaus.cargo cargo-maven2-plugin - - false - start-server @@ -208,11 +207,13 @@ 3.1.0 1.9.1 - 3.0.1-b09 - 4.0.1 - 2.3.3 + 5.0.0-M1 + 6.1.0-M1 + 4.0.0-M1 2.8.0 com.baeldung.SpringMVCApplication + 3.0.0 + 5.4.0 \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/filters/EmptyParamFilter.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/filters/EmptyParamFilter.java index b0b5392237..88f0431ab8 100644 --- a/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/filters/EmptyParamFilter.java +++ b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/filters/EmptyParamFilter.java @@ -1,12 +1,12 @@ package com.baeldung.filters; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.annotation.WebFilter; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.annotation.WebFilter; import java.io.IOException; @WebFilter(urlPatterns = "/uppercase") diff --git a/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/listeners/AppListener.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/listeners/AppListener.java index ed16dd1654..422af34c18 100644 --- a/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/listeners/AppListener.java +++ b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/listeners/AppListener.java @@ -1,9 +1,9 @@ package com.baeldung.listeners; -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.servlet.annotation.WebListener; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletContextEvent; +import jakarta.servlet.ServletContextListener; +import jakarta.servlet.annotation.WebListener; @WebListener public class AppListener implements ServletContextListener { diff --git a/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/listeners/RequestListener.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/listeners/RequestListener.java index 7f0c37b666..5070e266ec 100644 --- a/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/listeners/RequestListener.java +++ b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/listeners/RequestListener.java @@ -1,10 +1,10 @@ package com.baeldung.listeners; -import javax.servlet.ServletContext; -import javax.servlet.ServletRequestEvent; -import javax.servlet.ServletRequestListener; -import javax.servlet.annotation.WebListener; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletRequestEvent; +import jakarta.servlet.ServletRequestListener; +import jakarta.servlet.annotation.WebListener; +import jakarta.servlet.http.HttpServletRequest; @WebListener public class RequestListener implements ServletRequestListener { diff --git a/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/servlets/CounterServlet.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/servlets/CounterServlet.java index a11f084db2..3c827b5fdd 100644 --- a/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/servlets/CounterServlet.java +++ b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/servlets/CounterServlet.java @@ -1,9 +1,9 @@ package com.baeldung.servlets; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; diff --git a/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/servlets/UppercaseServlet.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/servlets/UppercaseServlet.java index 766ec2e6ff..f5dc2d82ff 100644 --- a/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/servlets/UppercaseServlet.java +++ b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/servlets/UppercaseServlet.java @@ -1,9 +1,9 @@ package com.baeldung.servlets; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; diff --git a/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/MainWebAppInitializer.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/MainWebAppInitializer.java index 3623217130..c6d8407af4 100644 --- a/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/MainWebAppInitializer.java +++ b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/MainWebAppInitializer.java @@ -1,29 +1,29 @@ package com.baeldung.spring.web.config; -import javax.servlet.MultipartConfigElement; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.support.GenericWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; +import jakarta.servlet.MultipartConfigElement; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletRegistration; + public class MainWebAppInitializer implements WebApplicationInitializer { - private String TMP_FOLDER = "/tmp"; - private int MAX_UPLOAD_SIZE = 5 * 1024 * 1024; - + private static final String TMP_FOLDER = "/tmp"; + private static final int MAX_UPLOAD_SIZE = 5 * 1024 * 1024; + @Override - public void onStartup(ServletContext sc) throws ServletException { + public void onStartup(ServletContext sc) { ServletRegistration.Dynamic appServlet = sc.addServlet("mvc", new DispatcherServlet( - new GenericWebApplicationContext())); + new GenericWebApplicationContext())); appServlet.setLoadOnStartup(1); - MultipartConfigElement multipartConfigElement = new MultipartConfigElement(TMP_FOLDER, - MAX_UPLOAD_SIZE, MAX_UPLOAD_SIZE * 2, MAX_UPLOAD_SIZE / 2); + MultipartConfigElement multipartConfigElement = new MultipartConfigElement(TMP_FOLDER, + MAX_UPLOAD_SIZE, MAX_UPLOAD_SIZE * 2L, MAX_UPLOAD_SIZE / 2); appServlet.setMultipartConfig(multipartConfigElement); diff --git a/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java index c135164a95..5ec4dd70c1 100644 --- a/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java +++ b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java @@ -12,7 +12,7 @@ import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.http.MediaType; import org.springframework.http.converter.ByteArrayHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.web.multipart.commons.CommonsMultipartResolver; +import org.springframework.web.multipart.support.StandardServletMultipartResolver; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; @@ -113,14 +113,11 @@ public class WebConfig implements WebMvcConfigurer { public void configurePathMatch(final PathMatchConfigurer configurer) { final UrlPathHelper urlPathHelper = new UrlPathHelper(); urlPathHelper.setRemoveSemicolonContent(false); - configurer.setUrlPathHelper(urlPathHelper); } @Bean(name = "multipartResolver") - public CommonsMultipartResolver multipartResolver() { - CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(); - multipartResolver.setMaxUploadSize(100000); - return multipartResolver; + public StandardServletMultipartResolver multipartResolver() { + return new StandardServletMultipartResolver(); } } \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/ImageController.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/ImageController.java index 5a8a491989..89c4bac261 100644 --- a/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/ImageController.java +++ b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/ImageController.java @@ -3,7 +3,7 @@ package com.baeldung.web.controller; import java.io.IOException; import java.io.InputStream; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerIntegrationTest.java b/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerIntegrationTest.java index 7b9da5707d..996821d1d8 100644 --- a/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerIntegrationTest.java +++ b/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerIntegrationTest.java @@ -16,7 +16,7 @@ import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import static org.junit.jupiter.api.Assertions.*; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; diff --git a/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerRealIntegrationTest.java b/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerRealIntegrationTest.java index 825520526e..899bad1310 100644 --- a/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerRealIntegrationTest.java +++ b/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerRealIntegrationTest.java @@ -1,14 +1,14 @@ package com.baeldung.web.controller; -import io.restassured.RestAssured; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.test.context.TestPropertySource; - -import static io.restassured.RestAssured.given; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; +import static io.restassured.RestAssured.given; + +import io.restassured.RestAssured; @SpringBootTest(webEnvironment = RANDOM_PORT) @TestPropertySource(properties = {"spring.main.allow-bean-definition-overriding=true", "server.servlet.context-path=/"}) From 58ab148266804230e7681956f07c9d3dea329224 Mon Sep 17 00:00:00 2001 From: Harry9656 Date: Sun, 21 Jan 2024 21:58:15 +0100 Subject: [PATCH 083/132] [JAVA-28924] Migrate libraries-data-db to Spring Boot 3 (#15638) --- libraries-data-db/pom.xml | 19 +++++++++++++------ .../baeldung/libraries/jdo/ProductXML.java | 2 +- .../libraries/jdo/xml/AnnotadedPerson.java | 7 ++++--- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/libraries-data-db/pom.xml b/libraries-data-db/pom.xml index 7f77d40667..42485ef43f 100644 --- a/libraries-data-db/pom.xml +++ b/libraries-data-db/pom.xml @@ -8,9 +8,9 @@ com.baeldung - parent-boot-2 + parent-boot-3 0.0.1-SNAPSHOT - ../parent-boot-2 + ../parent-boot-3 @@ -159,6 +159,11 @@ ebean-api ${ebean.version} + + jakarta.xml.bind + jakarta.xml.bind-api + ${jakarta.xml.bind.version} + @@ -290,22 +295,24 @@ - 11.11.2 + 13.25.2 18.1.0 3.0.0 1.8 6.1 - 6.0.3 + 6.0.6 6.0.1 6.0.0-release 6.0.1 3.2.1 5.1.0 13.15.2 - 2.1.3.Final + 2.5.0.Final 2.2.3 - 1.17.6 + 1.19.3 3.0.8 + 4.0.1 + true \ No newline at end of file diff --git a/libraries-data-db/src/main/java/com/baeldung/libraries/jdo/ProductXML.java b/libraries-data-db/src/main/java/com/baeldung/libraries/jdo/ProductXML.java index 2679b049bb..025834dbd4 100644 --- a/libraries-data-db/src/main/java/com/baeldung/libraries/jdo/ProductXML.java +++ b/libraries-data-db/src/main/java/com/baeldung/libraries/jdo/ProductXML.java @@ -2,7 +2,7 @@ package com.baeldung.libraries.jdo; import javax.jdo.annotations.PersistenceCapable; import javax.jdo.annotations.PrimaryKey; -import javax.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlAttribute; @PersistenceCapable() public class ProductXML { diff --git a/libraries-data-db/src/main/java/com/baeldung/libraries/jdo/xml/AnnotadedPerson.java b/libraries-data-db/src/main/java/com/baeldung/libraries/jdo/xml/AnnotadedPerson.java index 0520bf1d09..d7f72d78ee 100644 --- a/libraries-data-db/src/main/java/com/baeldung/libraries/jdo/xml/AnnotadedPerson.java +++ b/libraries-data-db/src/main/java/com/baeldung/libraries/jdo/xml/AnnotadedPerson.java @@ -3,12 +3,13 @@ package com.baeldung.libraries.jdo.xml; import javax.jdo.annotations.Element; import javax.jdo.annotations.PersistenceCapable; import javax.jdo.annotations.PrimaryKey; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; import java.util.ArrayList; import java.util.List; +import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; + @PersistenceCapable(schema = "/myproduct/people", table = "person") public class AnnotadedPerson { @XmlAttribute From 2a327001e371a199002dcf8a19de410a287d0b65 Mon Sep 17 00:00:00 2001 From: Wynn Teo <49014791+wynnteo@users.noreply.github.com> Date: Mon, 22 Jan 2024 05:08:42 +0800 Subject: [PATCH 084/132] Migrated from old fork (#15628) * Migrated from old fork" exiytt clear " * Update DateRangeOverlapCheckerUnitTest.java Fix typo --- .../DateRangeOverlapChecker.java | 46 +++++ .../DateRangeOverlapCheckerUnitTest.java | 158 ++++++++++++++++++ 2 files changed, 204 insertions(+) create mode 100644 core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java create mode 100644 core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java new file mode 100644 index 0000000000..9b898c87f5 --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java @@ -0,0 +1,46 @@ +package com.baeldung.daterangeoverlap; + +import java.time.LocalDate; +import java.util.Calendar; + +import org.joda.time.DateTime; +import org.joda.time.Interval; + +public class DateRangeOverlapChecker { + + public static boolean isOverlapUsingCalendarAndDuration(Calendar start1, Calendar end1, Calendar start2, Calendar end2) { + long overlap = Math.min(end1.getTimeInMillis(), end2.getTimeInMillis()) - Math.max(start1.getTimeInMillis(), start2.getTimeInMillis()); + return overlap >= 0; + } + + public static boolean isOverlapUsingLocalDateAndDuration(LocalDate start1, LocalDate end1, LocalDate start2, LocalDate end2) { + long overlap = Math.min(end1.toEpochDay(), end2.toEpochDay()) - Math.max(start1.toEpochDay(), start2.toEpochDay()); + return overlap >= 0; + } + + public static boolean isOverlapUsingJodaTime(DateTime start1, DateTime end1, DateTime start2, DateTime end2) { + Interval interval1 = new Interval(start1, end1); + Interval interval2 = new Interval(start2, end2); + return interval1.overlaps(interval2); + } + + public static boolean isOverlapUsingCalendarAndCondition(Calendar start1, Calendar end1, Calendar start2, Calendar end2) { + return !(end1.before(start2) || start1.after(end2)); + } + + public static boolean isOverlapUsingLocalDateAndCondition(LocalDate start1, LocalDate end1, LocalDate start2, LocalDate end2) { + return !(end1.isBefore(start2) || start1.isAfter(end2)); + } + + public static boolean isOverlapUsingCalendarAndFindMin(Calendar start1, Calendar end1, Calendar start2, Calendar end2) { + long overlap1 = Math.min(end1.getTimeInMillis() - start1.getTimeInMillis(), end1.getTimeInMillis() - start2.getTimeInMillis()); + long overlap2 = Math.min(end2.getTimeInMillis() - start2.getTimeInMillis(), end2.getTimeInMillis() - start1.getTimeInMillis()); + return Math.min(overlap1, overlap2) / (24 * 60 * 60 * 1000) >= 0; + } + + public static boolean isOverlapUsingLocalDateAndFindMin(LocalDate start1, LocalDate end1, LocalDate start2, LocalDate end2) { + long overlap1 = Math.min(end1.toEpochDay() - start1.toEpochDay(), end1.toEpochDay() - start2.toEpochDay()); + long overlap2 = Math.min(end2.toEpochDay() - start2.toEpochDay(), end2.toEpochDay() - start1.toEpochDay()); + return Math.min(overlap1, overlap2) >= 0; + } +} diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java new file mode 100644 index 0000000000..5811cb6552 --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java @@ -0,0 +1,158 @@ +package com.baeldung.daterangeoverlap; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.time.LocalDate; +import java.util.Calendar; + +import org.joda.time.DateTime; +import org.junit.Test; + +public class DateRangeOverlapCheckerUnitTest { + + @Test + public void givenPartialOverlappingRanges_thenReturnsTrue() { + Calendar start1 = Calendar.getInstance(); + start1.set(2024, 11, 15); + Calendar end1 = Calendar.getInstance(); + end1.set(2024, 11, 20); + + Calendar start2 = Calendar.getInstance(); + start2.set(2024, 11, 18); + Calendar end2 = Calendar.getInstance(); + end2.set(2024, 11, 22); + + LocalDate startLD1 = LocalDate.of(2024, 12, 15); + LocalDate endLD1 = LocalDate.of(2024, 12, 20); + + LocalDate startLD2 = LocalDate.of(2024, 12, 18); + LocalDate endLD2 = LocalDate.of(2024, 12, 22); + + DateTime startJT1 = new DateTime(2024, 12, 15, 0, 0); + DateTime endJT1 = new DateTime(2024, 12, 20, 0, 0); + + DateTime startJT2 = new DateTime(2024, 12, 18, 0, 0); + DateTime endJT2 = new DateTime(2024, 12, 22, 0, 0); + + assertTrue(DateRangeOverlapChecker.isOverlapUsingCalendarAndDuration(start1, end1, start2, end2)); + assertTrue(DateRangeOverlapChecker.isOverlapUsingLocalDateAndDuration(startLD1, endLD1, startLD2, endLD2)); + + assertTrue(DateRangeOverlapChecker.isOverlapUsingCalendarAndCondition(start1, end1, start2, end2)); + assertTrue(DateRangeOverlapChecker.isOverlapUsingLocalDateAndCondition(startLD1, endLD1, startLD2, endLD2)); + + assertTrue(DateRangeOverlapChecker.isOverlapUsingCalendarAndFindMin(start1, end1, start2, end2)); + assertTrue(DateRangeOverlapChecker.isOverlapUsingLocalDateAndFindMin(startLD1, endLD1, startLD2, endLD2)); + + assertTrue(DateRangeOverlapChecker.isOverlapUsingJodaTime(startJT1, endJT1, startJT2, endJT2)); + } + + @Test + public void givenFullOverlappingRanges_thenReturnsTrue() { + Calendar start1 = Calendar.getInstance(); + start1.set(2024, 11, 15); + Calendar end1 = Calendar.getInstance(); + end1.set(2024, 11, 20); + + Calendar start2 = Calendar.getInstance(); + start2.set(2024, 11, 16); + Calendar end2 = Calendar.getInstance(); + end2.set(2024, 11, 18); + + LocalDate startLD1 = LocalDate.of(2024, 12, 15); + LocalDate endLD1 = LocalDate.of(2024, 12, 20); + + LocalDate startLD2 = LocalDate.of(2024, 12, 16); + LocalDate endLD2 = LocalDate.of(2024, 12, 18); + + DateTime startJT1 = new DateTime(2024, 12, 15, 0, 0); + DateTime endJT1 = new DateTime(2024, 12, 20, 0, 0); + + DateTime startJT2 = new DateTime(2024, 12, 16, 0, 0); + DateTime endJT2 = new DateTime(2024, 12, 18, 0, 0); + + assertTrue(DateRangeOverlapChecker.isOverlapUsingCalendarAndDuration(start1, end1, start2, end2)); + assertTrue(DateRangeOverlapChecker.isOverlapUsingLocalDateAndDuration(startLD1, endLD1, startLD2, endLD2)); + + assertTrue(DateRangeOverlapChecker.isOverlapUsingCalendarAndCondition(start1, end1, start2, end2)); + assertTrue(DateRangeOverlapChecker.isOverlapUsingLocalDateAndCondition(startLD1, endLD1, startLD2, endLD2)); + + assertTrue(DateRangeOverlapChecker.isOverlapUsingCalendarAndFindMin(start1, end1, start2, end2)); + assertTrue(DateRangeOverlapChecker.isOverlapUsingLocalDateAndFindMin(startLD1, endLD1, startLD2, endLD2)); + + assertTrue(DateRangeOverlapChecker.isOverlapUsingJodaTime(startJT1, endJT1, startJT2, endJT2)); + } + + @Test + public void givenConsecutiveRanges_thenReturnsFalse() { + Calendar start1 = Calendar.getInstance(); + start1.set(2024, 11, 15); + Calendar end1 = Calendar.getInstance(); + end1.set(2024, 11, 20); + + Calendar start2 = Calendar.getInstance(); + start2.set(2024, 11, 21); + Calendar end2 = Calendar.getInstance(); + end2.set(2024, 11, 24); + + LocalDate startLD1 = LocalDate.of(2024, 12, 15); + LocalDate endLD1 = LocalDate.of(2024, 12, 20); + + LocalDate startLD2 = LocalDate.of(2024, 12, 21); + LocalDate endLD2 = LocalDate.of(2024, 12, 24); + + DateTime startJT1 = new DateTime(2024, 12, 15, 0, 0); + DateTime endJT1 = new DateTime(2024, 12, 20, 0, 0); + + DateTime startJT2 = new DateTime(2024, 12, 21, 0, 0); + DateTime endJT2 = new DateTime(2024, 12, 24, 0, 0); + + assertFalse(DateRangeOverlapChecker.isOverlapUsingCalendarAndDuration(start1, end1, start2, end2)); + assertFalse(DateRangeOverlapChecker.isOverlapUsingLocalDateAndDuration(startLD1, endLD1, startLD2, endLD2)); + + assertFalse(DateRangeOverlapChecker.isOverlapUsingCalendarAndCondition(start1, end1, start2, end2)); + assertFalse(DateRangeOverlapChecker.isOverlapUsingLocalDateAndCondition(startLD1, endLD1, startLD2, endLD2)); + + assertFalse(DateRangeOverlapChecker.isOverlapUsingCalendarAndFindMin(start1, end1, start2, end2)); + assertFalse(DateRangeOverlapChecker.isOverlapUsingLocalDateAndFindMin(startLD1, endLD1, startLD2, endLD2)); + + assertFalse(DateRangeOverlapChecker.isOverlapUsingJodaTime(startJT1, endJT1, startJT2, endJT2)); + } + + @Test + public void givenZeroRangeRanges_thenReturnsTrue() { + Calendar start1 = Calendar.getInstance(); + start1.set(2024, 11, 15); + Calendar end1 = Calendar.getInstance(); + end1.set(2024, 11, 20); + + Calendar start2 = Calendar.getInstance(); + start2.set(2024, 11, 20); + Calendar end2 = Calendar.getInstance(); + end2.set(2024, 11, 20); + + LocalDate startLD1 = LocalDate.of(2024, 12, 15); + LocalDate endLD1 = LocalDate.of(2024, 12, 20); + + LocalDate startLD2 = LocalDate.of(2024, 12, 20); + LocalDate endLD2 = LocalDate.of(2024, 12, 20); + + DateTime startJT1 = new DateTime(2024, 12, 15, 0, 0); + DateTime endJT1 = new DateTime(2024, 12, 20, 0, 0); + + DateTime startJT2 = new DateTime(2024, 12, 20, 0, 0); + DateTime endJT2 = new DateTime(2024, 12, 20, 0, 0); + + assertTrue(DateRangeOverlapChecker.isOverlapUsingCalendarAndDuration(start1, end1, start2, end2)); + assertTrue(DateRangeOverlapChecker.isOverlapUsingLocalDateAndDuration(startLD1, endLD1, startLD2, endLD2)); + + assertTrue(DateRangeOverlapChecker.isOverlapUsingCalendarAndCondition(start1, end1, start2, end2)); + assertTrue(DateRangeOverlapChecker.isOverlapUsingLocalDateAndCondition(startLD1, endLD1, startLD2, endLD2)); + + assertTrue(DateRangeOverlapChecker.isOverlapUsingCalendarAndFindMin(start1, end1, start2, end2)); + assertTrue(DateRangeOverlapChecker.isOverlapUsingLocalDateAndFindMin(startLD1, endLD1, startLD2, endLD2)); + + //the overlaps method considers two intervals as overlapping only if they have a non-zero duration. + assertFalse(DateRangeOverlapChecker.isOverlapUsingJodaTime(startJT1, endJT1, startJT2, endJT2)); + } +} From a09f1a89f1ac2e2f61f16a9f11444f6d7d83a67c Mon Sep 17 00:00:00 2001 From: Bipin kumar Date: Mon, 22 Jan 2024 03:00:13 +0530 Subject: [PATCH 085/132] [JAVA-30443] Changes made for removing commented module spring-data-rest (#15688) --- persistence-modules/pom.xml | 2 -- pom.xml | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index 4b7a5522da..87fa7761b0 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -97,8 +97,6 @@ spring-data-mongodb-2 spring-data-mongodb-reactive spring-data-redis - - spring-data-rest-2 spring-data-rest-querydsl spring-data-solr diff --git a/pom.xml b/pom.xml index e0e9629b98..92760e301e 100644 --- a/pom.xml +++ b/pom.xml @@ -821,7 +821,7 @@ spring-actuator spring-ai spring-aop-2 - + spring-batch-2 spring-batch spring-boot-modules @@ -1060,7 +1060,7 @@ spring-actuator spring-ai spring-aop-2 - + spring-batch-2 spring-batch spring-boot-modules From 22a1ca297804ee8bf0a7213c0d67e22e93ae7343 Mon Sep 17 00:00:00 2001 From: Amit Pandey Date: Mon, 22 Jan 2024 12:42:00 +0530 Subject: [PATCH 086/132] [JAVA-27759] Fix Spring 3.1.x and Keycloak 22.x OAuth2 Tutorial (#15618) --- .../spring-boot-keycloak/pom.xml | 1 + .../com/baeldung/keycloak/SecurityConfig.java | 89 +++++++++++++------ .../keycloaksoap/KeycloakSoapLiveTest.java | 8 +- 3 files changed, 67 insertions(+), 31 deletions(-) diff --git a/spring-boot-modules/spring-boot-keycloak/pom.xml b/spring-boot-modules/spring-boot-keycloak/pom.xml index ebba1f7f67..250ddb73b4 100644 --- a/spring-boot-modules/spring-boot-keycloak/pom.xml +++ b/spring-boot-modules/spring-boot-keycloak/pom.xml @@ -107,6 +107,7 @@ 4.0.0 1.6.3 3.1.0 + 17 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java index 5b9ce9677a..2bf3c12397 100644 --- a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java +++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java @@ -1,15 +1,21 @@ package com.baeldung.keycloak; +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; -import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.Customizer; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; import org.springframework.security.core.session.SessionRegistryImpl; +import org.springframework.security.oauth2.core.oidc.user.OidcUserAuthority; +import org.springframework.security.oauth2.core.user.OAuth2UserAuthority; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy; import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; @@ -19,6 +25,10 @@ import org.springframework.security.web.util.matcher.AntPathRequestMatcher; @EnableWebSecurity class SecurityConfig { + private static final String GROUPS = "groups"; + private static final String REALM_ACCESS_CLAIM = "realm_access"; + private static final String ROLES_CLAIM = "roles"; + private final KeycloakLogoutHandler keycloakLogoutHandler; SecurityConfig(KeycloakLogoutHandler keycloakLogoutHandler) { @@ -30,38 +40,63 @@ class SecurityConfig { return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl()); } - @Order(1) + @Bean - public SecurityFilterChain clientFilterChain(HttpSecurity http) throws Exception { - http.authorizeRequests() + public SecurityFilterChain resourceServerFilterChain(HttpSecurity http) throws Exception { + http.authorizeHttpRequests(auth -> auth + .requestMatchers(new AntPathRequestMatcher("/customers*")) + .hasRole("user") .requestMatchers(new AntPathRequestMatcher("/")) .permitAll() .anyRequest() - .authenticated(); - http.oauth2Login() - .and() - .logout() - .addLogoutHandler(keycloakLogoutHandler) - .logoutSuccessUrl("/"); - return http.build(); - } - - @Order(2) - @Bean - public SecurityFilterChain resourceServerFilterChain(HttpSecurity http) throws Exception { - http.authorizeRequests() - .requestMatchers(new AntPathRequestMatcher("/customers*")) - .hasRole("USER") - .anyRequest() - .authenticated(); + .authenticated()); http.oauth2ResourceServer((oauth2) -> oauth2 .jwt(Customizer.withDefaults())); + http.oauth2Login(Customizer.withDefaults()) + .logout(logout -> logout.addLogoutHandler(keycloakLogoutHandler).logoutSuccessUrl("/")); return http.build(); } + @Bean - public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception { - return http.getSharedObject(AuthenticationManagerBuilder.class) - .build(); + public GrantedAuthoritiesMapper userAuthoritiesMapperForKeycloak() { + return authorities -> { + Set mappedAuthorities = new HashSet<>(); + var authority = authorities.iterator().next(); + boolean isOidc = authority instanceof OidcUserAuthority; + + if (isOidc) { + var oidcUserAuthority = (OidcUserAuthority) authority; + var userInfo = oidcUserAuthority.getUserInfo(); + + // Tokens can be configured to return roles under + // Groups or REALM ACCESS hence have to check both + if (userInfo.hasClaim(REALM_ACCESS_CLAIM)) { + var realmAccess = userInfo.getClaimAsMap(REALM_ACCESS_CLAIM); + var roles = (Collection) realmAccess.get(ROLES_CLAIM); + mappedAuthorities.addAll(generateAuthoritiesFromClaim(roles)); + } else if (userInfo.hasClaim(GROUPS)) { + Collection roles = (Collection) userInfo.getClaim( + GROUPS); + mappedAuthorities.addAll(generateAuthoritiesFromClaim(roles)); + } + } else { + var oauth2UserAuthority = (OAuth2UserAuthority) authority; + Map userAttributes = oauth2UserAuthority.getAttributes(); + + if (userAttributes.containsKey(REALM_ACCESS_CLAIM)) { + Map realmAccess = (Map) userAttributes.get( + REALM_ACCESS_CLAIM); + Collection roles = (Collection) realmAccess.get(ROLES_CLAIM); + mappedAuthorities.addAll(generateAuthoritiesFromClaim(roles)); + } + } + return mappedAuthorities; + }; + } + + Collection generateAuthoritiesFromClaim(Collection roles) { + return roles.stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role)).collect( + Collectors.toList()); } } diff --git a/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapLiveTest.java b/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapLiveTest.java index 508061396f..8851d706c0 100644 --- a/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapLiveTest.java +++ b/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapLiveTest.java @@ -73,7 +73,7 @@ class KeycloakSoapLiveTest { ResponseEntity responseEntity = restTemplate.postForEntity("http://localhost:" + port + "/ws/api/v1/", request, String.class); assertThat(responseEntity).isNotNull(); - assertThat(responseEntity.getStatusCodeValue()).isEqualTo(HttpStatus.OK.value()); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK.value()); assertThat(responseEntity.getBody()).isNotBlank(); assertThat(responseEntity.getBody()).containsIgnoringCase(":id>1 request = new HttpEntity<>(Utility.getGetProductDetailsRequest(), headers); ResponseEntity responseEntity = restTemplate.postForEntity("http://localhost:" + port + "/ws/api/v1/", request, String.class); assertThat(responseEntity).isNotNull(); - assertThat(responseEntity.getStatusCodeValue()).isEqualTo(HttpStatus.UNAUTHORIZED.value()); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED.value()); assertThat(responseEntity.getBody()).isBlank(); } @@ -110,7 +110,7 @@ class KeycloakSoapLiveTest { ResponseEntity responseEntity = restTemplate.postForEntity("http://localhost:" + port + "/ws/api/v1/", request, String.class); assertThat(responseEntity).isNotNull(); - assertThat(responseEntity.getStatusCodeValue()).isEqualTo(HttpStatus.OK.value()); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK.value()); assertThat(responseEntity.getBody()).isNotBlank(); assertThat(responseEntity.getBody()).containsIgnoringCase("Deleted the product with the id"); } @@ -130,7 +130,7 @@ class KeycloakSoapLiveTest { ResponseEntity responseEntity = restTemplate.postForEntity("http://localhost:" + port + "/ws/api/v1/", request, String.class); assertThat(responseEntity).isNotNull(); - assertThat(responseEntity.getStatusCodeValue()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR.value()); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR.value()); assertThat(responseEntity.getBody()).isNotBlank(); assertThat(responseEntity.getBody()).containsIgnoringCase("Access is denied"); } From 97e9ba0c3f8ef20829223d2f1a1db06581a472cb Mon Sep 17 00:00:00 2001 From: Amit Pandey Date: Mon, 22 Jan 2024 13:30:05 +0530 Subject: [PATCH 087/132] [JAVA-30357] Upgrade spring-mvc-java-2 to Spring Boot 3 (#15625) --- spring-web-modules/spring-mvc-java-2/pom.xml | 30 ++++++------------- .../cache/CacheControlController.java | 2 +- .../com/baeldung/excel/ExcelController.java | 2 +- .../matrix/controller/CompanyController.java | 2 +- .../matrix/controller/EmployeeController.java | 4 +-- .../com/baeldung/matrix/model/Employee.java | 3 +- .../MultipartPostRequestController.java | 3 +- .../CustomWebMvcConfigurationSupport.java | 2 -- .../SiteController.java | 1 - .../com/baeldung/htmlunit/TestConfig.java | 19 +++++++----- .../matrix/EmployeeMvcIntegrationTest.java | 2 +- .../ConvertFileToMultipartFileUnitTest.java | 14 ++++----- 12 files changed, 36 insertions(+), 48 deletions(-) diff --git a/spring-web-modules/spring-mvc-java-2/pom.xml b/spring-web-modules/spring-mvc-java-2/pom.xml index a4484ed56d..f91e2dd541 100644 --- a/spring-web-modules/spring-mvc-java-2/pom.xml +++ b/spring-web-modules/spring-mvc-java-2/pom.xml @@ -10,21 +10,15 @@ com.baeldung - parent-boot-2 + parent-boot-3 0.0.1-SNAPSHOT - ../../parent-boot-2 + ../../parent-boot-3 - - javax.servlet - javax.servlet-api - ${javax.version} - org.springframework spring-webmvc - ${spring.mvc.version} com.fasterxml.jackson.core @@ -37,15 +31,10 @@ ${commons-io.version} - org.glassfish.jaxb - jaxb-runtime + com.sun.xml.bind + jaxb-impl ${jaxb-runtime.version} - - commons-fileupload - commons-fileupload - ${commons-fileupload.version} - net.sourceforge.htmlunit htmlunit @@ -80,6 +69,7 @@ javax.servlet jstl + ${jstl.version} org.apache.tomcat.embed @@ -89,7 +79,7 @@ org.thymeleaf - thymeleaf-spring4 + thymeleaf-spring5 ${thymeleaf.version} @@ -110,15 +100,13 @@ - 4.0.1 - 5.2.2.RELEASE - 2.3.5 - 1.5 + 4.0.1 2.32 3.16-beta1 3.0.1-b09 2.3.3 - 3.0.9.RELEASE + 3.1.2.RELEASE + true \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/cache/CacheControlController.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/cache/CacheControlController.java index 7305f836cf..641611f5c9 100644 --- a/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/cache/CacheControlController.java +++ b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/cache/CacheControlController.java @@ -7,7 +7,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.context.request.WebRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.concurrent.TimeUnit; diff --git a/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/excel/ExcelController.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/excel/ExcelController.java index 5cb5de7124..cda8ef123d 100644 --- a/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/excel/ExcelController.java +++ b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/excel/ExcelController.java @@ -7,7 +7,7 @@ import java.io.InputStream; import java.util.List; import java.util.Map; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; diff --git a/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/controller/CompanyController.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/controller/CompanyController.java index 7a21ded026..81ff304047 100644 --- a/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/controller/CompanyController.java +++ b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/controller/CompanyController.java @@ -49,7 +49,7 @@ public class CompanyController { @RequestMapping(value = "/companyData/{company}/employeeData/{employee}", method = RequestMethod.GET) @ResponseBody public ResponseEntity> getCompanyName(@MatrixVariable(value = "name", pathVar = "company") final String name) { - final Map result = new HashMap(); + final Map result = new HashMap<>(); result.put("name", name); return new ResponseEntity<>(result, HttpStatus.OK); } diff --git a/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/controller/EmployeeController.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/controller/EmployeeController.java index 3d5df0653d..48b58adbc2 100644 --- a/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/controller/EmployeeController.java +++ b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/controller/EmployeeController.java @@ -53,7 +53,7 @@ public class EmployeeController { @RequestMapping(value = "/employees/{name}", method = RequestMethod.GET) @ResponseBody public ResponseEntity> getEmployeeByNameAndBeginContactNumber(@PathVariable final String name, @MatrixVariable final String beginContactNumber) { - final List employeesList = new ArrayList(); + final List employeesList = new ArrayList<>(); for (final Map.Entry employeeEntry : employeeMap.entrySet()) { final Employee employee = employeeEntry.getValue(); if (employee.getName().equalsIgnoreCase(name) && employee.getContactNumber().startsWith(beginContactNumber)) { @@ -66,7 +66,7 @@ public class EmployeeController { @RequestMapping(value = "/employeesContacts/{contactNumber}", method = RequestMethod.GET) @ResponseBody public ResponseEntity> getEmployeeByContactNumber(@MatrixVariable(required = true) final String contactNumber) { - final List employeesList = new ArrayList(); + final List employeesList = new ArrayList<>(); for (final Map.Entry employeeEntry : employeeMap.entrySet()) { final Employee employee = employeeEntry.getValue(); if (employee.getContactNumber().equalsIgnoreCase(contactNumber)) { diff --git a/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/model/Employee.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/model/Employee.java index c3384122b4..b6aa3815fc 100644 --- a/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/model/Employee.java +++ b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/model/Employee.java @@ -1,6 +1,7 @@ package com.baeldung.matrix.model; -import javax.xml.bind.annotation.XmlRootElement; + +import jakarta.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Employee { diff --git a/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/multiparttesting/MultipartPostRequestController.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/multiparttesting/MultipartPostRequestController.java index d624ea368f..a9cf4c4f7a 100644 --- a/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/multiparttesting/MultipartPostRequestController.java +++ b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/multiparttesting/MultipartPostRequestController.java @@ -12,6 +12,7 @@ public class MultipartPostRequestController { @PostMapping(path = "/upload") public ResponseEntity uploadFile(@RequestParam("file") MultipartFile file) { - return file.isEmpty() ? new ResponseEntity(HttpStatus.NOT_FOUND) : new ResponseEntity(HttpStatus.OK); + return file.isEmpty() ? new ResponseEntity<>(HttpStatus.NOT_FOUND) : new ResponseEntity<>( + HttpStatus.OK); } } \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/pathvariable.dottruncated/CustomWebMvcConfigurationSupport.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/pathvariable.dottruncated/CustomWebMvcConfigurationSupport.java index 24d5a447ab..d4b716d6f1 100644 --- a/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/pathvariable.dottruncated/CustomWebMvcConfigurationSupport.java +++ b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/pathvariable.dottruncated/CustomWebMvcConfigurationSupport.java @@ -10,8 +10,6 @@ public class CustomWebMvcConfigurationSupport extends WebMvcConfigurationSupport @Override protected PathMatchConfigurer getPathMatchConfigurer() { PathMatchConfigurer pathMatchConfigurer = super.getPathMatchConfigurer(); - pathMatchConfigurer.setUseSuffixPatternMatch(false); - return pathMatchConfigurer; } } diff --git a/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/pathvariable.dottruncated/SiteController.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/pathvariable.dottruncated/SiteController.java index c9584afdc9..86ad9e531d 100644 --- a/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/pathvariable.dottruncated/SiteController.java +++ b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/pathvariable.dottruncated/SiteController.java @@ -1,6 +1,5 @@ package com.baeldung.pathvariable.dottruncated; -import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/htmlunit/TestConfig.java b/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/htmlunit/TestConfig.java index 6e55f01454..5d7264137c 100644 --- a/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/htmlunit/TestConfig.java +++ b/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/htmlunit/TestConfig.java @@ -1,17 +1,20 @@ package com.baeldung.htmlunit; -import javax.servlet.ServletContext; - import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import org.thymeleaf.spring4.SpringTemplateEngine; -import org.thymeleaf.spring4.view.ThymeleafViewResolver; -import org.thymeleaf.templateresolver.ServletContextTemplateResolver; +import org.thymeleaf.spring5.SpringTemplateEngine; +import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver; +import org.thymeleaf.spring5.view.ThymeleafViewResolver; +import org.thymeleaf.templateresolver.WebApplicationTemplateResolver; +import org.thymeleaf.web.IWebApplication; +import org.thymeleaf.web.servlet.IServletWebApplication; +import org.thymeleaf.web.servlet.JakartaServletWebApplication; @Configuration @EnableWebMvc @@ -19,7 +22,7 @@ import org.thymeleaf.templateresolver.ServletContextTemplateResolver; public class TestConfig implements WebMvcConfigurer { @Autowired - private ServletContext ctx; + private ApplicationContext ctx; @Bean public ViewResolver thymeleafViewResolver() { @@ -30,8 +33,8 @@ public class TestConfig implements WebMvcConfigurer { } @Bean - public ServletContextTemplateResolver templateResolver() { - final ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(ctx); + public SpringResourceTemplateResolver templateResolver() { + final SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver (); templateResolver.setPrefix("/WEB-INF/templates/"); templateResolver.setSuffix(".html"); templateResolver.setTemplateMode("HTML5"); diff --git a/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/matrix/EmployeeMvcIntegrationTest.java b/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/matrix/EmployeeMvcIntegrationTest.java index c061c1efc7..6d91f08bb0 100644 --- a/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/matrix/EmployeeMvcIntegrationTest.java +++ b/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/matrix/EmployeeMvcIntegrationTest.java @@ -29,7 +29,7 @@ public class EmployeeMvcIntegrationTest { @Before public void setup() { - MockitoAnnotations.initMocks(this); + MockitoAnnotations.openMocks(this); mockMvc = MockMvcBuilders.webAppContextSetup(webAppContext).build(); } diff --git a/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/multipart/file/ConvertFileToMultipartFileUnitTest.java b/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/multipart/file/ConvertFileToMultipartFileUnitTest.java index 7d99f7f9bb..47b9bfb058 100644 --- a/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/multipart/file/ConvertFileToMultipartFileUnitTest.java +++ b/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/multipart/file/ConvertFileToMultipartFileUnitTest.java @@ -4,18 +4,16 @@ import static org.junit.Assert.assertEquals; import java.io.File; import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.file.Files; - -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.disk.DiskFileItem; import org.apache.commons.io.IOUtils; import org.junit.jupiter.api.Test; -import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.multipart.commons.CommonsMultipartFile; +import org.springframework.http.MediaType; import org.springframework.mock.web.MockMultipartFile; +import org.springframework.web.multipart.MultipartFile; public class ConvertFileToMultipartFileUnitTest { @@ -32,11 +30,11 @@ public class ConvertFileToMultipartFileUnitTest { @Test public void givenFile_whenCreateMultipartFileUsingCommonsMultipart_thenContentMatch() throws IOException { File file = new File("src/main/resources/targetFile.tmp"); - FileItem fileItem = new DiskFileItem("file", Files.probeContentType(file.toPath()), false, file.getName(), (int) file.length(), file.getParentFile()); InputStream input = new FileInputStream(file); - OutputStream outputStream = fileItem.getOutputStream(); + byte [] arr = IOUtils.toByteArray(input); + OutputStream outputStream = new FileOutputStream(file); IOUtils.copy(input, outputStream); - MultipartFile multipartFile = new CommonsMultipartFile(fileItem); + MultipartFile multipartFile = new MockMultipartFile("test","targetFile.tmp", MediaType.TEXT_PLAIN_VALUE, arr); String fileContent = new String(multipartFile.getBytes()); assertEquals("Hello World", fileContent); assertEquals("targetFile.tmp", multipartFile.getOriginalFilename()); From e13051aff412e7b04e4faab41f76955374f0d4ae Mon Sep 17 00:00:00 2001 From: Amit Pandey Date: Mon, 22 Jan 2024 18:05:02 +0530 Subject: [PATCH 088/132] Java 28951 :- Upgrade spring-boot-rest to Spring Boot 3 (#15617) --- spring-boot-rest/pom.xml | 10 +++++----- .../com/baeldung/persistence/model/Foo.java | 14 +++++++------- .../service/common/AbstractService.java | 4 ++-- .../persistence/service/impl/FooService.java | 18 ++++++++---------- .../baeldung/springpagination/model/Post.java | 10 +++++----- .../springpagination/model/Preference.java | 10 +++++----- .../springpagination/model/Subject.java | 10 +++++----- .../baeldung/springpagination/model/User.java | 12 ++++++------ .../repository/PostRepository.java | 1 - .../springpagination/service/PostService.java | 2 +- .../baeldung/web/config/MyErrorController.java | 2 +- .../baeldung/web/controller/FooController.java | 2 +- .../web/controller/RootController.java | 4 ++-- .../controller/students/StudentService.java | 2 +- .../RestResponseEntityExceptionHandler.java | 11 +++++------ .../RestResponseStatusExceptionResolver.java | 4 ++-- .../event/PaginatedResultsRetrievedEvent.java | 2 +- .../hateoas/event/ResourceCreatedEvent.java | 2 +- .../event/SingleResourceRetrievedEvent.java | 2 +- ...esultsRetrievedDiscoverabilityListener.java | 2 +- ...ResourceCreatedDiscoverabilityListener.java | 11 ++++------- ...sourceRetrievedDiscoverabilityListener.java | 2 +- .../java/com/baeldung/web/util/LinkUtil.java | 2 +- .../common/web/AbstractBasicLiveTest.java | 2 +- .../web/AbstractDiscoverabilityLiveTest.java | 2 +- .../com/baeldung/rest/GithubBasicLiveTest.java | 2 +- .../CustomerControllerIntegrationTest.java | 2 +- ...FooControllerCustomEtagIntegrationTest.java | 2 +- .../web/FooMessageConvertersLiveTest.java | 2 +- .../com/baeldung/web/FooPageableLiveTest.java | 2 +- 30 files changed, 73 insertions(+), 80 deletions(-) diff --git a/spring-boot-rest/pom.xml b/spring-boot-rest/pom.xml index 71916900a4..2fd05ef394 100644 --- a/spring-boot-rest/pom.xml +++ b/spring-boot-rest/pom.xml @@ -11,9 +11,9 @@ com.baeldung - parent-boot-2 + parent-boot-3 0.0.1-SNAPSHOT - ../parent-boot-2 + ../parent-boot-3 @@ -144,8 +144,8 @@ - org.glassfish.jaxb - jaxb-runtime + com.sun.xml.bind + jaxb-impl ${jaxb-runtime.version} @@ -164,6 +164,6 @@ 1.4.11.1 3.2.0 3.3.0 - 2.3.7 + 4.0.1 diff --git a/spring-boot-rest/src/main/java/com/baeldung/persistence/model/Foo.java b/spring-boot-rest/src/main/java/com/baeldung/persistence/model/Foo.java index c8af731bc5..02f33bc5db 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/persistence/model/Foo.java +++ b/spring-boot-rest/src/main/java/com/baeldung/persistence/model/Foo.java @@ -2,12 +2,12 @@ package com.baeldung.persistence.model; import java.io.Serializable; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Version; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Version; import com.thoughtworks.xstream.annotations.XStreamAlias; @@ -16,7 +16,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; public class Foo implements Serializable { @Id - @GeneratedValue(strategy = GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; @Column(nullable = false) diff --git a/spring-boot-rest/src/main/java/com/baeldung/persistence/service/common/AbstractService.java b/spring-boot-rest/src/main/java/com/baeldung/persistence/service/common/AbstractService.java index f589eaecf5..fcf5426438 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/persistence/service/common/AbstractService.java +++ b/spring-boot-rest/src/main/java/com/baeldung/persistence/service/common/AbstractService.java @@ -5,7 +5,7 @@ import java.util.List; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; -import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.transaction.annotation.Transactional; import com.baeldung.persistence.IOperations; @@ -57,6 +57,6 @@ public abstract class AbstractService implements IOperat getDao().deleteById(entityId); } - protected abstract PagingAndSortingRepository getDao(); + protected abstract JpaRepository getDao(); } diff --git a/spring-boot-rest/src/main/java/com/baeldung/persistence/service/impl/FooService.java b/spring-boot-rest/src/main/java/com/baeldung/persistence/service/impl/FooService.java index 299e5ec214..9a8f48ba6e 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/persistence/service/impl/FooService.java +++ b/spring-boot-rest/src/main/java/com/baeldung/persistence/service/impl/FooService.java @@ -1,19 +1,17 @@ package com.baeldung.persistence.service.impl; -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.repository.PagingAndSortingRepository; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - import com.baeldung.persistence.dao.IFooDao; import com.baeldung.persistence.model.Foo; import com.baeldung.persistence.service.IFooService; import com.baeldung.persistence.service.common.AbstractService; import com.google.common.collect.Lists; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @Transactional @@ -29,7 +27,7 @@ public class FooService extends AbstractService implements IFooService { // API @Override - protected PagingAndSortingRepository getDao() { + protected JpaRepository getDao() { return dao; } diff --git a/spring-boot-rest/src/main/java/com/baeldung/springpagination/model/Post.java b/spring-boot-rest/src/main/java/com/baeldung/springpagination/model/Post.java index 88e9ef67bb..e3719c8b10 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/springpagination/model/Post.java +++ b/spring-boot-rest/src/main/java/com/baeldung/springpagination/model/Post.java @@ -2,16 +2,16 @@ package com.baeldung.springpagination.model; import java.util.Date; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class Post { @Id - @GeneratedValue(strategy = GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String title; diff --git a/spring-boot-rest/src/main/java/com/baeldung/springpagination/model/Preference.java b/spring-boot-rest/src/main/java/com/baeldung/springpagination/model/Preference.java index 44f8f41aff..3469fc19b3 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/springpagination/model/Preference.java +++ b/spring-boot-rest/src/main/java/com/baeldung/springpagination/model/Preference.java @@ -1,15 +1,15 @@ package com.baeldung.springpagination.model; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class Preference { @Id - @GeneratedValue(strategy = GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String timezone; diff --git a/spring-boot-rest/src/main/java/com/baeldung/springpagination/model/Subject.java b/spring-boot-rest/src/main/java/com/baeldung/springpagination/model/Subject.java index 80598ae07d..50e9d534c6 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/springpagination/model/Subject.java +++ b/spring-boot-rest/src/main/java/com/baeldung/springpagination/model/Subject.java @@ -1,10 +1,10 @@ package com.baeldung.springpagination.model; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class Subject { diff --git a/spring-boot-rest/src/main/java/com/baeldung/springpagination/model/User.java b/spring-boot-rest/src/main/java/com/baeldung/springpagination/model/User.java index 4d33834b28..1dc06210da 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/springpagination/model/User.java +++ b/spring-boot-rest/src/main/java/com/baeldung/springpagination/model/User.java @@ -1,16 +1,16 @@ package com.baeldung.springpagination.model; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToOne; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToOne; @Entity public class User { @Id - @GeneratedValue(strategy = GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; diff --git a/spring-boot-rest/src/main/java/com/baeldung/springpagination/repository/PostRepository.java b/spring-boot-rest/src/main/java/com/baeldung/springpagination/repository/PostRepository.java index 62f05f8262..c50ddcdf48 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/springpagination/repository/PostRepository.java +++ b/spring-boot-rest/src/main/java/com/baeldung/springpagination/repository/PostRepository.java @@ -4,7 +4,6 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.query.Param; import com.baeldung.springpagination.model.Post; diff --git a/spring-boot-rest/src/main/java/com/baeldung/springpagination/service/PostService.java b/spring-boot-rest/src/main/java/com/baeldung/springpagination/service/PostService.java index bb4869dd33..faa3d124b3 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/springpagination/service/PostService.java +++ b/spring-boot-rest/src/main/java/com/baeldung/springpagination/service/PostService.java @@ -42,6 +42,6 @@ public class PostService implements IPostService { @Override public Post getPostById(Long id) { - return postRepository.getOne(id); + return postRepository.getReferenceById(id); } } diff --git a/spring-boot-rest/src/main/java/com/baeldung/web/config/MyErrorController.java b/spring-boot-rest/src/main/java/com/baeldung/web/config/MyErrorController.java index 05150716f6..df6418fee3 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/web/config/MyErrorController.java +++ b/spring-boot-rest/src/main/java/com/baeldung/web/config/MyErrorController.java @@ -2,7 +2,7 @@ package com.baeldung.web.config; import java.util.Map; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; diff --git a/spring-boot-rest/src/main/java/com/baeldung/web/controller/FooController.java b/spring-boot-rest/src/main/java/com/baeldung/web/controller/FooController.java index a09878fb84..54fb4faab4 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/web/controller/FooController.java +++ b/spring-boot-rest/src/main/java/com/baeldung/web/controller/FooController.java @@ -2,7 +2,7 @@ package com.baeldung.web.controller; import java.util.List; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/spring-boot-rest/src/main/java/com/baeldung/web/controller/RootController.java b/spring-boot-rest/src/main/java/com/baeldung/web/controller/RootController.java index d618e9f0bf..32671ef225 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/web/controller/RootController.java +++ b/spring-boot-rest/src/main/java/com/baeldung/web/controller/RootController.java @@ -2,8 +2,8 @@ package com.baeldung.web.controller; import java.net.URI; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; diff --git a/spring-boot-rest/src/main/java/com/baeldung/web/controller/students/StudentService.java b/spring-boot-rest/src/main/java/com/baeldung/web/controller/students/StudentService.java index d923f4f14f..88e59727d1 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/web/controller/students/StudentService.java +++ b/spring-boot-rest/src/main/java/com/baeldung/web/controller/students/StudentService.java @@ -19,7 +19,7 @@ public class StudentService { new Student(2, "Sebastian","Bach"), new Student(3, "Pablo","Picasso"), }).stream() - .collect(Collectors.toConcurrentMap(s -> s.getId(), Function.identity())); + .collect(Collectors.toConcurrentMap(Student::getId, Function.identity())); // DB id sequence mock private AtomicLong sequence = new AtomicLong(3); diff --git a/spring-boot-rest/src/main/java/com/baeldung/web/error/RestResponseEntityExceptionHandler.java b/spring-boot-rest/src/main/java/com/baeldung/web/error/RestResponseEntityExceptionHandler.java index 2e2672f510..1726e00dff 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/web/error/RestResponseEntityExceptionHandler.java +++ b/spring-boot-rest/src/main/java/com/baeldung/web/error/RestResponseEntityExceptionHandler.java @@ -1,13 +1,14 @@ package com.baeldung.web.error; -import javax.persistence.EntityNotFoundException; - +import com.baeldung.web.exception.MyResourceNotFoundException; +import jakarta.persistence.EntityNotFoundException; import org.hibernate.exception.ConstraintViolationException; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.web.bind.MethodArgumentNotValidException; @@ -16,8 +17,6 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; -import com.baeldung.web.exception.MyResourceNotFoundException; - @ControllerAdvice public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler { @@ -42,14 +41,14 @@ public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionH } @Override - protected ResponseEntity handleHttpMessageNotReadable(final HttpMessageNotReadableException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request) { + protected ResponseEntity handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { final String bodyOfResponse = "This should be application specific"; // ex.getCause() instanceof JsonMappingException, JsonParseException // for additional information later on return handleExceptionInternal(ex, bodyOfResponse, headers, HttpStatus.BAD_REQUEST, request); } @Override - protected ResponseEntity handleMethodArgumentNotValid(final MethodArgumentNotValidException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request) { + protected ResponseEntity handleMethodArgumentNotValid(final MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { final String bodyOfResponse = "This should be application specific"; return handleExceptionInternal(ex, bodyOfResponse, headers, HttpStatus.BAD_REQUEST, request); } diff --git a/spring-boot-rest/src/main/java/com/baeldung/web/error/RestResponseStatusExceptionResolver.java b/spring-boot-rest/src/main/java/com/baeldung/web/error/RestResponseStatusExceptionResolver.java index 6753ab35cf..095d16bcc6 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/web/error/RestResponseStatusExceptionResolver.java +++ b/spring-boot-rest/src/main/java/com/baeldung/web/error/RestResponseStatusExceptionResolver.java @@ -3,8 +3,8 @@ package com.baeldung.web.error; import java.util.HashMap; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/event/PaginatedResultsRetrievedEvent.java b/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/event/PaginatedResultsRetrievedEvent.java index f62fbf6247..15ae2a1a8b 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/event/PaginatedResultsRetrievedEvent.java +++ b/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/event/PaginatedResultsRetrievedEvent.java @@ -2,7 +2,7 @@ package com.baeldung.web.hateoas.event; import java.io.Serializable; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.ApplicationEvent; import org.springframework.web.util.UriComponentsBuilder; diff --git a/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/event/ResourceCreatedEvent.java b/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/event/ResourceCreatedEvent.java index b602f7ec4b..a029ed7386 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/event/ResourceCreatedEvent.java +++ b/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/event/ResourceCreatedEvent.java @@ -1,6 +1,6 @@ package com.baeldung.web.hateoas.event; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.ApplicationEvent; diff --git a/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/event/SingleResourceRetrievedEvent.java b/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/event/SingleResourceRetrievedEvent.java index 70face083c..055fcab626 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/event/SingleResourceRetrievedEvent.java +++ b/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/event/SingleResourceRetrievedEvent.java @@ -1,6 +1,6 @@ package com.baeldung.web.hateoas.event; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.ApplicationEvent; diff --git a/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/listener/PaginatedResultsRetrievedDiscoverabilityListener.java b/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/listener/PaginatedResultsRetrievedDiscoverabilityListener.java index afcd364cce..3c4b5a49d3 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/listener/PaginatedResultsRetrievedDiscoverabilityListener.java +++ b/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/listener/PaginatedResultsRetrievedDiscoverabilityListener.java @@ -2,7 +2,7 @@ package com.baeldung.web.hateoas.listener; import java.util.StringJoiner; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; diff --git a/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/listener/ResourceCreatedDiscoverabilityListener.java b/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/listener/ResourceCreatedDiscoverabilityListener.java index 37afcdace4..b42805f9d0 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/listener/ResourceCreatedDiscoverabilityListener.java +++ b/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/listener/ResourceCreatedDiscoverabilityListener.java @@ -1,17 +1,14 @@ package com.baeldung.web.hateoas.listener; -import java.net.URI; - -import javax.servlet.http.HttpServletResponse; - -import org.apache.http.HttpHeaders; import com.baeldung.web.hateoas.event.ResourceCreatedEvent; +import com.google.common.base.Preconditions; +import java.net.URI; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.http.HttpHeaders; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; -import com.google.common.base.Preconditions; - @Component class ResourceCreatedDiscoverabilityListener implements ApplicationListener { diff --git a/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/listener/SingleResourceRetrievedDiscoverabilityListener.java b/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/listener/SingleResourceRetrievedDiscoverabilityListener.java index d527c308b9..f751b325e1 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/listener/SingleResourceRetrievedDiscoverabilityListener.java +++ b/spring-boot-rest/src/main/java/com/baeldung/web/hateoas/listener/SingleResourceRetrievedDiscoverabilityListener.java @@ -1,6 +1,6 @@ package com.baeldung.web.hateoas.listener; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import com.baeldung.web.hateoas.event.SingleResourceRetrievedEvent; import com.baeldung.web.util.LinkUtil; diff --git a/spring-boot-rest/src/main/java/com/baeldung/web/util/LinkUtil.java b/spring-boot-rest/src/main/java/com/baeldung/web/util/LinkUtil.java index 3ebba8ae1c..82e3d2c913 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/web/util/LinkUtil.java +++ b/spring-boot-rest/src/main/java/com/baeldung/web/util/LinkUtil.java @@ -1,6 +1,6 @@ package com.baeldung.web.util; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; /** * Provides some constants and utility methods to build a Link Header to be stored in the {@link HttpServletResponse} object diff --git a/spring-boot-rest/src/test/java/com/baeldung/common/web/AbstractBasicLiveTest.java b/spring-boot-rest/src/test/java/com/baeldung/common/web/AbstractBasicLiveTest.java index 6e50f828de..70208658f1 100644 --- a/spring-boot-rest/src/test/java/com/baeldung/common/web/AbstractBasicLiveTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/common/web/AbstractBasicLiveTest.java @@ -9,7 +9,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertTrue; import java.io.Serializable; diff --git a/spring-boot-rest/src/test/java/com/baeldung/common/web/AbstractDiscoverabilityLiveTest.java b/spring-boot-rest/src/test/java/com/baeldung/common/web/AbstractDiscoverabilityLiveTest.java index fc581f2631..c2eaa11849 100644 --- a/spring-boot-rest/src/test/java/com/baeldung/common/web/AbstractDiscoverabilityLiveTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/common/web/AbstractDiscoverabilityLiveTest.java @@ -4,7 +4,7 @@ import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import java.io.Serializable; diff --git a/spring-boot-rest/src/test/java/com/baeldung/rest/GithubBasicLiveTest.java b/spring-boot-rest/src/test/java/com/baeldung/rest/GithubBasicLiveTest.java index 3082b34421..430b6116d1 100644 --- a/spring-boot-rest/src/test/java/com/baeldung/rest/GithubBasicLiveTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/rest/GithubBasicLiveTest.java @@ -3,7 +3,7 @@ package com.baeldung.rest; import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import java.io.IOException; diff --git a/spring-boot-rest/src/test/java/com/baeldung/springhateoas/CustomerControllerIntegrationTest.java b/spring-boot-rest/src/test/java/com/baeldung/springhateoas/CustomerControllerIntegrationTest.java index 644ce5132a..2c0da4af39 100644 --- a/spring-boot-rest/src/test/java/com/baeldung/springhateoas/CustomerControllerIntegrationTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/springhateoas/CustomerControllerIntegrationTest.java @@ -86,7 +86,7 @@ public class CustomerControllerIntegrationTest { List orders = Collections.singletonList(order1); given(this.orderService.getAllOrdersForCustomer(DEFAULT_CUSTOMER_ID)).willReturn(orders); - this.mvc.perform(get("/customers/").accept(MediaTypes.HAL_JSON_VALUE)) + this.mvc.perform(get("/customers").accept(MediaTypes.HAL_JSON_VALUE)) .andExpect(status().isOk()) .andExpect( jsonPath("$._embedded.customers[0]._links.self.href", is("http://localhost/customers/customer1"))) diff --git a/spring-boot-rest/src/test/java/com/baeldung/web/FooControllerCustomEtagIntegrationTest.java b/spring-boot-rest/src/test/java/com/baeldung/web/FooControllerCustomEtagIntegrationTest.java index e472d308e8..a6de23a7d1 100644 --- a/spring-boot-rest/src/test/java/com/baeldung/web/FooControllerCustomEtagIntegrationTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/web/FooControllerCustomEtagIntegrationTest.java @@ -29,7 +29,7 @@ public class FooControllerCustomEtagIntegrationTest { @Autowired private MockMvc mvc; - private String FOOS_ENDPOINT = "/foos/"; + private String FOOS_ENDPOINT = "/foos"; private String CUSTOM_ETAG_ENDPOINT_SUFFIX = "/custom-etag"; private static String serializeFoo(Foo foo) throws Exception { diff --git a/spring-boot-rest/src/test/java/com/baeldung/web/FooMessageConvertersLiveTest.java b/spring-boot-rest/src/test/java/com/baeldung/web/FooMessageConvertersLiveTest.java index 9b1a9e9733..8e093a90ae 100644 --- a/spring-boot-rest/src/test/java/com/baeldung/web/FooMessageConvertersLiveTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/web/FooMessageConvertersLiveTest.java @@ -4,7 +4,7 @@ import static com.baeldung.Consts.APPLICATION_PORT; import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.baeldung.common.web.AbstractLiveTest; import com.baeldung.persistence.model.Foo; diff --git a/spring-boot-rest/src/test/java/com/baeldung/web/FooPageableLiveTest.java b/spring-boot-rest/src/test/java/com/baeldung/web/FooPageableLiveTest.java index 242fbb609e..cb7786b097 100644 --- a/spring-boot-rest/src/test/java/com/baeldung/web/FooPageableLiveTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/web/FooPageableLiveTest.java @@ -5,7 +5,7 @@ import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; import static org.apache.commons.lang3.RandomStringUtils.randomNumeric; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import java.util.List; From f4e2bd8e39e56db65d5a6474da2be504520452df Mon Sep 17 00:00:00 2001 From: Sam Gardner Date: Mon, 22 Jan 2024 14:36:04 +0000 Subject: [PATCH 089/132] BAEL-7382 Add date operations 4 to parent pom --- core-java-modules/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index f4722855bc..ec6c8bcb3c 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -112,6 +112,7 @@ core-java-datetime-string-2 core-java-date-operations-2 core-java-date-operations-3 + core-java-date-operations-4 core-java-documentation core-java-exceptions core-java-exceptions-2 From f3e944ebd7eeb8926202180315afc770942fd012 Mon Sep 17 00:00:00 2001 From: Sam Gardner Date: Mon, 22 Jan 2024 15:02:39 +0000 Subject: [PATCH 090/132] BAEL-7382 Use JUnit 5 for tests --- .../CalculateWeekdaysUnitTest.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/core-java-modules/core-java-date-operations-4/src/test/java/com/baeldung/calculateweekdays/CalculateWeekdaysUnitTest.java b/core-java-modules/core-java-date-operations-4/src/test/java/com/baeldung/calculateweekdays/CalculateWeekdaysUnitTest.java index 4a14b6bb99..05a2202682 100644 --- a/core-java-modules/core-java-date-operations-4/src/test/java/com/baeldung/calculateweekdays/CalculateWeekdaysUnitTest.java +++ b/core-java-modules/core-java-date-operations-4/src/test/java/com/baeldung/calculateweekdays/CalculateWeekdaysUnitTest.java @@ -4,7 +4,7 @@ import static junit.framework.TestCase.assertEquals; import java.time.LocalDate; -import org.junit.Test; +import org.junit.jupiter.api.Test; public class CalculateWeekdaysUnitTest { @@ -25,56 +25,56 @@ public class CalculateWeekdaysUnitTest { LocalDate endThreeWeeksWeekend = LocalDate.of(2023, 12, 9); @Test - public void givenTwoDaysOnSameWeekend_whenUsingStreams_calculateWeekdays(){ + void givenTwoDaysOnSameWeekend_whenUsingStreams_thenCalculateWeekdays(){ CalculateWeekdays c = new CalculateWeekdays(); long result = c.getWorkingDaysWithStream(startTomorrow, endTomorrow); assertEquals(0, result); } @Test - public void givenTwoDaysOnSameWeekend_whenUsingMaths_calculateWeekdays(){ + void givenTwoDaysOnSameWeekend_whenUsingMaths_thenCalculateWeekdays(){ CalculateWeekdays c = new CalculateWeekdays(); long result = c.getWorkingDaysWithoutStream(startTomorrow, endTomorrow); assertEquals(0, result); } @Test - public void givenAThreeWeekGapMidweekDates_whenUsingStreams_calculateWeekdays(){ + void givenAThreeWeekGapMidweekDates_whenUsingStreams_thenCalculateWeekdays(){ CalculateWeekdays c = new CalculateWeekdays(); long result = c.getWorkingDaysWithStream(startThreeWeeks, endThreeWeeks); assertEquals(17, result); } @Test - public void givenAThreeWeekGapMidweekDates_whenUsingMaths_calculateWeekdays(){ + void givenAThreeWeekGapMidweekDates_whenUsingMaths_thenCalculateWeekdays(){ CalculateWeekdays c = new CalculateWeekdays(); long result = c.getWorkingDaysWithoutStream(startThreeWeeks, endThreeWeeks); assertEquals(17, result); } @Test - public void givenThreeWeekGapMidweekAndWeekendDates_whenUsingStreams_calculateWeekdays(){ + void givenThreeWeekGapMidweekAndWeekendDates_whenUsingStreams_thenCalculateWeekdays(){ CalculateWeekdays c = new CalculateWeekdays(); long result = c.getWorkingDaysWithStream(startThreeWeeksWeekend, endThreeWeeksWeekend); assertEquals(5, result); } @Test - public void givenThreeWeekGapMidweekAndWeekendDates_whenUsingMaths_calculateWeekdays(){ + void givenThreeWeekGapMidweekAndWeekendDates_whenUsingMaths_thenCalculateWeekdays(){ CalculateWeekdays c = new CalculateWeekdays(); long result = c.getWorkingDaysWithoutStream(startThreeWeeksWeekend, endThreeWeeksWeekend); assertEquals(5, result); } @Test - public void givenThreeWeekGapWeekendDates_whenUsingStreams_calculateWeekdays(){ + void givenThreeWeekGapWeekendDates_whenUsingStreams_thenCalculateWeekdays(){ CalculateWeekdays c = new CalculateWeekdays(); long result = c.getWorkingDaysWithStream(startThreeWeeks2, endThreeWeeks2); assertEquals(40, result); } @Test - public void givenThreeWeekGapWeekendDates_whenUsingMaths_calculateWeekdays(){ + void givenThreeWeekGapWeekendDates_whenUsingMaths_thenCalculateWeekdays(){ CalculateWeekdays c = new CalculateWeekdays(); long result = c.getWorkingDaysWithoutStream(startThreeWeeks2, endThreeWeeks2); assertEquals(40, result); From a3956ce15c73f56f81aeab8875f6da46f877bdee Mon Sep 17 00:00:00 2001 From: parthiv39731 <70740707+parthiv39731@users.noreply.github.com> Date: Mon, 22 Jan 2024 21:59:56 +0530 Subject: [PATCH 091/132] BAEL-7388, fixed class diagram --- .../src/main/resources/builder-pattern.puml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/patterns-modules/design-patterns-creational-2/src/main/resources/builder-pattern.puml b/patterns-modules/design-patterns-creational-2/src/main/resources/builder-pattern.puml index dbc9297ede..0e7b9717f8 100644 --- a/patterns-modules/design-patterns-creational-2/src/main/resources/builder-pattern.puml +++ b/patterns-modules/design-patterns-creational-2/src/main/resources/builder-pattern.puml @@ -45,12 +45,12 @@ class ElectricCarBuilder { +batteryType(String batteryType): ElectricCarBuilder } CarBuilder -left-|> VehicleBuilder: extends -ElectricCarBuilder <|-left- CarBuilder: extends +ElectricCarBuilder -left-|> CarBuilder: extends VehicleBuilder -down-> Vehicle: builds CarBuilder -down-> Car:builds ElectricCarBuilder -down-> ElectricCar: builds -Vehicle -right-|> Car: extends +Vehicle <|-right- Car: extends Car <|-right- ElectricCar: extends @enduml \ No newline at end of file From f6806580ae1fb46b111128931a4cb9295fb67543 Mon Sep 17 00:00:00 2001 From: ovidiumihaitacu <138307181+ovidiumihaitacu@users.noreply.github.com> Date: Mon, 22 Jan 2024 20:09:24 +0200 Subject: [PATCH 092/132] [BAEL-7257] Monkey-Patching in Java (#15700) --- patterns-modules/monkey-patching/README.md | 1 + patterns-modules/monkey-patching/pom.xml | 44 +++++++++++++++++++ .../baeldung/monkey/patching/Application.java | 12 +++++ .../patching/aop/BeanConfiguration.java | 15 +++++++ .../monkey/patching/aop/LoggingAspect.java | 22 ++++++++++ .../patching/converter/MoneyConverter.java | 5 +++ .../converter/MoneyConverterImpl.java | 15 +++++++ .../decorator/MoneyConverterDecorator.java | 21 +++++++++ .../proxy/LoggingInvocationHandler.java | 21 +++++++++ .../aop/LoggingAspectIntegrationTest.java | 35 +++++++++++++++ .../converter/MoneyConverterUnitTest.java | 17 +++++++ .../MoneyConverterDecoratorUnitTest.java | 28 ++++++++++++ .../LoggingInvocationHandlerUnitTest.java | 34 ++++++++++++++ .../reflection/ReflectionUnitTest.java | 24 ++++++++++ patterns-modules/pom.xml | 1 + 15 files changed, 295 insertions(+) create mode 100644 patterns-modules/monkey-patching/README.md create mode 100644 patterns-modules/monkey-patching/pom.xml create mode 100644 patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/Application.java create mode 100644 patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/aop/BeanConfiguration.java create mode 100644 patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/aop/LoggingAspect.java create mode 100644 patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/converter/MoneyConverter.java create mode 100644 patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/converter/MoneyConverterImpl.java create mode 100644 patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/decorator/MoneyConverterDecorator.java create mode 100644 patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/proxy/LoggingInvocationHandler.java create mode 100644 patterns-modules/monkey-patching/src/test/java/com/baeldung/monkey/patching/aop/LoggingAspectIntegrationTest.java create mode 100644 patterns-modules/monkey-patching/src/test/java/com/baeldung/monkey/patching/converter/MoneyConverterUnitTest.java create mode 100644 patterns-modules/monkey-patching/src/test/java/com/baeldung/monkey/patching/decorator/MoneyConverterDecoratorUnitTest.java create mode 100644 patterns-modules/monkey-patching/src/test/java/com/baeldung/monkey/patching/proxy/LoggingInvocationHandlerUnitTest.java create mode 100644 patterns-modules/monkey-patching/src/test/java/com/baeldung/monkey/patching/reflection/ReflectionUnitTest.java diff --git a/patterns-modules/monkey-patching/README.md b/patterns-modules/monkey-patching/README.md new file mode 100644 index 0000000000..7d843af9ea --- /dev/null +++ b/patterns-modules/monkey-patching/README.md @@ -0,0 +1 @@ +### Relevant Articles: diff --git a/patterns-modules/monkey-patching/pom.xml b/patterns-modules/monkey-patching/pom.xml new file mode 100644 index 0000000000..e7fae87646 --- /dev/null +++ b/patterns-modules/monkey-patching/pom.xml @@ -0,0 +1,44 @@ + + + 4.0.0 + com.baeldung + monkey-patching + 1.0.0-SNAPSHOT + monkey-patching + jar + + + com.baeldung + patterns-modules + 1.0.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + 2.7.0 + + + org.springframework.boot + spring-boot-starter-test + 2.7.0 + + + org.springframework.boot + spring-boot-starter-aop + 2.7.0 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/Application.java b/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/Application.java new file mode 100644 index 0000000000..6c586b1c84 --- /dev/null +++ b/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/Application.java @@ -0,0 +1,12 @@ +package com.baeldung.monkey.patching; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} \ No newline at end of file diff --git a/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/aop/BeanConfiguration.java b/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/aop/BeanConfiguration.java new file mode 100644 index 0000000000..dff55dc008 --- /dev/null +++ b/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/aop/BeanConfiguration.java @@ -0,0 +1,15 @@ +package com.baeldung.monkey.patching.aop; + +import com.baeldung.monkey.patching.converter.MoneyConverter; +import com.baeldung.monkey.patching.converter.MoneyConverterImpl; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class BeanConfiguration { + + @Bean + public MoneyConverter moneyConverter() { + return new MoneyConverterImpl(); + } +} diff --git a/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/aop/LoggingAspect.java b/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/aop/LoggingAspect.java new file mode 100644 index 0000000000..bbceb581c6 --- /dev/null +++ b/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/aop/LoggingAspect.java @@ -0,0 +1,22 @@ +package com.baeldung.monkey.patching.aop; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.After; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.springframework.stereotype.Component; + +@Aspect +@Component +public class LoggingAspect { + + @Before("execution(* com.baeldung.monkey.patching.converter.MoneyConverter.convertEURtoUSD(..))") + public void beforeConvertEURtoUSD(JoinPoint joinPoint) { + System.out.println("Before method: " + joinPoint.getSignature().getName()); + } + + @After("execution(* com.baeldung.monkey.patching.converter.MoneyConverter.convertEURtoUSD(..))") + public void afterConvertEURtoUSD(JoinPoint joinPoint) { + System.out.println("After method: " + joinPoint.getSignature().getName()); + } +} \ No newline at end of file diff --git a/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/converter/MoneyConverter.java b/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/converter/MoneyConverter.java new file mode 100644 index 0000000000..97e32aaa61 --- /dev/null +++ b/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/converter/MoneyConverter.java @@ -0,0 +1,5 @@ +package com.baeldung.monkey.patching.converter; + +public interface MoneyConverter { + double convertEURtoUSD(double amount); +} diff --git a/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/converter/MoneyConverterImpl.java b/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/converter/MoneyConverterImpl.java new file mode 100644 index 0000000000..86071341c9 --- /dev/null +++ b/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/converter/MoneyConverterImpl.java @@ -0,0 +1,15 @@ +package com.baeldung.monkey.patching.converter; + +public class MoneyConverterImpl implements MoneyConverter { + + private final double conversionRate; + + public MoneyConverterImpl() { + this.conversionRate = 1.10; + } + + @Override + public double convertEURtoUSD(double amount) { + return amount * conversionRate; + } +} diff --git a/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/decorator/MoneyConverterDecorator.java b/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/decorator/MoneyConverterDecorator.java new file mode 100644 index 0000000000..81c86f136e --- /dev/null +++ b/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/decorator/MoneyConverterDecorator.java @@ -0,0 +1,21 @@ +package com.baeldung.monkey.patching.decorator; + +import com.baeldung.monkey.patching.converter.MoneyConverter; + +public class MoneyConverterDecorator implements MoneyConverter { + + private final MoneyConverter moneyConverter; + + public MoneyConverterDecorator(MoneyConverter moneyConverter) { + this.moneyConverter = moneyConverter; + } + + @Override + public double convertEURtoUSD(double amount) { + + System.out.println("Before method: convertEURtoUSD"); + double result = moneyConverter.convertEURtoUSD(amount); + System.out.println("After method: convertEURtoUSD"); + return result; + } +} diff --git a/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/proxy/LoggingInvocationHandler.java b/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/proxy/LoggingInvocationHandler.java new file mode 100644 index 0000000000..266738e514 --- /dev/null +++ b/patterns-modules/monkey-patching/src/main/java/com/baeldung/monkey/patching/proxy/LoggingInvocationHandler.java @@ -0,0 +1,21 @@ +package com.baeldung.monkey.patching.proxy; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +public class LoggingInvocationHandler implements InvocationHandler { + + private final Object target; + + public LoggingInvocationHandler(Object target) { + this.target = target; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + System.out.println("Before method: " + method.getName()); + Object result = method.invoke(target, args); + System.out.println("After method: " + method.getName()); + return result; + } +} diff --git a/patterns-modules/monkey-patching/src/test/java/com/baeldung/monkey/patching/aop/LoggingAspectIntegrationTest.java b/patterns-modules/monkey-patching/src/test/java/com/baeldung/monkey/patching/aop/LoggingAspectIntegrationTest.java new file mode 100644 index 0000000000..da185f654a --- /dev/null +++ b/patterns-modules/monkey-patching/src/test/java/com/baeldung/monkey/patching/aop/LoggingAspectIntegrationTest.java @@ -0,0 +1,35 @@ +package com.baeldung.monkey.patching.aop; + +import com.baeldung.monkey.patching.converter.MoneyConverter; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import static org.junit.Assert.assertTrue; + +@SpringBootTest +@RunWith(SpringRunner.class) +public class LoggingAspectIntegrationTest { + + @Autowired + private MoneyConverter moneyConverter; + + @Test + public void whenMethodCalled_thenSurroundedByLogs() { + ByteArrayOutputStream logOutputStream = new ByteArrayOutputStream(); + System.setOut(new PrintStream(logOutputStream)); + + double result = moneyConverter.convertEURtoUSD(10); + + Assertions.assertEquals(11, result); + String logOutput = logOutputStream.toString(); + assertTrue(logOutput.contains("Before method: convertEURtoUSD")); + assertTrue(logOutput.contains("After method: convertEURtoUSD")); + } +} diff --git a/patterns-modules/monkey-patching/src/test/java/com/baeldung/monkey/patching/converter/MoneyConverterUnitTest.java b/patterns-modules/monkey-patching/src/test/java/com/baeldung/monkey/patching/converter/MoneyConverterUnitTest.java new file mode 100644 index 0000000000..bf6cfe58e8 --- /dev/null +++ b/patterns-modules/monkey-patching/src/test/java/com/baeldung/monkey/patching/converter/MoneyConverterUnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.monkey.patching.converter; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class MoneyConverterUnitTest { + + @Test + void whenMoneyConverter_thenResultIsCorrect() { + MoneyConverterImpl moneyConverter = new MoneyConverterImpl(); + + double result = moneyConverter.convertEURtoUSD(10); + + assertEquals(11, result); + } +} \ No newline at end of file diff --git a/patterns-modules/monkey-patching/src/test/java/com/baeldung/monkey/patching/decorator/MoneyConverterDecoratorUnitTest.java b/patterns-modules/monkey-patching/src/test/java/com/baeldung/monkey/patching/decorator/MoneyConverterDecoratorUnitTest.java new file mode 100644 index 0000000000..24013f0ce7 --- /dev/null +++ b/patterns-modules/monkey-patching/src/test/java/com/baeldung/monkey/patching/decorator/MoneyConverterDecoratorUnitTest.java @@ -0,0 +1,28 @@ +package com.baeldung.monkey.patching.decorator; + +import com.baeldung.monkey.patching.converter.MoneyConverter; +import com.baeldung.monkey.patching.converter.MoneyConverterImpl; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import static org.junit.Assert.assertTrue; + +public class MoneyConverterDecoratorUnitTest { + + @Test + public void whenMethodCalled_thenSurroundedByLogs() { + ByteArrayOutputStream logOutputStream = new ByteArrayOutputStream(); + System.setOut(new PrintStream(logOutputStream)); + MoneyConverter moneyConverter = new MoneyConverterDecorator(new MoneyConverterImpl()); + + double result = moneyConverter.convertEURtoUSD(10); + + Assertions.assertEquals(11, result); + String logOutput = logOutputStream.toString(); + assertTrue(logOutput.contains("Before method: convertEURtoUSD")); + assertTrue(logOutput.contains("After method: convertEURtoUSD")); + } +} diff --git a/patterns-modules/monkey-patching/src/test/java/com/baeldung/monkey/patching/proxy/LoggingInvocationHandlerUnitTest.java b/patterns-modules/monkey-patching/src/test/java/com/baeldung/monkey/patching/proxy/LoggingInvocationHandlerUnitTest.java new file mode 100644 index 0000000000..7b6f49b9c5 --- /dev/null +++ b/patterns-modules/monkey-patching/src/test/java/com/baeldung/monkey/patching/proxy/LoggingInvocationHandlerUnitTest.java @@ -0,0 +1,34 @@ +package com.baeldung.monkey.patching.proxy; + +import com.baeldung.monkey.patching.converter.MoneyConverter; +import com.baeldung.monkey.patching.converter.MoneyConverterImpl; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.lang.reflect.Proxy; + +import static org.junit.Assert.assertTrue; + +public class LoggingInvocationHandlerUnitTest { + + @Test + public void whenMethodCalled_thenSurroundedByLogs() { + ByteArrayOutputStream logOutputStream = new ByteArrayOutputStream(); + System.setOut(new PrintStream(logOutputStream)); + MoneyConverter moneyConverter = new MoneyConverterImpl(); + MoneyConverter proxy = (MoneyConverter) Proxy.newProxyInstance( + MoneyConverter.class.getClassLoader(), + new Class[]{MoneyConverter.class}, + new LoggingInvocationHandler(moneyConverter) + ); + + double result = proxy.convertEURtoUSD(10); + + Assertions.assertEquals(11, result); + String logOutput = logOutputStream.toString(); + assertTrue(logOutput.contains("Before method: convertEURtoUSD")); + assertTrue(logOutput.contains("After method: convertEURtoUSD")); + } +} diff --git a/patterns-modules/monkey-patching/src/test/java/com/baeldung/monkey/patching/reflection/ReflectionUnitTest.java b/patterns-modules/monkey-patching/src/test/java/com/baeldung/monkey/patching/reflection/ReflectionUnitTest.java new file mode 100644 index 0000000000..4729f05802 --- /dev/null +++ b/patterns-modules/monkey-patching/src/test/java/com/baeldung/monkey/patching/reflection/ReflectionUnitTest.java @@ -0,0 +1,24 @@ +package com.baeldung.monkey.patching.reflection; + +import com.baeldung.monkey.patching.converter.MoneyConverter; +import com.baeldung.monkey.patching.converter.MoneyConverterImpl; +import org.junit.Test; + +import java.lang.reflect.Field; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ReflectionUnitTest { + +@Test +public void givenPrivateField_whenUsingReflection_thenBehaviorCanBeChanged() throws IllegalAccessException, NoSuchFieldException { + MoneyConverter moneyConvertor = new MoneyConverterImpl(); + + Field conversionRate = MoneyConverterImpl.class.getDeclaredField("conversionRate"); + conversionRate.setAccessible(true); + conversionRate.set(moneyConvertor, 1.2); + double result = moneyConvertor.convertEURtoUSD(10); + + assertEquals(12, result); +} +} diff --git a/patterns-modules/pom.xml b/patterns-modules/pom.xml index 7dd26ac31c..a32779a9d8 100644 --- a/patterns-modules/pom.xml +++ b/patterns-modules/pom.xml @@ -35,6 +35,7 @@ idd intercepting-filter solid + monkey-patching From 2b82e913a6622738e4f32a6b0e2066f3b774eac9 Mon Sep 17 00:00:00 2001 From: Mo Helmy <135069400+BenHelmyBen@users.noreply.github.com> Date: Mon, 22 Jan 2024 20:18:56 +0200 Subject: [PATCH 093/132] Update CheckIfStringContainsInvalidEncodedCharactersUnitTest.java (#15703) Update: assertTrue(found ? true : false); to assertTrue(found); and assertTrue(matcher.find() ? true : false); to assertTrue(matcher.find()); --- ...CheckIfStringContainsInvalidEncodedCharactersUnitTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/checkifstringcontainsinvalidcharacters/CheckIfStringContainsInvalidEncodedCharactersUnitTest.java b/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/checkifstringcontainsinvalidcharacters/CheckIfStringContainsInvalidEncodedCharactersUnitTest.java index ffa7f54dd3..249587b56a 100644 --- a/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/checkifstringcontainsinvalidcharacters/CheckIfStringContainsInvalidEncodedCharactersUnitTest.java +++ b/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/checkifstringcontainsinvalidcharacters/CheckIfStringContainsInvalidEncodedCharactersUnitTest.java @@ -18,7 +18,7 @@ public class CheckIfStringContainsInvalidEncodedCharactersUnitTest { String regexPattern = "[^\\x00-\\x7F]+"; Pattern pattern = Pattern.compile(regexPattern); Matcher matcher = pattern.matcher(input); - assertTrue(matcher.find() ? true : false); + assertTrue(matcher.find()); } @Test @@ -28,6 +28,6 @@ public class CheckIfStringContainsInvalidEncodedCharactersUnitTest { for (byte b : bytes) { found = (b & 0xFF) > 127 ? true : found; } - assertTrue(found ? true : false); + assertTrue(found); } } From b6c126b1830adfa88d9d0671c45183262e81a0ce Mon Sep 17 00:00:00 2001 From: Eugene Kovko <37694937+eukovko@users.noreply.github.com> Date: Mon, 22 Jan 2024 19:33:11 +0100 Subject: [PATCH 094/132] Bael 7231 (#15707) * feat: Simple test with Junit Pioneer * feat: Simple test for PATH env variable * feat: Test for getting all the environment variables * feat: Guardrails for an environment test * feat: Fixed the test * feat: Test for reflexive access to the environment * feat: Renamed a test * feat: Renamed a utility method * feat: Removed unused import * feat: Renamed a test class * feat: Child process runner * feat: Method and tag rename * feat: Docker example * feat: Testcontainer example * feat: Cleanup and renames * feat: Cleanup and renames * feat: Prevent Docker test from running * feat: Change assertion to JUnit to prevent adding assertj into the container * feat: Renamed constants * feat: Fixed the naming problem * feat: Changed conditional execution * feat: Changed conditional execution * feat: Changed conditional execution --- core-java-modules/core-java-lang-6/Dockerfile | 7 ++ .../core-java-lang-6/docker-pom.xml | 42 ++++++++++ core-java-modules/core-java-lang-6/pom.xml | 23 +++++ ...ildProcessEnvironmentVariableUnitTest.java | 44 ++++++++++ ...tingDockerEnvironmentVariableUnitTest.java | 19 +++++ ...ameProcessEnvironmentVariableUnitTest.java | 83 +++++++++++++++++++ .../SettingTestcontainerVariableUnitTest.java | 31 +++++++ 7 files changed, 249 insertions(+) create mode 100644 core-java-modules/core-java-lang-6/Dockerfile create mode 100644 core-java-modules/core-java-lang-6/docker-pom.xml create mode 100644 core-java-modules/core-java-lang-6/src/test/java/com/baeldung/setenvironment/SettingChildProcessEnvironmentVariableUnitTest.java create mode 100644 core-java-modules/core-java-lang-6/src/test/java/com/baeldung/setenvironment/SettingDockerEnvironmentVariableUnitTest.java create mode 100644 core-java-modules/core-java-lang-6/src/test/java/com/baeldung/setenvironment/SettingSameProcessEnvironmentVariableUnitTest.java create mode 100644 core-java-modules/core-java-lang-6/src/test/java/com/baeldung/setenvironment/SettingTestcontainerVariableUnitTest.java diff --git a/core-java-modules/core-java-lang-6/Dockerfile b/core-java-modules/core-java-lang-6/Dockerfile new file mode 100644 index 0000000000..60c052f79f --- /dev/null +++ b/core-java-modules/core-java-lang-6/Dockerfile @@ -0,0 +1,7 @@ +FROM maven:3.9-amazoncorretto-17 +WORKDIR /app +COPY /src/test/java/com/baeldung/setenvironment/SettingDockerEnvironmentVariableUnitTest.java \ + ./src/test/java/com/baeldung/setenvironment/ +COPY /docker-pom.xml ./ +ENV CUSTOM_DOCKER_ENV_VARIABLE=TRUE +ENTRYPOINT mvn -f docker-pom.xml test \ No newline at end of file diff --git a/core-java-modules/core-java-lang-6/docker-pom.xml b/core-java-modules/core-java-lang-6/docker-pom.xml new file mode 100644 index 0000000000..5977480664 --- /dev/null +++ b/core-java-modules/core-java-lang-6/docker-pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + com.baeldung.core-java-modules + core-java-lang-6 + 0.0.1-SNAPSHOT + + + + org.testcontainers + testcontainers + ${testcontainers.junit.version} + test + + + org.testcontainers + junit-jupiter + ${testcontainers.junit.version} + test + + + org.junit.jupiter + junit-jupiter-api + 5.10.1 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.10.1 + test + + + + + 1.19.3 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-lang-6/pom.xml b/core-java-modules/core-java-lang-6/pom.xml index accb014963..7bf2fafaa1 100644 --- a/core-java-modules/core-java-lang-6/pom.xml +++ b/core-java-modules/core-java-lang-6/pom.xml @@ -33,6 +33,25 @@ jmh-generator-annprocess ${jmh.version} + + org.junit-pioneer + junit-pioneer + ${junit.pioneer.version} + test + + + org.testcontainers + testcontainers + ${testcontaienr.version} + test + + + org.testcontainers + junit-jupiter + ${testcontaienr.version} + test + + @@ -53,6 +72,8 @@ ${jmh.version} + 14 + 14 @@ -61,6 +82,8 @@ 1.6.0.Beta1 1.37 + 2.2.0 + 1.19.3 \ No newline at end of file diff --git a/core-java-modules/core-java-lang-6/src/test/java/com/baeldung/setenvironment/SettingChildProcessEnvironmentVariableUnitTest.java b/core-java-modules/core-java-lang-6/src/test/java/com/baeldung/setenvironment/SettingChildProcessEnvironmentVariableUnitTest.java new file mode 100644 index 0000000000..609f6be739 --- /dev/null +++ b/core-java-modules/core-java-lang-6/src/test/java/com/baeldung/setenvironment/SettingChildProcessEnvironmentVariableUnitTest.java @@ -0,0 +1,44 @@ +package com.baeldung.setenvironment; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.util.Map; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; + +class SettingChildProcessEnvironmentVariableUnitTest { + + public static final String ENVIRONMENT_VARIABLE_NAME = "test"; + public static final String ENVIRONMENT_VARIABLE_VALUE = "Hello World"; + public static final String CHILD_PROCESS_CONDITION = "CHILD_PROCESS_TEST"; + public static final String CHILD_PROCESS_VALUE = "true"; + public static final String CHILD_PROCESS_TAG = "child_process"; + public static final String TAG = String.format("-Dgroups=%s", CHILD_PROCESS_TAG); + private final String testClass = String.format("-Dtest=%s", getClass().getName()); + private final String[] arguments = {"mvn", "test", TAG, testClass}; + + @Test + void givenChildProcessTestRunner_whenRunTheTest_thenAllSucceed() + throws IOException, InterruptedException { + ProcessBuilder processBuilder = new ProcessBuilder(); + processBuilder.inheritIO(); + + Map environment = processBuilder.environment(); + environment.put(CHILD_PROCESS_CONDITION, CHILD_PROCESS_VALUE); + environment.put(ENVIRONMENT_VARIABLE_NAME, ENVIRONMENT_VARIABLE_VALUE); + Process process = processBuilder.command(arguments).start(); + + int errorCode = process.waitFor(); + assertThat(errorCode).isZero(); + } + + @Test + @EnabledIfEnvironmentVariable(named = CHILD_PROCESS_CONDITION, matches = CHILD_PROCESS_VALUE) + @Tag(CHILD_PROCESS_TAG) + void givenChildProcess_whenGetEnvironmentVariable_thenReturnsCorrectValue() { + String actual = System.getenv(ENVIRONMENT_VARIABLE_NAME); + assertThat(actual).isEqualTo(ENVIRONMENT_VARIABLE_VALUE); + } +} diff --git a/core-java-modules/core-java-lang-6/src/test/java/com/baeldung/setenvironment/SettingDockerEnvironmentVariableUnitTest.java b/core-java-modules/core-java-lang-6/src/test/java/com/baeldung/setenvironment/SettingDockerEnvironmentVariableUnitTest.java new file mode 100644 index 0000000000..5621b431a8 --- /dev/null +++ b/core-java-modules/core-java-lang-6/src/test/java/com/baeldung/setenvironment/SettingDockerEnvironmentVariableUnitTest.java @@ -0,0 +1,19 @@ +package com.baeldung.setenvironment; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; + +class SettingDockerEnvironmentVariableUnitTest { + + public static final String ENV_VARIABLE_NAME = "CUSTOM_DOCKER_ENV_VARIABLE"; + public static final String ENV_VARIABLE_VALUE = "TRUE"; + + @Test + @EnabledIfEnvironmentVariable(named = ENV_VARIABLE_NAME, matches = ENV_VARIABLE_VALUE) + void givenDockerEnvironment_whenGetEnvironmentVariable_thenReturnsCorrectValue() { + String actual = System.getenv(ENV_VARIABLE_NAME); + assertEquals(ENV_VARIABLE_VALUE, actual); + } +} diff --git a/core-java-modules/core-java-lang-6/src/test/java/com/baeldung/setenvironment/SettingSameProcessEnvironmentVariableUnitTest.java b/core-java-modules/core-java-lang-6/src/test/java/com/baeldung/setenvironment/SettingSameProcessEnvironmentVariableUnitTest.java new file mode 100644 index 0000000000..dacd351c83 --- /dev/null +++ b/core-java-modules/core-java-lang-6/src/test/java/com/baeldung/setenvironment/SettingSameProcessEnvironmentVariableUnitTest.java @@ -0,0 +1,83 @@ +package com.baeldung.setenvironment; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.lang.reflect.Field; +import java.util.Collections; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledForJreRange; +import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; +import org.junit.jupiter.api.condition.JRE; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junitpioneer.jupiter.SetEnvironmentVariable; + +class SettingSameProcessEnvironmentVariableUnitTest { + + private static final String PROCESS_ENVIRONMENT = "java.lang.ProcessEnvironment"; + private static final String ENVIRONMENT = "theUnmodifiableEnvironment"; + private static final String SOURCE_MAP = "m"; + private static final Object STATIC_METHOD = null; + private static final Class UMODIFIABLE_MAP_CLASS + = Collections.unmodifiableMap(Collections.emptyMap()).getClass(); + private static final Class MAP_CLASS = Map.class; + public static final String ENV_VARIABLE_NAME = "test"; + public static final String ENB_VARIABLE_VALUE = "Hello World"; + + @ParameterizedTest + @CsvSource({ENB_VARIABLE_VALUE + "," + ENV_VARIABLE_NAME}) + @EnabledForJreRange(max = JRE.JAVA_16) + void givenReflexiveAccess_whenGetSourceMap_thenSuccessfullyModifyVariables(String environmentVariable, String value) + throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { + Map modifiableEnvironment = getModifiableEnvironment(); + assertThat(modifiableEnvironment).isNotNull(); + + modifiableEnvironment.put(environmentVariable, value); + String actual = modifiableEnvironment.get(environmentVariable); + assertThat(actual).isEqualTo(value); + } + + @Test + @EnabledIfEnvironmentVariable(named = "PATH", matches = ".*", + disabledReason = "The test relies on the presence of PATH variable") + void givenOS_whenGetPath_thenVariableIsPresent() { + String classPath = System.getenv("PATH"); + assertThat(classPath).isNotNull(); + } + + @Test + void givenOS_whenGetPath_thenVariablesArePresent() { + Map environment = System.getenv(); + assertThat(environment).isNotNull(); + } + + @Test + @SetEnvironmentVariable(key = ENV_VARIABLE_NAME, value = ENB_VARIABLE_VALUE) + @EnabledForJreRange(max = JRE.JAVA_16) + void givenVariableSet_whenGetEnvironmentVariable_thenReturnsCorrectValue() { + String actual = System.getenv(ENV_VARIABLE_NAME); + assertThat(actual).isEqualTo(ENB_VARIABLE_VALUE); + } + + @SuppressWarnings("unchecked") + private static Map getModifiableEnvironment() + throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { + Class environmentClass = Class.forName(PROCESS_ENVIRONMENT); + Field environmentField = environmentClass.getDeclaredField(ENVIRONMENT); + assertThat(environmentField).isNotNull(); + environmentField.setAccessible(true); + + Object unmodifiableEnvironmentMap = environmentField.get(STATIC_METHOD); + assertThat(unmodifiableEnvironmentMap).isNotNull(); + assertThat(unmodifiableEnvironmentMap).isInstanceOf(UMODIFIABLE_MAP_CLASS); + + Field underlyingMapField = unmodifiableEnvironmentMap.getClass().getDeclaredField(SOURCE_MAP); + underlyingMapField.setAccessible(true); + Object underlyingMap = underlyingMapField.get(unmodifiableEnvironmentMap); + assertThat(underlyingMap).isNotNull(); + assertThat(underlyingMap).isInstanceOf(MAP_CLASS); + + return (Map) underlyingMap; + } +} diff --git a/core-java-modules/core-java-lang-6/src/test/java/com/baeldung/setenvironment/SettingTestcontainerVariableUnitTest.java b/core-java-modules/core-java-lang-6/src/test/java/com/baeldung/setenvironment/SettingTestcontainerVariableUnitTest.java new file mode 100644 index 0000000000..b6f9054931 --- /dev/null +++ b/core-java-modules/core-java-lang-6/src/test/java/com/baeldung/setenvironment/SettingTestcontainerVariableUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.setenvironment; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.nio.file.Path; +import java.nio.file.Paths; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.images.builder.ImageFromDockerfile; + +class SettingTestcontainerVariableUnitTest { + + public static final String CONTAINER_REPORT_FILE = "/app/target/surefire-reports/TEST-com.baeldung.setenvironment.SettingDockerEnvironmentVariableUnitTest.xml"; + public static final String HOST_REPORT_FILE = "./container-test-report.xml"; + public static final String DOCKERFILE = "./Dockerfile"; + + @Test + @Disabled("Requires working Docker environment ") + void givenTestcontainerEnvironment_whenGetEnvironmentVariable_thenReturnsCorrectValue() { + Path dockerfilePath = Paths.get(DOCKERFILE); + GenericContainer container = new GenericContainer( + new ImageFromDockerfile().withDockerfile(dockerfilePath)); + assertThat(container).isNotNull(); + container.start(); + while (container.isRunning()) { + // Busy spin + } + container.copyFileFromContainer(CONTAINER_REPORT_FILE, HOST_REPORT_FILE); + } +} From 790334d094c3dff56209de070407a37f479cd84d Mon Sep 17 00:00:00 2001 From: Amit Pandey Date: Tue, 23 Jan 2024 03:41:26 +0530 Subject: [PATCH 095/132] [JAVA-28961] Upgrade to spring-boot-data-2 module to Spring Boot 3 (#15620) --- spring-boot-modules/spring-boot-data-2/pom.xml | 8 +++++--- .../com/baeldung/boot/bootstrapmode/domain/Todo.java | 8 ++++---- .../com/baeldung/boot/readonlyrepository/Book.java | 6 +++--- .../com/baeldung/dynamicvalidation/ContactInfo.java | 4 ++-- .../dynamicvalidation/ContactInfoValidator.java | 4 ++-- .../dynamicvalidation/DynamicValidationApp.java | 2 +- .../dynamicvalidation/config/CustomerController.java | 2 +- .../dynamicvalidation/model/ContactInfoExpression.java | 6 +++--- .../com/baeldung/dynamicvalidation/model/Customer.java | 10 +++++----- .../main/java/com/baeldung/javers/domain/Address.java | 2 +- .../main/java/com/baeldung/javers/domain/Product.java | 2 +- .../main/java/com/baeldung/javers/domain/Store.java | 2 +- .../propertyeditor/PropertyEditorRestController.java | 4 ++-- .../propertyeditor/creditcard/CreditCardEditor.java | 2 +- 14 files changed, 32 insertions(+), 30 deletions(-) diff --git a/spring-boot-modules/spring-boot-data-2/pom.xml b/spring-boot-modules/spring-boot-data-2/pom.xml index 9aaab02925..41e4616a38 100644 --- a/spring-boot-modules/spring-boot-data-2/pom.xml +++ b/spring-boot-modules/spring-boot-data-2/pom.xml @@ -6,9 +6,10 @@ spring-boot-data-2 - com.baeldung.spring-boot-modules - spring-boot-modules - 1.0.0-SNAPSHOT + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -42,6 +43,7 @@ 6.6.5 + com.baeldung.boot.bootstrapmode.Application \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/bootstrapmode/domain/Todo.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/bootstrapmode/domain/Todo.java index 8d6ab3cfb8..23e9a4d483 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/bootstrapmode/domain/Todo.java +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/bootstrapmode/domain/Todo.java @@ -1,9 +1,9 @@ package com.baeldung.boot.bootstrapmode.domain; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class Todo { diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/Book.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/Book.java index ff0a8a1bb3..bb208239e3 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/Book.java +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/Book.java @@ -1,8 +1,8 @@ package com.baeldung.boot.readonlyrepository; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; @Entity public class Book diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/ContactInfo.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/ContactInfo.java index 41f873b42a..7b3139ac5f 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/ContactInfo.java +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/ContactInfo.java @@ -10,8 +10,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import javax.validation.Constraint; -import javax.validation.Payload; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; @Constraint(validatedBy = { ContactInfoValidator.class }) @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/ContactInfoValidator.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/ContactInfoValidator.java index cc05fd4fbd..331706e87a 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/ContactInfoValidator.java +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/ContactInfoValidator.java @@ -9,8 +9,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.thymeleaf.util.StringUtils; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; import java.util.regex.Pattern; public class ContactInfoValidator implements ConstraintValidator { diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/DynamicValidationApp.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/DynamicValidationApp.java index 6b04380ece..f9bc89ded9 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/DynamicValidationApp.java +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/DynamicValidationApp.java @@ -1,6 +1,6 @@ package com.baeldung.dynamicvalidation; -import javax.annotation.security.RolesAllowed; +import jakarta.annotation.security.RolesAllowed; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/config/CustomerController.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/config/CustomerController.java index f08271f307..2e0e65dda9 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/config/CustomerController.java +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/config/CustomerController.java @@ -1,6 +1,6 @@ package com.baeldung.dynamicvalidation.config; -import javax.validation.Valid; +import jakarta.validation.Valid; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/model/ContactInfoExpression.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/model/ContactInfoExpression.java index 9c202b07c8..41e328361a 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/model/ContactInfoExpression.java +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/model/ContactInfoExpression.java @@ -1,8 +1,8 @@ package com.baeldung.dynamicvalidation.model; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; @Entity public class ContactInfoExpression { diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/model/Customer.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/model/Customer.java index 78d3580793..b69b4d4502 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/model/Customer.java +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/model/Customer.java @@ -1,10 +1,10 @@ package com.baeldung.dynamicvalidation.model; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.validation.constraints.NotNull; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.validation.constraints.NotNull; import com.baeldung.dynamicvalidation.ContactInfo; diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/domain/Address.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/domain/Address.java index 930276b3ee..b6a8ded010 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/domain/Address.java +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/domain/Address.java @@ -1,6 +1,6 @@ package com.baeldung.javers.domain; -import javax.persistence.Embeddable; +import jakarta.persistence.Embeddable; @Embeddable public class Address { diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/domain/Product.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/domain/Product.java index 61a2993bb9..513ce094ac 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/domain/Product.java +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/domain/Product.java @@ -1,6 +1,6 @@ package com.baeldung.javers.domain; -import javax.persistence.*; +import jakarta.persistence.*; @Entity public class Product { diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/domain/Store.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/domain/Store.java index 5aa6686261..cfe5cf19ac 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/domain/Store.java +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/domain/Store.java @@ -1,6 +1,6 @@ package com.baeldung.javers.domain; -import javax.persistence.*; +import jakarta.persistence.*; import java.util.ArrayList; import java.util.List; diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/propertyeditor/PropertyEditorRestController.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/propertyeditor/PropertyEditorRestController.java index 02edc96cf6..729c4baa66 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/propertyeditor/PropertyEditorRestController.java +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/propertyeditor/PropertyEditorRestController.java @@ -17,13 +17,13 @@ import com.baeldung.propertyeditor.exotictype.model.ExoticType; public class PropertyEditorRestController { @GetMapping(value = "/credit-card/{card-no}", - produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + produces = MediaType.APPLICATION_JSON_VALUE ) public CreditCard parseCreditCardNumber(@PathVariable("card-no") CreditCard creditCard) { return creditCard; } @GetMapping(value = "/exotic-type/{value}", - produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + produces = MediaType.APPLICATION_JSON_VALUE ) public ExoticType parseExoticType(@PathVariable("value") ExoticType exoticType) { return exoticType; } diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/propertyeditor/creditcard/CreditCardEditor.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/propertyeditor/creditcard/CreditCardEditor.java index d413afee85..5d9738d3a7 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/propertyeditor/creditcard/CreditCardEditor.java +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/propertyeditor/creditcard/CreditCardEditor.java @@ -15,7 +15,7 @@ public class CreditCardEditor extends PropertyEditorSupport { @Override public void setAsText(String text) throws IllegalArgumentException { - if (StringUtils.isEmpty(text)) { + if (!StringUtils.hasLength(text)) { setValue(null); } else { CreditCard creditCard = new CreditCard(); From 3aa6d757c1506cb11299445f3a0fe4779ff14179 Mon Sep 17 00:00:00 2001 From: Bipin kumar Date: Tue, 23 Jan 2024 04:16:19 +0530 Subject: [PATCH 096/132] [JAVA-28956] Upgrade spring-data-jpa-repo module to Spring Boot 3 (#15665) --- .../spring-data-jpa-repo/pom.xml | 29 +++++++++++++++++-- .../daos/impl/CustomItemRepositoryImpl.java | 2 +- .../impl/CustomItemTypeRepositoryImpl.java | 3 +- .../daos/impl/ExtendedRepositoryImpl.java | 13 +++++---- .../java/com/baeldung/boot/domain/Item.java | 6 ++-- .../com/baeldung/boot/domain/ItemType.java | 10 +++---- .../java/com/baeldung/boot/domain/KVTag.java | 2 +- .../com/baeldung/boot/domain/Location.java | 10 +++---- .../boot/domain/MerchandiseEntity.java | 9 +++--- .../com/baeldung/boot/domain/SkillTag.java | 2 +- .../java/com/baeldung/boot/domain/Store.java | 12 ++++---- .../com/baeldung/boot/domain/Student.java | 7 +++-- .../baeldung/derivedquery/entity/User.java | 9 +++--- .../java/com/baeldung/jpa/domain/Foo.java | 10 +++---- .../java/com/baeldung/jpa/domain/Fruit.java | 6 ++-- .../com/baeldung/jpa/domain/Passenger.java | 11 +++---- .../java/com/baeldung/jpa/domain/Song.java | 10 ++++--- .../data/persistence/like/model/Movie.java | 8 ++--- .../baeldung/storedprocedure/entity/Car.java | 16 +++++----- ...endedStudentRepositoryIntegrationTest.java | 3 +- .../PassengerRepositoryIntegrationTest.java | 8 ++--- 21 files changed, 110 insertions(+), 76 deletions(-) diff --git a/persistence-modules/spring-data-jpa-repo/pom.xml b/persistence-modules/spring-data-jpa-repo/pom.xml index 4ce19d83d0..1eed56266a 100644 --- a/persistence-modules/spring-data-jpa-repo/pom.xml +++ b/persistence-modules/spring-data-jpa-repo/pom.xml @@ -8,9 +8,9 @@ com.baeldung - parent-boot-2 + parent-boot-3 0.0.1-SNAPSHOT - ../../parent-boot-2 + ../../parent-boot-3 @@ -47,6 +47,31 @@ guava ${guava.version} + + jakarta.xml.bind + jakarta.xml.bind-api + 4.0.0 + + + + + org.springframework.boot + spring-boot-maven-plugin + + + repackage + + repackage + + + true + + + + + + + \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/daos/impl/CustomItemRepositoryImpl.java b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/daos/impl/CustomItemRepositoryImpl.java index 820a2cdd41..132095213d 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/daos/impl/CustomItemRepositoryImpl.java +++ b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/daos/impl/CustomItemRepositoryImpl.java @@ -1,12 +1,12 @@ package com.baeldung.boot.daos.impl; -import javax.persistence.EntityManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import com.baeldung.boot.daos.CustomItemRepository; import com.baeldung.boot.domain.Item; +import jakarta.persistence.EntityManager; @Repository public class CustomItemRepositoryImpl implements CustomItemRepository { diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/daos/impl/CustomItemTypeRepositoryImpl.java b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/daos/impl/CustomItemTypeRepositoryImpl.java index e057f36b26..d533503b57 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/daos/impl/CustomItemTypeRepositoryImpl.java +++ b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/daos/impl/CustomItemTypeRepositoryImpl.java @@ -1,6 +1,5 @@ package com.baeldung.boot.daos.impl; -import javax.persistence.EntityManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; @@ -8,6 +7,8 @@ import org.springframework.stereotype.Repository; import com.baeldung.boot.daos.CustomItemTypeRepository; import com.baeldung.boot.domain.ItemType; +import jakarta.persistence.EntityManager; + @Repository public class CustomItemTypeRepositoryImpl implements CustomItemTypeRepository { diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/daos/impl/ExtendedRepositoryImpl.java b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/daos/impl/ExtendedRepositoryImpl.java index fbe6695844..14d59b9d7e 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/daos/impl/ExtendedRepositoryImpl.java +++ b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/daos/impl/ExtendedRepositoryImpl.java @@ -3,18 +3,19 @@ package com.baeldung.boot.daos.impl; import java.io.Serializable; import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.TypedQuery; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Root; -import javax.transaction.Transactional; import org.springframework.data.jpa.repository.support.JpaEntityInformation; import org.springframework.data.jpa.repository.support.SimpleJpaRepository; import com.baeldung.boot.daos.ExtendedRepository; +import jakarta.persistence.EntityManager; +import jakarta.persistence.TypedQuery; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Root; +import jakarta.transaction.Transactional; + public class ExtendedRepositoryImpl extends SimpleJpaRepository implements ExtendedRepository { private EntityManager entityManager; diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/Item.java b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/Item.java index 8ac06af15a..1a9c418064 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/Item.java +++ b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/Item.java @@ -2,9 +2,9 @@ package com.baeldung.boot.domain; import java.math.BigDecimal; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.ManyToOne; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; @Entity public class Item { diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/ItemType.java b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/ItemType.java index 8a52a9847c..41f248c149 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/ItemType.java +++ b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/ItemType.java @@ -3,11 +3,11 @@ package com.baeldung.boot.domain; import java.util.ArrayList; import java.util.List; -import javax.persistence.CascadeType; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.OneToMany; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToMany; @Entity public class ItemType { diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/KVTag.java b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/KVTag.java index 1901f43c0a..fd19370c3b 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/KVTag.java +++ b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/KVTag.java @@ -1,6 +1,6 @@ package com.baeldung.boot.domain; -import javax.persistence.Embeddable; +import jakarta.persistence.Embeddable; @Embeddable public class KVTag { diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/Location.java b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/Location.java index 9c1b93d551..34d5ea7315 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/Location.java +++ b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/Location.java @@ -3,11 +3,11 @@ package com.baeldung.boot.domain; import java.util.ArrayList; import java.util.List; -import javax.persistence.CascadeType; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.OneToMany; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToMany; @Entity public class Location { diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/MerchandiseEntity.java b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/MerchandiseEntity.java index e94c23de86..613aeb21ef 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/MerchandiseEntity.java +++ b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/MerchandiseEntity.java @@ -1,11 +1,12 @@ package com.baeldung.boot.domain; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; import java.math.BigDecimal; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + @Entity public class MerchandiseEntity { @Id diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/SkillTag.java b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/SkillTag.java index 0933a3e6af..c46017bce7 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/SkillTag.java +++ b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/SkillTag.java @@ -1,6 +1,6 @@ package com.baeldung.boot.domain; -import javax.persistence.Embeddable; +import jakarta.persistence.Embeddable; @Embeddable public class SkillTag { diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/Store.java b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/Store.java index 5b4b831cc7..ea01094c98 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/Store.java +++ b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/Store.java @@ -3,12 +3,12 @@ package com.baeldung.boot.domain; import java.util.ArrayList; import java.util.List; -import javax.persistence.CascadeType; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; @Entity public class Store { diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/Student.java b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/Student.java index 1003167cc7..01c26fa987 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/Student.java +++ b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/boot/domain/Student.java @@ -1,11 +1,12 @@ package com.baeldung.boot.domain; -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.Id; import java.util.ArrayList; import java.util.List; +import jakarta.persistence.ElementCollection; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; + @Entity public class Student { diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/derivedquery/entity/User.java b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/derivedquery/entity/User.java index 49e824f09f..b5b5eb40b0 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/derivedquery/entity/User.java +++ b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/derivedquery/entity/User.java @@ -1,11 +1,12 @@ package com.baeldung.derivedquery.entity; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Table; import java.time.ZonedDateTime; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + @Table(name = "users") @Entity public class User { diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/jpa/domain/Foo.java b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/jpa/domain/Foo.java index f799635eae..f725be4adf 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/jpa/domain/Foo.java +++ b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/jpa/domain/Foo.java @@ -2,11 +2,11 @@ package com.baeldung.jpa.domain; import java.io.Serializable; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class Foo implements Serializable { diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/jpa/domain/Fruit.java b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/jpa/domain/Fruit.java index 6314c58da3..84c9daf4c4 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/jpa/domain/Fruit.java +++ b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/jpa/domain/Fruit.java @@ -1,8 +1,8 @@ package com.baeldung.jpa.domain; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.xml.bind.annotation.XmlRootElement; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.xml.bind.annotation.XmlRootElement; @XmlRootElement @Entity diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/jpa/domain/Passenger.java b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/jpa/domain/Passenger.java index acfb7947c0..3a98d97426 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/jpa/domain/Passenger.java +++ b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/jpa/domain/Passenger.java @@ -1,12 +1,13 @@ package com.baeldung.jpa.domain; -import javax.persistence.Basic; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; import java.util.Objects; +import jakarta.persistence.Basic; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; + @Entity public class Passenger { diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/jpa/domain/Song.java b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/jpa/domain/Song.java index 9dcde0bea4..caeef47f8f 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/jpa/domain/Song.java +++ b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/jpa/domain/Song.java @@ -1,14 +1,16 @@ package com.baeldung.jpa.domain; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; import java.time.LocalDateTime; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; + @Entity public class Song { - @Id private long id; + @Id + private long id; private String name; @Column(name = "length_in_seconds") private int lengthInSeconds; diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/spring/data/persistence/like/model/Movie.java b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/spring/data/persistence/like/model/Movie.java index f500b61a8a..292219b7b1 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/spring/data/persistence/like/model/Movie.java +++ b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/spring/data/persistence/like/model/Movie.java @@ -1,9 +1,9 @@ package com.baeldung.spring.data.persistence.like.model; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class Movie { diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/storedprocedure/entity/Car.java b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/storedprocedure/entity/Car.java index 2817c25ff7..0a61a16e24 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/storedprocedure/entity/Car.java +++ b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/storedprocedure/entity/Car.java @@ -1,13 +1,13 @@ package com.baeldung.storedprocedure.entity; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.NamedStoredProcedureQuery; -import javax.persistence.StoredProcedureParameter; -import javax.persistence.ParameterMode; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.NamedStoredProcedureQuery; +import jakarta.persistence.ParameterMode; +import jakarta.persistence.StoredProcedureParameter; @Entity @NamedStoredProcedureQuery(name = "Car.getTotalCardsbyModelEntity", procedureName = "GET_TOTAL_CARS_BY_MODEL", parameters = { diff --git a/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/boot/daos/ExtendedStudentRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/boot/daos/ExtendedStudentRepositoryIntegrationTest.java index 51874e2bbe..f05f4fc86c 100644 --- a/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/boot/daos/ExtendedStudentRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/boot/daos/ExtendedStudentRepositoryIntegrationTest.java @@ -4,7 +4,6 @@ import static org.assertj.core.api.Assertions.assertThat; import java.util.List; -import javax.annotation.Resource; import org.junit.Before; import org.junit.Test; @@ -16,6 +15,8 @@ import org.springframework.test.context.junit4.SpringRunner; import com.baeldung.boot.BootApplication; import com.baeldung.boot.domain.Student; +import jakarta.annotation.Resource; + @RunWith(SpringRunner.class) @ContextConfiguration(classes = { BootApplication.class}) @DirtiesContext diff --git a/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/jpa/PassengerRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/jpa/PassengerRepositoryIntegrationTest.java index 1676cd6406..e7689c3f14 100644 --- a/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/jpa/PassengerRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/jpa/PassengerRepositoryIntegrationTest.java @@ -6,10 +6,6 @@ import static org.hamcrest.core.IsNot.not; import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.transaction.Transactional; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -21,6 +17,10 @@ import org.springframework.test.context.junit4.SpringRunner; import com.baeldung.jpa.domain.Passenger; import com.baeldung.jpa.repository.PassengerRepository; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.transaction.Transactional; + @RunWith(SpringRunner.class) @ContextConfiguration(classes = { JpaApplication.class}) @DirtiesContext From 6c341beb1aae58ab53dc1da5ef2e771036cf0117 Mon Sep 17 00:00:00 2001 From: Harry9656 Date: Tue, 23 Jan 2024 00:34:18 +0100 Subject: [PATCH 097/132] JAVA-29479: Upgrade guava version to 33.0.0-jre. (#15651) --- docker-modules/docker-caching/multi-module-caching/pom.xml | 2 +- docker-modules/docker-caching/single-module-caching/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-modules/docker-caching/multi-module-caching/pom.xml b/docker-modules/docker-caching/multi-module-caching/pom.xml index f2b52f246d..b9977f8f3a 100644 --- a/docker-modules/docker-caching/multi-module-caching/pom.xml +++ b/docker-modules/docker-caching/multi-module-caching/pom.xml @@ -25,7 +25,7 @@ - 32.1.3-jre + 33.0.0-jre \ No newline at end of file diff --git a/docker-modules/docker-caching/single-module-caching/pom.xml b/docker-modules/docker-caching/single-module-caching/pom.xml index bb44c21e10..1e90c7130e 100644 --- a/docker-modules/docker-caching/single-module-caching/pom.xml +++ b/docker-modules/docker-caching/single-module-caching/pom.xml @@ -49,7 +49,7 @@ 8 8 UTF-8 - 32.1.3-jre + 33.0.0-jre \ No newline at end of file diff --git a/pom.xml b/pom.xml index 92760e301e..a73d508d89 100644 --- a/pom.xml +++ b/pom.xml @@ -1215,7 +1215,7 @@ 3.21.0 1.18.30 2.1.214 - 32.1.3-jre + 33.0.0-jre 3.3.0 From 69fad866d949c9e1dad46e2001c46647ec25bcd9 Mon Sep 17 00:00:00 2001 From: Kasra Madadipouya Date: Tue, 23 Jan 2024 16:54:18 +0100 Subject: [PATCH 098/132] JAVA-30632 Upgrade spring-resttemplate module to Spring Boot 3 (#15713) * JAVA-30632 upgrade Spring rest template module to Spring Boot 3 * JAVA-30632 fix broken tests --- .../spring-resttemplate/.gitignore | 13 --- .../spring-resttemplate/pom.xml | 87 ++++--------------- .../configuration/SpringConfig.java | 1 - .../RestTemplateResponseErrorHandler.java | 32 +++---- .../web/controller/MyFooController.java | 2 +- .../mock/EmployeeServiceUnitTest.java | 7 +- .../RestTemplateBasicLiveTest.java | 8 +- 7 files changed, 36 insertions(+), 114 deletions(-) delete mode 100644 spring-web-modules/spring-resttemplate/.gitignore diff --git a/spring-web-modules/spring-resttemplate/.gitignore b/spring-web-modules/spring-resttemplate/.gitignore deleted file mode 100644 index 83c05e60c8..0000000000 --- a/spring-web-modules/spring-resttemplate/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -*.class - -#folders# -/target -/neoDb* -/data -/src/main/webapp/WEB-INF/classes -*/META-INF/* - -# Packaged files # -*.jar -*.war -*.ear \ No newline at end of file diff --git a/spring-web-modules/spring-resttemplate/pom.xml b/spring-web-modules/spring-resttemplate/pom.xml index 84c1add07e..3a03f3aafc 100644 --- a/spring-web-modules/spring-resttemplate/pom.xml +++ b/spring-web-modules/spring-resttemplate/pom.xml @@ -10,71 +10,20 @@ com.baeldung - parent-boot-2 + parent-boot-3 0.0.1-SNAPSHOT - ../../parent-boot-2 + ../../parent-boot-3 - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.boot - spring-boot-starter-thymeleaf - - - org.springframework.boot - spring-boot-devtools - org.springframework.boot spring-boot-starter-web org.springframework.boot - spring-boot-starter-test - - - au.com.dius - pact-jvm-provider-junit5_2.12 - ${pact.version} - - - au.com.dius - pact-jvm-consumer-junit5_2.12 - ${pact.version} - test - - - - org.springframework - spring-web - - - commons-logging - commons-logging - - - - - org.springframework - spring-webmvc - - - org.springframework - spring-oxm - - - - com.fasterxml.jackson.core - jackson-databind - - - com.fasterxml.jackson.dataformat - jackson-dataformat-xml + spring-boot-starter-actuator com.thoughtworks.xstream @@ -100,14 +49,15 @@ - org.springframework - spring-test - - - org.mockito - mockito-junit-jupiter - ${mockito.version} + org.springframework.boot + spring-boot-starter-test test + + + org.junit.vintage + junit-vintage-engine + + @@ -120,14 +70,13 @@ + + org.springframework.boot + spring-boot-maven-plugin + org.apache.maven.plugins maven-compiler-plugin - ${maven.version} - - ${source.version} - ${target.version} - org.apache.maven.plugins @@ -254,16 +203,12 @@ - 1.4.9 + 1.4.20 1.6.1 3.0.4 4.12.0 - 3.6.3 - 1.8 - 1.8 - 3.7.0 \ No newline at end of file diff --git a/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/SpringConfig.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/SpringConfig.java index 7866a4abcd..f6a618fc12 100644 --- a/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/SpringConfig.java +++ b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/SpringConfig.java @@ -7,7 +7,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; -import org.springframework.web.client.RestTemplate; @Configuration @EnableAutoConfiguration diff --git a/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/handler/RestTemplateResponseErrorHandler.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/handler/RestTemplateResponseErrorHandler.java index 02260438c7..fe7e1239c5 100644 --- a/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/handler/RestTemplateResponseErrorHandler.java +++ b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/handler/RestTemplateResponseErrorHandler.java @@ -2,40 +2,32 @@ package com.baeldung.resttemplate.web.handler; import java.io.IOException; -import com.baeldung.resttemplate.web.exception.NotFoundException; import org.springframework.http.HttpStatus; import org.springframework.http.client.ClientHttpResponse; import org.springframework.stereotype.Component; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.ResponseErrorHandler; +import com.baeldung.resttemplate.web.exception.NotFoundException; + @Component -public class RestTemplateResponseErrorHandler - implements ResponseErrorHandler { +public class RestTemplateResponseErrorHandler implements ResponseErrorHandler { @Override - public boolean hasError(ClientHttpResponse httpResponse) - throws IOException { - - return (httpResponse - .getStatusCode() - .series() == HttpStatus.Series.CLIENT_ERROR || httpResponse - .getStatusCode() - .series() == HttpStatus.Series.SERVER_ERROR); + public boolean hasError(ClientHttpResponse httpResponse) throws IOException { + return httpResponse.getStatusCode() + .is5xxServerError() || httpResponse.getStatusCode() + .is4xxClientError(); } @Override - public void handleError(ClientHttpResponse httpResponse) - throws IOException { - - if (httpResponse - .getStatusCode() - .series() == HttpStatus.Series.SERVER_ERROR) { + public void handleError(ClientHttpResponse httpResponse) throws IOException { + if (httpResponse.getStatusCode() + .is5xxServerError()) { //Handle SERVER_ERROR throw new HttpClientErrorException(httpResponse.getStatusCode()); - } else if (httpResponse - .getStatusCode() - .series() == HttpStatus.Series.CLIENT_ERROR) { + } else if (httpResponse.getStatusCode() + .is4xxClientError()) { //Handle CLIENT_ERROR if (httpResponse.getStatusCode() == HttpStatus.NOT_FOUND) { throw new NotFoundException(); diff --git a/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/MyFooController.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/MyFooController.java index 5c385edb07..c1a4825fc0 100644 --- a/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/MyFooController.java +++ b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/MyFooController.java @@ -4,7 +4,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; diff --git a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/mock/EmployeeServiceUnitTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/mock/EmployeeServiceUnitTest.java index 4c6e2fa5ca..97d49bd335 100644 --- a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/mock/EmployeeServiceUnitTest.java +++ b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/mock/EmployeeServiceUnitTest.java @@ -1,5 +1,7 @@ package com.baeldung.mock; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -18,8 +20,6 @@ import com.baeldung.resttemplate.web.model.Employee; @ExtendWith(MockitoExtension.class) public class EmployeeServiceUnitTest { - private static final Logger logger = LoggerFactory.getLogger(EmployeeServiceUnitTest.class); - @Mock private RestTemplate restTemplate; @@ -34,7 +34,6 @@ public class EmployeeServiceUnitTest { Employee employee = empService.getEmployee("E001"); - Assertions.assertEquals(emp, employee); + assertEquals(emp, employee); } - } diff --git a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateBasicLiveTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateBasicLiveTest.java index a433ac73c3..0c5d473291 100644 --- a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateBasicLiveTest.java +++ b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateBasicLiveTest.java @@ -1,6 +1,6 @@ package com.baeldung.resttemplate; -import static org.apache.commons.codec.binary.Base64.encodeBase64; +import java.util.Base64; import static com.baeldung.client.Consts.APPLICATION_PORT; import static org.junit.jupiter.api.Assertions.fail; @@ -32,7 +32,7 @@ import org.springframework.web.client.RestTemplate; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import org.springframework.web.client.RestTemplate; import com.google.common.base.Charsets; // This test needs RestTemplateConfigurationApplication to be up and running @@ -62,7 +62,7 @@ public class RestTemplateBasicLiveTest { final RestTemplate template = new RestTemplate(); final ResponseEntity response = template.getForEntity(fooResourceUrl + "/1", String.class); - final ObjectMapper mapper = new XmlMapper(); + final ObjectMapper mapper = new ObjectMapper(); final JsonNode root = mapper.readTree(response.getBody()); final JsonNode name = root.path("name"); Assertions.assertNotNull(name.asText()); @@ -243,7 +243,7 @@ public class RestTemplateBasicLiveTest { private String getBase64EncodedLogPass() { final String logPass = "user1:user1Pass"; - final byte[] authHeaderBytes = encodeBase64(logPass.getBytes(Charsets.US_ASCII)); + final byte[] authHeaderBytes = Base64.getEncoder().encode(logPass.getBytes(Charsets.US_ASCII)); return new String(authHeaderBytes, Charsets.US_ASCII); } From 15de11de9aafafe787ccb01b4001e5f657fada5c Mon Sep 17 00:00:00 2001 From: Eugene Kovko <37694937+eukovko@users.noreply.github.com> Date: Tue, 23 Jan 2024 19:23:39 +0100 Subject: [PATCH 099/132] Bael 7452 updated (#15714) * BAEL-7452: Lazy loaded lists * BAEL-7452: Example with Lazy Lists * BAEL-7452: Test for lazy groups --- .../set/lazy/moderatedomain/Application.java | 8 ++ .../eager/set/lazy/moderatedomain/Group.java | 22 ++++++ .../lazy/moderatedomain/GroupRepository.java | 7 ++ .../set/lazy/moderatedomain/GroupService.java | 29 +++++++ .../eager/set/lazy/moderatedomain/Post.java | 43 +++++++++++ .../lazy/moderatedomain/PostRepository.java | 7 ++ .../eager/set/lazy/moderatedomain/User.java | 45 +++++++++++ .../lazy/moderatedomain/UserRepository.java | 7 ++ .../set/lazy/moderatedomain/UserService.java | 20 +++++ .../lazy/list/moderatedomain/Application.java | 8 ++ .../lazy/list/moderatedomain/Group.java | 22 ++++++ .../list/moderatedomain/GroupRepository.java | 7 ++ .../list/moderatedomain/GroupService.java | 35 +++++++++ .../lazy/list/moderatedomain/Post.java | 23 ++++++ .../list/moderatedomain/PostRepository.java | 7 ++ .../lazy/list/moderatedomain/User.java | 45 +++++++++++ .../list/moderatedomain/UserRepository.java | 7 ++ .../lazy/list/moderatedomain/UserService.java | 20 +++++ .../defaultfetch/list/Application.java | 8 ++ .../nplusone/defaultfetch/list/Post.java | 23 ++++++ .../defaultfetch/list/PostRepository.java | 7 ++ .../nplusone/defaultfetch/list/User.java | 25 ++++++ .../defaultfetch/list/UserRepository.java | 9 +++ .../defaultfetch/list/UserService.java | 20 +++++ ...sOneLazyModerateDomainIntegrationTest.java | 77 +++++++++++++++++++ ...lusOneLazySimpleDomainIntegrationTest.java | 55 +++++++++++++ 26 files changed, 586 insertions(+) create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Application.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Group.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/GroupRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/GroupService.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Post.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/PostRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/User.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/UserRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/UserService.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Application.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Group.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/GroupRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/GroupService.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Post.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/PostRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/User.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/UserRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/UserService.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/Application.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/Post.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/PostRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/User.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/UserRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/UserService.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/lazy/list/NPlusOneLazyModerateDomainIntegrationTest.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/lazy/list/NPlusOneLazySimpleDomainIntegrationTest.java diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Application.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Application.java new file mode 100644 index 0000000000..c9a0442ad6 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Application.java @@ -0,0 +1,8 @@ +package com.baeldung.listvsset.eager.set.lazy.moderatedomain; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Group.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Group.java new file mode 100644 index 0000000000..28e94f542b --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Group.java @@ -0,0 +1,22 @@ +package com.baeldung.listvsset.eager.set.lazy.moderatedomain; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.Table; +import java.util.Set; +import lombok.Data; + +@Data +@Entity(name = "interest_group") +@Table(name = "interest_group") +public class Group { + + @Id + private Long id; + + private String name; + + @ManyToMany + private Set members; +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/GroupRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/GroupRepository.java new file mode 100644 index 0000000000..8f67f3c10c --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/GroupRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.listvsset.eager.set.lazy.moderatedomain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface GroupRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/GroupService.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/GroupService.java new file mode 100644 index 0000000000..9fd9407309 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/GroupService.java @@ -0,0 +1,29 @@ +package com.baeldung.listvsset.eager.set.lazy.moderatedomain; + +import java.util.List; +import java.util.Optional; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class GroupService { + + private final GroupRepository groupRepository; + + @Autowired + public GroupService(GroupRepository groupRepository) { + this.groupRepository = groupRepository; + } + + public Optional findById(Long aLong) { + return groupRepository.findById(aLong); + } + + public List findAll() { + return groupRepository.findAll(); + } + + public void save(Group group) { + groupRepository.save(group); + } +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Post.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Post.java new file mode 100644 index 0000000000..00edc08e5f --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Post.java @@ -0,0 +1,43 @@ +package com.baeldung.listvsset.eager.set.lazy.moderatedomain; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Lob; +import jakarta.persistence.ManyToOne; +import java.util.Objects; +import lombok.Data; + +@Entity +@Data +public class Post { + + @Id + private Long id; + + @Lob + private String content; + + @JsonBackReference + @ManyToOne + private User author; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Post post = (Post) o; + + return Objects.equals(id, post.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/PostRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/PostRepository.java new file mode 100644 index 0000000000..8671c4b8a7 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/PostRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.listvsset.eager.set.lazy.moderatedomain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PostRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/User.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/User.java new file mode 100644 index 0000000000..adb4db8921 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/User.java @@ -0,0 +1,45 @@ +package com.baeldung.listvsset.eager.set.lazy.moderatedomain; + +import com.fasterxml.jackson.annotation.JsonManagedReference; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import java.util.Objects; +import java.util.Set; +import lombok.Data; + +@Data +@Entity(name = "simple_user") +@Table(name = "simple_user") +public class User { + + @Id + private Long id; + private String username; + private String email; + + @JsonManagedReference + @OneToMany(cascade = CascadeType.ALL, mappedBy = "author") + protected Set posts; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + User user = (User) o; + + return Objects.equals(id, user.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/UserRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/UserRepository.java new file mode 100644 index 0000000000..93eb21cbf5 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/UserRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.listvsset.eager.set.lazy.moderatedomain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/UserService.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/UserService.java new file mode 100644 index 0000000000..d633c55563 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/UserService.java @@ -0,0 +1,20 @@ +package com.baeldung.listvsset.eager.set.lazy.moderatedomain; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +@Service +public class UserService extends com.baeldung.listvsset.Service { + + public UserService(JpaRepository repository) { + super(repository); + } + + @Override + public UserRepository getRepository() { + return ((UserRepository) super.getRepository()); + } + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Application.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Application.java new file mode 100644 index 0000000000..4b5c61f89d --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Application.java @@ -0,0 +1,8 @@ +package com.baeldung.listvsset.lazy.list.moderatedomain; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Group.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Group.java new file mode 100644 index 0000000000..f74272cb99 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Group.java @@ -0,0 +1,22 @@ +package com.baeldung.listvsset.lazy.list.moderatedomain; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.Table; +import java.util.List; +import lombok.Data; + +@Data +@Entity(name = "interest_group") +@Table(name = "interest_group") +public class Group { + + @Id + private Long id; + + private String name; + + @ManyToMany + private List members; +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/GroupRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/GroupRepository.java new file mode 100644 index 0000000000..2bc919566a --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/GroupRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.listvsset.lazy.list.moderatedomain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface GroupRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/GroupService.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/GroupService.java new file mode 100644 index 0000000000..7ee2b83566 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/GroupService.java @@ -0,0 +1,35 @@ +package com.baeldung.listvsset.lazy.list.moderatedomain; + +import java.util.List; +import java.util.Optional; +import java.util.function.ToIntFunction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +public class GroupService { + + private final GroupRepository groupRepository; + + @Autowired + public GroupService(GroupRepository groupRepository) { + this.groupRepository = groupRepository; + } + + public Optional findById(Long aLong) { + return groupRepository.findById(aLong); + } + + public List findAll() { + return groupRepository.findAll(); + } + public int countNumberOfRequestsWithFunction(ToIntFunction> function) { + return function.applyAsInt(groupRepository.findAll()); + } + + public S save(S entity) { + return groupRepository.save(entity); + } +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Post.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Post.java new file mode 100644 index 0000000000..3d2dc2a89e --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Post.java @@ -0,0 +1,23 @@ +package com.baeldung.listvsset.lazy.list.moderatedomain; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Lob; +import jakarta.persistence.ManyToOne; +import lombok.Data; + +@Entity +@Data +public class Post { + + @Id + private Long id; + + @Lob + private String content; + + @JsonBackReference + @ManyToOne + private User author; +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/PostRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/PostRepository.java new file mode 100644 index 0000000000..e1696a9b75 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/PostRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.listvsset.lazy.list.moderatedomain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PostRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/User.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/User.java new file mode 100644 index 0000000000..d2c19febca --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/User.java @@ -0,0 +1,45 @@ +package com.baeldung.listvsset.lazy.list.moderatedomain; + +import com.fasterxml.jackson.annotation.JsonManagedReference; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import java.util.List; +import java.util.Objects; +import lombok.Data; + +@Data +@Entity(name = "simple_user") +@Table(name = "simple_user") +public class User { + + @Id + private Long id; + private String username; + private String email; + + @JsonManagedReference + @OneToMany(cascade = CascadeType.ALL, mappedBy = "author") + protected List posts; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + User user = (User) o; + + return Objects.equals(id, user.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/UserRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/UserRepository.java new file mode 100644 index 0000000000..0a89e1638f --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/UserRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.listvsset.lazy.list.moderatedomain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/UserService.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/UserService.java new file mode 100644 index 0000000000..22944f5b35 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/UserService.java @@ -0,0 +1,20 @@ +package com.baeldung.listvsset.lazy.list.moderatedomain; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +@Service +public class UserService extends com.baeldung.listvsset.Service { + + public UserService(JpaRepository repository) { + super(repository); + } + + @Override + public UserRepository getRepository() { + return ((UserRepository) super.getRepository()); + } + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/Application.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/Application.java new file mode 100644 index 0000000000..648c153c13 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/Application.java @@ -0,0 +1,8 @@ +package com.baeldung.nplusone.defaultfetch.list; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/Post.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/Post.java new file mode 100644 index 0000000000..b0ad40ec06 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/Post.java @@ -0,0 +1,23 @@ +package com.baeldung.nplusone.defaultfetch.list; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Lob; +import jakarta.persistence.ManyToOne; +import lombok.Data; + +@Entity +@Data +public class Post { + + @Id + private Long id; + + @Lob + private String content; + + @JsonBackReference + @ManyToOne + private User author; +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/PostRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/PostRepository.java new file mode 100644 index 0000000000..19cd9a32bd --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/PostRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.nplusone.defaultfetch.list; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PostRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/User.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/User.java new file mode 100644 index 0000000000..81b570a292 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/User.java @@ -0,0 +1,25 @@ +package com.baeldung.nplusone.defaultfetch.list; + +import com.fasterxml.jackson.annotation.JsonManagedReference; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import java.util.List; +import lombok.Data; + +@Data +@Entity(name = "simple_user") +@Table(name = "simple_user") +public class User { + + @Id + private Long id; + private String username; + private String email; + + @JsonManagedReference + @OneToMany(cascade = CascadeType.ALL, mappedBy = "author") + protected List posts; +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/UserRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/UserRepository.java new file mode 100644 index 0000000000..22516cd31b --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/UserRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.nplusone.defaultfetch.list; + +import org.springframework.context.annotation.Lazy; +import org.springframework.data.jpa.repository.JpaRepository; + +@Lazy(value = false) +public interface UserRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/UserService.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/UserService.java new file mode 100644 index 0000000000..d0decf9f9d --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/UserService.java @@ -0,0 +1,20 @@ +package com.baeldung.nplusone.defaultfetch.list; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +@Service +public class UserService extends com.baeldung.listvsset.Service { + + public UserService(JpaRepository repository) { + super(repository); + } + + @Override + public UserRepository getRepository() { + return ((UserRepository) super.getRepository()); + } + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/lazy/list/NPlusOneLazyModerateDomainIntegrationTest.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/lazy/list/NPlusOneLazyModerateDomainIntegrationTest.java new file mode 100644 index 0000000000..2544a73b24 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/lazy/list/NPlusOneLazyModerateDomainIntegrationTest.java @@ -0,0 +1,77 @@ +package com.baeldung.listvsset.lazy.list; + +import static com.vladmihalcea.sql.SQLStatementCountValidator.assertSelectCount; +import static org.assertj.core.api.Assertions.assertThat; + +import com.baeldung.listvsset.BaseNPlusOneIntegrationTest; +import com.baeldung.listvsset.lazy.list.moderatedomain.Application; +import com.baeldung.listvsset.lazy.list.moderatedomain.Group; +import com.baeldung.listvsset.lazy.list.moderatedomain.GroupService; +import com.baeldung.listvsset.lazy.list.moderatedomain.User; +import com.baeldung.listvsset.util.TestConfig; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest(classes = {Application.class, TestConfig.class}, properties = { + "hibernate.show_sql=true", + "logging.level.org.hibernate.SQL=debug", + "logging.level.org.hibernate.orm.jdbc.bind=trace" +}) +class NPlusOneLazyModerateDomainIntegrationTest extends BaseNPlusOneIntegrationTest { + + @Autowired + private GroupService groupService; + + @Test + void givenLazyListBasedUser_whenFetchingAllUsers_thenIssueOneRequest() { + getService().findAll(); + assertSelectCount(1); + } + + @ParameterizedTest + @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) + void givenLazyListBasedUser_whenFetchingOneUser_thenIssueOneRequest(Long id) { + getService().getUserById(id); + assertSelectCount(1); + } + + @Test + void givenLazyListBasedGroup_whenFetchingAllGroups_thenIssueOneRequest() { + groupService.findAll(); + assertSelectCount(1); + } + @Test + void givenLazyListBasedGroup_whenFilteringGroups_thenIssueNPlusOneRequests() { + int numberOfRequests = groupService.countNumberOfRequestsWithFunction(groups -> { + groups.stream() + .map(Group::getMembers) + .flatMap(Collection::stream) + .collect(Collectors.toSet()); + return groups.size(); + }); + assertSelectCount(numberOfRequests + 1); + } + + @ParameterizedTest + @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) + void givenLazyListBasedGroup_whenFetchingAllGroups_thenIssueOneRequest(Long groupId) { + Optional group = groupService.findById(groupId); + assertThat(group).isPresent(); + assertSelectCount(1); + } + + protected void addUsers() { + List users = jsonUtils.getUsers(User.class); + databaseUtil.saveAll(users); + List groups = jsonUtils.getGroupsWithMembers(Group.class); + databaseUtil.saveAll(groups); + } + +} diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/lazy/list/NPlusOneLazySimpleDomainIntegrationTest.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/lazy/list/NPlusOneLazySimpleDomainIntegrationTest.java new file mode 100644 index 0000000000..5d61b76d5d --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/lazy/list/NPlusOneLazySimpleDomainIntegrationTest.java @@ -0,0 +1,55 @@ +package com.baeldung.listvsset.lazy.list; + +import static com.vladmihalcea.sql.SQLStatementCountValidator.assertSelectCount; + +import com.baeldung.listvsset.BaseNPlusOneIntegrationTest; +import com.baeldung.listvsset.util.TestConfig; +import com.baeldung.nplusone.defaultfetch.list.Application; +import com.baeldung.nplusone.defaultfetch.list.Post; +import com.baeldung.nplusone.defaultfetch.list.User; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest(classes = {Application.class, TestConfig.class}, properties = { + "hibernate.show_sql=true", + "logging.level.org.hibernate.SQL=debug", + "logging.level.org.hibernate.orm.jdbc.bind=trace" +}) +class NPlusOneLazySimpleDomainIntegrationTest extends BaseNPlusOneIntegrationTest { + + @Test + void givenLazyListBasedUser_WhenFetchingAllUsers_ThenIssueOneRequests() { + getService().findAll(); + assertSelectCount(1); + } + + @Test + void givenLazyListBasedUser_WhenFetchingAllUsersCheckingPosts_ThenIssueNPlusOneRequests() { + int numberOfRequests = getService().countNumberOfRequestsWithFunction(users -> { + List> usersWithPosts + = users.stream() + .map(User::getPosts) + .filter(List::isEmpty) + .toList(); + return users.size(); + }); + assertSelectCount(numberOfRequests + 1); + } + + @ParameterizedTest + @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) + void givenLazyListBasedUser_WhenFetchingOneUser_ThenIssueTwoRequest(Long id) { + getService().getUserByIdWithPredicate(id, user -> !user.getPosts().isEmpty()); + assertSelectCount(2); + } + + + protected void addUsers() { + List users = jsonUtils.getUsers(User.class); + databaseUtil.saveAll(users); + } + +} From 72cd365b266a1a060ef8d8ad6daef2ad266bbf0c Mon Sep 17 00:00:00 2001 From: Mo Helmy <135069400+BenHelmyBen@users.noreply.github.com> Date: Tue, 23 Jan 2024 21:21:56 +0200 Subject: [PATCH 100/132] This PR is related to BAEL-7174 (#15712) * Update pom.xml Add: core-java-regex-3 * This commit is related to BAEL-7174 This commit aims to add a new module named "core-java-regex-3" and a new project named "passwordvalidation" to validate passwords using regex. * Update PasswordValidationUsingRegexUnitTest.java Change else-if to assertTrue(matcher.matches()); --- core-java-modules/core-java-regex-3/README.md | 3 ++ core-java-modules/core-java-regex-3/pom.xml | 24 +++++++++ .../PasswordValidationUsingRegexUnitTest.java | 53 +++++++++++++++++++ core-java-modules/pom.xml | 1 + 4 files changed, 81 insertions(+) create mode 100644 core-java-modules/core-java-regex-3/README.md create mode 100644 core-java-modules/core-java-regex-3/pom.xml create mode 100644 core-java-modules/core-java-regex-3/src/test/java/com/baeldung/passwordvalidation/PasswordValidationUsingRegexUnitTest.java diff --git a/core-java-modules/core-java-regex-3/README.md b/core-java-modules/core-java-regex-3/README.md new file mode 100644 index 0000000000..18b5f0127f --- /dev/null +++ b/core-java-modules/core-java-regex-3/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- More articles: [[<-- prev]](/core-java-modules/core-java-regex-2) diff --git a/core-java-modules/core-java-regex-3/pom.xml b/core-java-modules/core-java-regex-3/pom.xml new file mode 100644 index 0000000000..143b615246 --- /dev/null +++ b/core-java-modules/core-java-regex-3/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + core-java-regex-3 + core-java-regex-3 + + + org.junit.jupiter + junit-jupiter + 5.8.1 + test + + + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + \ No newline at end of file diff --git a/core-java-modules/core-java-regex-3/src/test/java/com/baeldung/passwordvalidation/PasswordValidationUsingRegexUnitTest.java b/core-java-modules/core-java-regex-3/src/test/java/com/baeldung/passwordvalidation/PasswordValidationUsingRegexUnitTest.java new file mode 100644 index 0000000000..b55943f1b6 --- /dev/null +++ b/core-java-modules/core-java-regex-3/src/test/java/com/baeldung/passwordvalidation/PasswordValidationUsingRegexUnitTest.java @@ -0,0 +1,53 @@ +package com.baeldung.passwordvalidation; + +import org.junit.jupiter.api.Test; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static org.junit.jupiter.api.Assertions.*; + +public class PasswordValidationUsingRegexUnitTest { + String password = "Baeldung20@"; + + @Test + public void givenStringPassword_whenUsingDynamicPasswordValidationRules_thenCheckIfPasswordValid() { + boolean result = false; + try { + if (password != null) { + String MIN_LENGHT = "8"; + String MAX_LENGHT = "20"; + boolean SPECIAL_CHAR_NEEDED = false; + + String ONE_DIGIT = "(?=.*[0-9])"; + String LOWER_CASE = "(?=.*[a-z])"; + String UPPER_CASE = "(?=.*[A-Z])"; + String SPECIAL_CHAR = SPECIAL_CHAR_NEEDED ? "(?=.*[@#$%^&+=])" : ""; + String NO_SPACE = "(?=\\S+$)"; + + String MIN_MAX_CHAR = ".{" + MIN_LENGHT + "," + MAX_LENGHT + "}"; + String PATTERN = ONE_DIGIT + LOWER_CASE + UPPER_CASE + SPECIAL_CHAR + NO_SPACE + MIN_MAX_CHAR; + + assertTrue(password.matches(PATTERN)); + } + + } catch (Exception ex) { + ex.printStackTrace(); + fail("Exception occurred: " + ex.getMessage()); + } + } + + @Test + public void givenStringPassword_whenUsingRegulaExpressions_thenCheckIfPasswordValid() { + + + String regExpn = + "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,20}$"; + + Pattern pattern = Pattern.compile(regExpn, Pattern.CASE_INSENSITIVE); + Matcher matcher = pattern.matcher(password); + + assertTrue(matcher.matches()); + } + +} diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index ec6c8bcb3c..569e5df9bc 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -200,6 +200,7 @@ core-java-string-operations-7 core-java-regex core-java-regex-2 + core-java-regex-3 core-java-uuid core-java-collections-maps-6 core-java-records From 0c507be8d5727e39213ecfdb0897ca9543ca9139 Mon Sep 17 00:00:00 2001 From: timis1 <12120641+timis1@users.noreply.github.com> Date: Wed, 24 Jan 2024 13:29:42 +0200 Subject: [PATCH 101/132] JAVA-30439 Align module names, folder names and artifact id - Week 4 - 2024 (#15709) Co-authored-by: timis1 --- core-java-modules/core-java-swing/pom.xml | 4 ++-- spring-kafka-3_/pom.xml | 12 +++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/core-java-modules/core-java-swing/pom.xml b/core-java-modules/core-java-swing/pom.xml index 28228ebb29..53a2e9b1ff 100644 --- a/core-java-modules/core-java-swing/pom.xml +++ b/core-java-modules/core-java-swing/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - core-java-string-swing - core-java-string-swing + core-java-swing + core-java-swing jar diff --git a/spring-kafka-3_/pom.xml b/spring-kafka-3_/pom.xml index 972412d18e..058b981bc1 100644 --- a/spring-kafka-3_/pom.xml +++ b/spring-kafka-3_/pom.xml @@ -1,5 +1,10 @@ + 4.0.0 + spring-kafka-3_ + jar + spring-kafka-3_ + com.baeldung parent-boot-2 @@ -7,13 +12,6 @@ ../parent-boot-2 - 4.0.0 - - spring-kafka-3 - jar - - spring-kafka-3 - org.springframework.kafka From d1009f0f9157fbb74a9768e00cb8a264e97791dc Mon Sep 17 00:00:00 2001 From: Amit Pandey Date: Wed, 24 Jan 2024 19:10:42 +0530 Subject: [PATCH 102/132] JAVA-27509 :- Update Spring Boot validation to Spring Boot 3. (#15694) --- spring-boot-modules/spring-boot-validation/pom.xml | 11 ++++++++--- .../beanvalidation/application/Application.java | 2 +- .../application/controllers/UserController.java | 2 +- .../beanvalidation/application/entities/User.java | 11 +++++------ .../spring/servicevalidation/dao/UserAccountDao.java | 2 +- .../spring/servicevalidation/domain/UserAccount.java | 10 +++++----- .../spring/servicevalidation/domain/UserAddress.java | 2 +- .../servicevalidation/service/UserAccountService.java | 6 +++--- .../src/main/resources/application.properties | 1 + .../application/UserControllerIntegrationTest.java | 2 +- 10 files changed, 27 insertions(+), 22 deletions(-) create mode 100644 spring-boot-modules/spring-boot-validation/src/main/resources/application.properties diff --git a/spring-boot-modules/spring-boot-validation/pom.xml b/spring-boot-modules/spring-boot-validation/pom.xml index 1412a57e2a..197fc67b22 100644 --- a/spring-boot-modules/spring-boot-validation/pom.xml +++ b/spring-boot-modules/spring-boot-validation/pom.xml @@ -8,9 +8,10 @@ 0.0.1-SNAPSHOT - com.baeldung.spring-boot-modules - spring-boot-modules - 1.0.0-SNAPSHOT + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -41,4 +42,8 @@ + + com.baeldung.beanvalidation.application.Application + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/beanvalidation/application/Application.java b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/beanvalidation/application/Application.java index e2b933a67e..2a1e10edbc 100644 --- a/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/beanvalidation/application/Application.java +++ b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/beanvalidation/application/Application.java @@ -16,7 +16,7 @@ public class Application { } @Bean - public CommandLineRunner run(UserRepository userRepository) throws Exception { + public CommandLineRunner run(UserRepository userRepository) { return (String[] args) -> { User user1 = new User("Bob", "bob@domain.com"); User user2 = new User("Jenny", "jenny@domain.com"); diff --git a/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/beanvalidation/application/controllers/UserController.java b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/beanvalidation/application/controllers/UserController.java index abda9a9449..7e13aec4a0 100644 --- a/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/beanvalidation/application/controllers/UserController.java +++ b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/beanvalidation/application/controllers/UserController.java @@ -6,7 +6,7 @@ import com.baeldung.beanvalidation.application.repositories.UserRepository; import java.util.HashMap; import java.util.List; import java.util.Map; -import javax.validation.Valid; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/beanvalidation/application/entities/User.java b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/beanvalidation/application/entities/User.java index 511ce47775..13fc97661d 100644 --- a/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/beanvalidation/application/entities/User.java +++ b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/beanvalidation/application/entities/User.java @@ -1,11 +1,10 @@ package com.baeldung.beanvalidation.application.entities; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; -import javax.validation.constraints.NotBlank; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.validation.constraints.NotBlank; @Entity public class User { diff --git a/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/dao/UserAccountDao.java b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/dao/UserAccountDao.java index c49c5220f4..adb0117997 100644 --- a/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/dao/UserAccountDao.java +++ b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/dao/UserAccountDao.java @@ -11,7 +11,7 @@ import com.baeldung.spring.servicevalidation.domain.UserAccount; @Service public class UserAccountDao { - private Map DB = new HashMap(); + private Map DB = new HashMap<>(); public String addUserAccount(UserAccount useraccount) { DB.put(useraccount.getName(), useraccount); diff --git a/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/domain/UserAccount.java b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/domain/UserAccount.java index 5b0e795a8a..50ea9a4a66 100644 --- a/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/domain/UserAccount.java +++ b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/domain/UserAccount.java @@ -1,10 +1,10 @@ package com.baeldung.spring.servicevalidation.domain; -import javax.validation.Valid; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; public class UserAccount { diff --git a/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/domain/UserAddress.java b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/domain/UserAddress.java index cd149dc5f5..276f18ff67 100644 --- a/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/domain/UserAddress.java +++ b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/domain/UserAddress.java @@ -1,6 +1,6 @@ package com.baeldung.spring.servicevalidation.domain; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; public class UserAddress { diff --git a/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/service/UserAccountService.java b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/service/UserAccountService.java index 9d79e4e226..648c45d893 100644 --- a/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/service/UserAccountService.java +++ b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/service/UserAccountService.java @@ -2,9 +2,9 @@ package com.baeldung.spring.servicevalidation.service; import java.util.Set; -import javax.validation.ConstraintViolation; -import javax.validation.ConstraintViolationException; -import javax.validation.Validator; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolationException; +import jakarta.validation.Validator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/spring-boot-modules/spring-boot-validation/src/main/resources/application.properties b/spring-boot-modules/spring-boot-validation/src/main/resources/application.properties new file mode 100644 index 0000000000..ead0df89a3 --- /dev/null +++ b/spring-boot-modules/spring-boot-validation/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.jpa.properties.hibernate.globally_quoted_identifiers=true diff --git a/spring-boot-modules/spring-boot-validation/src/test/java/com/baeldung/beanvalidation/application/UserControllerIntegrationTest.java b/spring-boot-modules/spring-boot-validation/src/test/java/com/baeldung/beanvalidation/application/UserControllerIntegrationTest.java index 21fcaf922c..c26174d961 100644 --- a/spring-boot-modules/spring-boot-validation/src/test/java/com/baeldung/beanvalidation/application/UserControllerIntegrationTest.java +++ b/spring-boot-modules/spring-boot-validation/src/test/java/com/baeldung/beanvalidation/application/UserControllerIntegrationTest.java @@ -34,7 +34,7 @@ public class UserControllerIntegrationTest { private MockMvc mockMvc; @Test - public void whenUserControllerInjected_thenNotNull() throws Exception { + public void whenUserControllerInjected_thenNotNull() { assertThat(userController).isNotNull(); } From 120c2357ee2d35ba5e91a1139cc49f55dbbc27f8 Mon Sep 17 00:00:00 2001 From: Eugene Kovko <37694937+eukovko@users.noreply.github.com> Date: Wed, 24 Jan 2024 21:29:55 +0100 Subject: [PATCH 103/132] Bael 7231 fixing typos (#15718) * feat: Fix typo * feat: Fix type --- .../SettingSameProcessEnvironmentVariableUnitTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core-java-modules/core-java-lang-6/src/test/java/com/baeldung/setenvironment/SettingSameProcessEnvironmentVariableUnitTest.java b/core-java-modules/core-java-lang-6/src/test/java/com/baeldung/setenvironment/SettingSameProcessEnvironmentVariableUnitTest.java index dacd351c83..7cd44430fa 100644 --- a/core-java-modules/core-java-lang-6/src/test/java/com/baeldung/setenvironment/SettingSameProcessEnvironmentVariableUnitTest.java +++ b/core-java-modules/core-java-lang-6/src/test/java/com/baeldung/setenvironment/SettingSameProcessEnvironmentVariableUnitTest.java @@ -23,10 +23,10 @@ class SettingSameProcessEnvironmentVariableUnitTest { = Collections.unmodifiableMap(Collections.emptyMap()).getClass(); private static final Class MAP_CLASS = Map.class; public static final String ENV_VARIABLE_NAME = "test"; - public static final String ENB_VARIABLE_VALUE = "Hello World"; + public static final String ENV_VARIABLE_VALUE = "Hello World"; @ParameterizedTest - @CsvSource({ENB_VARIABLE_VALUE + "," + ENV_VARIABLE_NAME}) + @CsvSource({ENV_VARIABLE_VALUE + "," + ENV_VARIABLE_NAME}) @EnabledForJreRange(max = JRE.JAVA_16) void givenReflexiveAccess_whenGetSourceMap_thenSuccessfullyModifyVariables(String environmentVariable, String value) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { @@ -47,17 +47,17 @@ class SettingSameProcessEnvironmentVariableUnitTest { } @Test - void givenOS_whenGetPath_thenVariablesArePresent() { + void givenOS_whenGetEnv_thenVariablesArePresent() { Map environment = System.getenv(); assertThat(environment).isNotNull(); } @Test - @SetEnvironmentVariable(key = ENV_VARIABLE_NAME, value = ENB_VARIABLE_VALUE) + @SetEnvironmentVariable(key = ENV_VARIABLE_NAME, value = ENV_VARIABLE_VALUE) @EnabledForJreRange(max = JRE.JAVA_16) void givenVariableSet_whenGetEnvironmentVariable_thenReturnsCorrectValue() { String actual = System.getenv(ENV_VARIABLE_NAME); - assertThat(actual).isEqualTo(ENB_VARIABLE_VALUE); + assertThat(actual).isEqualTo(ENV_VARIABLE_VALUE); } @SuppressWarnings("unchecked") From ec8bf626eb2399a64098d7524364a2ee0389e5b4 Mon Sep 17 00:00:00 2001 From: Rajat Garg Date: Thu, 25 Jan 2024 02:09:08 +0530 Subject: [PATCH 104/132] Add new maven module (#15723) Co-authored-by: rajatgarg --- .../core-java-datetime-conversion-2/README.md | 6 ++ .../core-java-datetime-conversion-2/pom.xml | 57 +++++++++++++++++++ .../GregorianToHijriDateConverter.java | 0 ...GregorianToHijriDateConverterUnitTest.java | 0 .../core-java-datetime-conversion/pom.xml | 7 --- core-java-modules/pom.xml | 1 + 6 files changed, 64 insertions(+), 7 deletions(-) create mode 100644 core-java-modules/core-java-datetime-conversion-2/README.md create mode 100644 core-java-modules/core-java-datetime-conversion-2/pom.xml rename core-java-modules/{core-java-datetime-conversion => core-java-datetime-conversion-2}/src/main/java/com/baeldung/gregoriantohijri/GregorianToHijriDateConverter.java (100%) rename core-java-modules/{core-java-datetime-conversion => core-java-datetime-conversion-2}/src/test/java/com/baeldung/gregoriantohijri/GregorianToHijriDateConverterUnitTest.java (100%) diff --git a/core-java-modules/core-java-datetime-conversion-2/README.md b/core-java-modules/core-java-datetime-conversion-2/README.md new file mode 100644 index 0000000000..a4204729e1 --- /dev/null +++ b/core-java-modules/core-java-datetime-conversion-2/README.md @@ -0,0 +1,6 @@ +## Java Date/time conversion Cookbooks and Examples + +This module contains articles about converting between Java date and time objects. + +### Relevant Articles: + diff --git a/core-java-modules/core-java-datetime-conversion-2/pom.xml b/core-java-modules/core-java-datetime-conversion-2/pom.xml new file mode 100644 index 0000000000..079df86a72 --- /dev/null +++ b/core-java-modules/core-java-datetime-conversion-2/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + core-java-datetime-conversion-2 + ${project.parent.version} + core-java-datetime-conversion-2 + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + + joda-time + joda-time + ${joda-time.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + com.github.msarhan + ummalqura-calendar + ${ummalqura-calendar.version} + + + + + + core-java-datetime-conversion-2 + + + src/main/resources + true + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + + 2.12.5 + 2.0.2 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/gregoriantohijri/GregorianToHijriDateConverter.java b/core-java-modules/core-java-datetime-conversion-2/src/main/java/com/baeldung/gregoriantohijri/GregorianToHijriDateConverter.java similarity index 100% rename from core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/gregoriantohijri/GregorianToHijriDateConverter.java rename to core-java-modules/core-java-datetime-conversion-2/src/main/java/com/baeldung/gregoriantohijri/GregorianToHijriDateConverter.java diff --git a/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/gregoriantohijri/GregorianToHijriDateConverterUnitTest.java b/core-java-modules/core-java-datetime-conversion-2/src/test/java/com/baeldung/gregoriantohijri/GregorianToHijriDateConverterUnitTest.java similarity index 100% rename from core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/gregoriantohijri/GregorianToHijriDateConverterUnitTest.java rename to core-java-modules/core-java-datetime-conversion-2/src/test/java/com/baeldung/gregoriantohijri/GregorianToHijriDateConverterUnitTest.java diff --git a/core-java-modules/core-java-datetime-conversion/pom.xml b/core-java-modules/core-java-datetime-conversion/pom.xml index f415b8a6ce..17b5ff62ab 100644 --- a/core-java-modules/core-java-datetime-conversion/pom.xml +++ b/core-java-modules/core-java-datetime-conversion/pom.xml @@ -25,12 +25,6 @@ commons-lang3 ${commons-lang3.version} - - com.github.msarhan - ummalqura-calendar - ${ummalqura-calendar.version} - - @@ -51,7 +45,6 @@ 2.12.5 - 2.0.2 \ No newline at end of file diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index 569e5df9bc..568fc37811 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -211,6 +211,7 @@ core-java-collections-set core-java-date-operations-1 core-java-datetime-conversion + core-java-datetime-conversion-2 core-java-httpclient java-native java-rmi From 81f7ea2aa88364fd72e679612e1713ed9e1d97cc Mon Sep 17 00:00:00 2001 From: timis1 <12120641+timis1@users.noreply.github.com> Date: Thu, 25 Jan 2024 01:01:14 +0200 Subject: [PATCH 105/132] JAVA-29286 Upgrade spring-security-auth0 (#15715) Co-authored-by: timis1 --- spring-security-modules/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-security-modules/pom.xml b/spring-security-modules/pom.xml index 1b3db18b84..0781a98119 100644 --- a/spring-security-modules/pom.xml +++ b/spring-security-modules/pom.xml @@ -17,7 +17,7 @@ spring-security-acl - spring-security-auth0 + spring-security-auth0 spring-security-cognito spring-security-core spring-security-core-2 From cb34210a520444ba3b4aa9164b064d6a4f2b4806 Mon Sep 17 00:00:00 2001 From: Kai Yuan Date: Thu, 25 Jan 2024 03:09:32 +0100 Subject: [PATCH 106/132] [unicode-from-number] BAEL-5832 (#15689) --- ...odeCharFromCodePointHexStringUnitTest.java | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 core-java-modules/core-java-char/src/test/java/com/baeldung/unicodechar/UnicodeCharFromCodePointHexStringUnitTest.java diff --git a/core-java-modules/core-java-char/src/test/java/com/baeldung/unicodechar/UnicodeCharFromCodePointHexStringUnitTest.java b/core-java-modules/core-java-char/src/test/java/com/baeldung/unicodechar/UnicodeCharFromCodePointHexStringUnitTest.java new file mode 100644 index 0000000000..014267abdc --- /dev/null +++ b/core-java-modules/core-java-char/src/test/java/com/baeldung/unicodechar/UnicodeCharFromCodePointHexStringUnitTest.java @@ -0,0 +1,70 @@ +package com.baeldung.unicodechar; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class UnicodeCharFromCodePointHexStringUnitTest { + private static final String U_CHECK = "✅"; // U+2705 + private static final String U_STRONG = "强"; // U+5F3A + + + @Test + void whenEscapeUAndNumberInString_thenGetExpectedUnicodeStr() { + String check = "\u2705"; + assertEquals(U_CHECK, check); + + String strong = "\u5F3A"; + assertEquals(U_STRONG, strong); + + // "A" U+0041 + assertEquals("A", "\u0041"); + } + + + @Test + void whenConcatUAndNumberAsString_thenDoNotGetExpectedUnicodeStr() { + String check = "\\u" + "2705"; + assertEquals("\\u2705", check); + + String strong = "\\u" + "5F3A"; + assertEquals("\\u5F3A", strong); + } + + + @Test + void whenCastHexCodePointToCharAndConvertCharToString_thenGetExpectedUnicodeStr() { + + int codePoint = Integer.parseInt("2705", 16); //Decimal int: 9989 + char[] checkChar = Character.toChars(codePoint); + String check = String.valueOf(checkChar); + assertEquals(U_CHECK, check); + + // For Java 11 and later versions + // assertEquals(U_CHECK, Character.toString(codePoint)); + + codePoint = Integer.parseInt("5F3A", 16); //Decimal int: 24378 + char[] strongChar = Character.toChars(codePoint); + String strong = String.valueOf(strongChar); + assertEquals(U_STRONG, strong); + + // For Java 11 and later versions + // assertEquals(U_STRONG, Character.toString(codePoint)); + } + + String stringFromCodePointHex(String codePointHex) { + int codePoint = Integer.parseInt(codePointHex, 16); + + // For Java 11 and later versions: return Character.toString(codePoint) + + char[] chars = Character.toChars(codePoint); + return String.valueOf(chars); + } + + @Test + void whenUsingstringFromCodePointHex_thenGetExpectedUnicodeStr() { + assertEquals("A", stringFromCodePointHex("0041")); + assertEquals(U_CHECK, stringFromCodePointHex("2705")); + assertEquals(U_STRONG, stringFromCodePointHex("5F3A")); + } +} \ No newline at end of file From 8154f89f1797008fe3519b06a49b56903747dd5d Mon Sep 17 00:00:00 2001 From: Mo Helmy <135069400+BenHelmyBen@users.noreply.github.com> Date: Thu, 25 Jan 2024 19:17:03 +0200 Subject: [PATCH 107/132] Update PasswordValidationUsingRegexUnitTest.java (#15726) Typo fixed --- .../PasswordValidationUsingRegexUnitTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core-java-modules/core-java-regex-3/src/test/java/com/baeldung/passwordvalidation/PasswordValidationUsingRegexUnitTest.java b/core-java-modules/core-java-regex-3/src/test/java/com/baeldung/passwordvalidation/PasswordValidationUsingRegexUnitTest.java index b55943f1b6..cbd1f1da58 100644 --- a/core-java-modules/core-java-regex-3/src/test/java/com/baeldung/passwordvalidation/PasswordValidationUsingRegexUnitTest.java +++ b/core-java-modules/core-java-regex-3/src/test/java/com/baeldung/passwordvalidation/PasswordValidationUsingRegexUnitTest.java @@ -15,8 +15,8 @@ public class PasswordValidationUsingRegexUnitTest { boolean result = false; try { if (password != null) { - String MIN_LENGHT = "8"; - String MAX_LENGHT = "20"; + String MIN_LENGTH = "8"; + String MAX_LENGTH = "20"; boolean SPECIAL_CHAR_NEEDED = false; String ONE_DIGIT = "(?=.*[0-9])"; @@ -25,7 +25,7 @@ public class PasswordValidationUsingRegexUnitTest { String SPECIAL_CHAR = SPECIAL_CHAR_NEEDED ? "(?=.*[@#$%^&+=])" : ""; String NO_SPACE = "(?=\\S+$)"; - String MIN_MAX_CHAR = ".{" + MIN_LENGHT + "," + MAX_LENGHT + "}"; + String MIN_MAX_CHAR = ".{" + MIN_LENGTH + "," + MAX_LENGTH + "}"; String PATTERN = ONE_DIGIT + LOWER_CASE + UPPER_CASE + SPECIAL_CHAR + NO_SPACE + MIN_MAX_CHAR; assertTrue(password.matches(PATTERN)); From 450e82b2ca57ddabeba6eaa2f10b8acef3a1566b Mon Sep 17 00:00:00 2001 From: Eugene Kovko <37694937+eukovko@users.noreply.github.com> Date: Thu, 25 Jan 2024 18:30:04 +0100 Subject: [PATCH 108/132] Bael 7452 fixes (#15729) * BAEL-7452: Renamed service getter * BAEL-7452: Delombok and cleanup --- .../spring-boot-persistence-4/pom.xml | 6 -- .../java/com/baeldung/listvsset/Service.java | 2 +- .../eager/list/fulldomain/Comment.java | 62 ++++++++++++++- .../eager/list/fulldomain/Group.java | 53 ++++++++++++- .../listvsset/eager/list/fulldomain/Post.java | 62 ++++++++++++++- .../eager/list/fulldomain/Profile.java | 70 ++++++++++++++++- .../listvsset/eager/list/fulldomain/User.java | 78 ++++++++++++++++++- .../eager/list/moderatedomain/Group.java | 53 ++++++++++++- .../eager/list/moderatedomain/Post.java | 54 ++++++++++++- .../eager/list/moderatedomain/User.java | 42 +++++++++- .../eager/list/simpledomain/Post.java | 53 ++++++++++++- .../eager/list/simpledomain/User.java | 62 ++++++++++++++- .../eager/set/fulldomain/Comment.java | 42 +++++++++- .../listvsset/eager/set/fulldomain/Group.java | 33 +++++++- .../listvsset/eager/set/fulldomain/Post.java | 42 +++++++++- .../eager/set/fulldomain/Profile.java | 70 ++++++++++++++++- .../listvsset/eager/set/fulldomain/User.java | 58 +++++++++++++- .../eager/set/lazy/moderatedomain/Group.java | 53 ++++++++++++- .../eager/set/lazy/moderatedomain/Post.java | 33 +++++++- .../eager/set/lazy/moderatedomain/User.java | 42 +++++++++- .../eager/set/moderatedomain/Group.java | 53 ++++++++++++- .../eager/set/moderatedomain/Post.java | 33 +++++++- .../eager/set/moderatedomain/User.java | 42 +++++++++- .../eager/set/simpledomain/Post.java | 33 +++++++- .../eager/set/simpledomain/User.java | 62 ++++++++++++++- .../lazy/list/moderatedomain/Group.java | 53 ++++++++++++- .../list/moderatedomain/GroupService.java | 1 + .../lazy/list/moderatedomain/Post.java | 53 ++++++++++++- .../lazy/list/moderatedomain/User.java | 42 +++++++++- .../nplusone/defaultfetch/list/Post.java | 46 ++++++++++- .../nplusone/defaultfetch/list/User.java | 56 ++++++++++++- .../BaseNPlusOneIntegrationTest.java | 6 +- ...sOneLazyModerateDomainIntegrationTest.java | 4 +- ...lusOneLazySimpleDomainIntegrationTest.java | 6 +- ...PlusOneEagerFullDomainIntegrationTest.java | 4 +- ...OneEagerModerateDomainIntegrationTest.java | 4 +- ...usOneEagerSimpleDomainIntegrationTest.java | 10 +-- ...OneEagerFullDomainJoinIntegrationTest.java | 4 +- ...OneEagerModerateDomainIntegrationTest.java | 4 +- ...usOneEagerSimpleDomainIntegrationTest.java | 10 +-- 40 files changed, 1406 insertions(+), 90 deletions(-) diff --git a/persistence-modules/spring-boot-persistence-4/pom.xml b/persistence-modules/spring-boot-persistence-4/pom.xml index 78cd75234a..1452f5ad66 100644 --- a/persistence-modules/spring-boot-persistence-4/pom.xml +++ b/persistence-modules/spring-boot-persistence-4/pom.xml @@ -57,11 +57,6 @@ jackson-databind ${jackson.version} - - org.projectlombok - lombok - ${lombok.version} - @@ -81,7 +76,6 @@ 1.0.7 3.7.0 2.16.0 - 1.18.28 \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/Service.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/Service.java index 2a700de09b..1b11d6facb 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/Service.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/Service.java @@ -50,7 +50,7 @@ public class Service extends ParametrizationAware { public int getUserByIdWithFunction(Long id, ToIntFunction function) { Optional optionalUser = repository.findById(id); - if(optionalUser.isPresent()) { + if (optionalUser.isPresent()) { return function.applyAsInt(optionalUser.get()); } else { return 0; diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Comment.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Comment.java index 482ddc3dc5..6a939b63bb 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Comment.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Comment.java @@ -4,9 +4,8 @@ import com.fasterxml.jackson.annotation.JsonBackReference; import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.ManyToOne; -import lombok.Data; +import java.util.Objects; -@Data @Entity public class Comment { @@ -22,4 +21,63 @@ public class Comment { @ManyToOne private Post post; + public Comment() { + } + + public Long getId() { + return this.id; + } + + public String getText() { + return this.text; + } + + public User getAuthor() { + return this.author; + } + + public Post getPost() { + return this.post; + } + + public void setId(Long id) { + this.id = id; + } + + public void setText(String text) { + this.text = text; + } + + public void setAuthor(User author) { + this.author = author; + } + + public void setPost(Post post) { + this.post = post; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Comment comment = (Comment) o; + + return Objects.equals(id, comment.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + public String toString() { + return "Comment(id=" + this.getId() + ", text=" + this.getText() + ", author=" + this.getAuthor() + ", post=" + this.getPost() + + ")"; + } } diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Group.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Group.java index 0f02d3025c..57a8b40378 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Group.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Group.java @@ -6,9 +6,8 @@ import jakarta.persistence.Id; import jakarta.persistence.ManyToMany; import jakarta.persistence.Table; import java.util.List; -import lombok.Data; +import java.util.Objects; -@Data @Entity(name = "interest_group") @Table(name = "interest_group") public class Group { @@ -20,4 +19,54 @@ public class Group { @ManyToMany(fetch = FetchType.EAGER) private List members; + + public Group() { + } + + public Long getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public List getMembers() { + return this.members; + } + + public void setId(Long id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public void setMembers(List members) { + this.members = members; + } + + @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(id, group.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + public String toString() { + return "Group(id=" + this.getId() + ", name=" + this.getName() + ", members=" + this.getMembers() + ")"; + } } diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Post.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Post.java index 301301a1ff..bfcbfeb0fd 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Post.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Post.java @@ -10,10 +10,9 @@ import jakarta.persistence.Lob; import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; import java.util.List; -import lombok.Data; +import java.util.Objects; @Entity -@Data public class Post { @Id @@ -29,4 +28,63 @@ public class Post { @JsonBackReference @ManyToOne private User author; + + public Post() { + } + + public Long getId() { + return this.id; + } + + public String getContent() { + return this.content; + } + + public List getComments() { + return this.comments; + } + + public User getAuthor() { + return this.author; + } + + public void setId(Long id) { + this.id = id; + } + + public void setContent(String content) { + this.content = content; + } + + public void setComments(List comments) { + this.comments = comments; + } + + public void setAuthor(User author) { + this.author = author; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Post post = (Post) o; + + return Objects.equals(id, post.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + public String toString() { + return "Post(id=" + this.getId() + ", content=" + this.getContent() + ", comments=" + this.getComments() + ", author=" + + this.getAuthor() + ")"; + } } diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Profile.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Profile.java index 9e29eec2aa..06a453b42a 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Profile.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/Profile.java @@ -6,10 +6,9 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.Lob; import jakarta.persistence.OneToOne; -import lombok.Data; +import java.util.Objects; @Entity -@Data public class Profile { @Id @@ -24,5 +23,72 @@ public class Profile { @OneToOne(mappedBy = "profile") @JoinColumn(unique = true) private User user; + + public Profile() { + } + + public Long getId() { + return this.id; + } + + public String getBiography() { + return this.biography; + } + + public String getWebsite() { + return this.website; + } + + public String getProfilePictureUrl() { + return this.profilePictureUrl; + } + + public User getUser() { + return this.user; + } + + public void setId(Long id) { + this.id = id; + } + + public void setBiography(String biography) { + this.biography = biography; + } + + public void setWebsite(String website) { + this.website = website; + } + + public void setProfilePictureUrl(String profilePictureUrl) { + this.profilePictureUrl = profilePictureUrl; + } + + public void setUser(User user) { + this.user = user; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Profile profile = (Profile) o; + + return Objects.equals(id, profile.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + public String toString() { + return "Profile(id=" + this.getId() + ", biography=" + this.getBiography() + ", website=" + this.getWebsite() + + ", profilePictureUrl=" + this.getProfilePictureUrl() + ", user=" + this.getUser() + ")"; + } } diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/User.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/User.java index 48f733e27a..4f0c26d0a1 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/User.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/fulldomain/User.java @@ -10,9 +10,8 @@ import jakarta.persistence.OneToMany; import jakarta.persistence.OneToOne; import jakarta.persistence.Table; import java.util.List; -import lombok.Data; +import java.util.Objects; -@Data @Entity(name = "simple_user") @Table(name = "simple_user") public class User { @@ -33,4 +32,79 @@ public class User { @ManyToMany(mappedBy = "members", fetch = FetchType.EAGER) private List groups; + + public User() { + } + + public Long getId() { + return this.id; + } + + public String getUsername() { + return this.username; + } + + public String getEmail() { + return this.email; + } + + public Profile getProfile() { + return this.profile; + } + + public List getPosts() { + return this.posts; + } + + public List getGroups() { + return this.groups; + } + + public void setId(Long id) { + this.id = id; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setEmail(String email) { + this.email = email; + } + + public void setProfile(Profile profile) { + this.profile = profile; + } + + public void setPosts(List posts) { + this.posts = posts; + } + + public void setGroups(List groups) { + this.groups = groups; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + User user = (User) o; + + return Objects.equals(id, user.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + public String toString() { + return "User(id=" + this.getId() + ", username=" + this.getUsername() + ", email=" + this.getEmail() + ", profile=" + + this.getProfile() + ", posts=" + this.getPosts() + ", groups=" + this.getGroups() + ")"; + } } \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/Group.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/Group.java index 0460f77a60..10ed2f37e8 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/Group.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/Group.java @@ -6,9 +6,8 @@ import jakarta.persistence.Id; import jakarta.persistence.ManyToMany; import jakarta.persistence.Table; import java.util.List; -import lombok.Data; +import java.util.Objects; -@Data @Entity(name = "interest_group") @Table(name = "interest_group") public class Group { @@ -20,4 +19,54 @@ public class Group { @ManyToMany(fetch = FetchType.EAGER) private List members; + + public Group() { + } + + public Long getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public List getMembers() { + return this.members; + } + + public void setId(Long id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public void setMembers(List members) { + this.members = members; + } + + @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(id, group.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + public String toString() { + return "Group(id=" + this.getId() + ", name=" + this.getName() + ", members=" + this.getMembers() + ")"; + } } diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/Post.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/Post.java index faef97b212..479d0cfdd3 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/Post.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/Post.java @@ -5,10 +5,9 @@ import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Lob; import jakarta.persistence.ManyToOne; -import lombok.Data; +import java.util.Objects; @Entity -@Data public class Post { @Id @@ -20,4 +19,55 @@ public class Post { @JsonBackReference @ManyToOne private User author; + + public Post() { + } + + public Long getId() { + return this.id; + } + + public String getContent() { + return this.content; + } + + public User getAuthor() { + return this.author; + } + + public void setId(Long id) { + this.id = id; + } + + public void setContent(String content) { + this.content = content; + } + + public void setAuthor(User author) { + this.author = author; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Post post = (Post) o; + + return Objects.equals(id, post.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + public String toString() { + return "Post(id=" + this.getId() + ", content=" + this.getContent() + ", author=" + this.getAuthor() + ")"; + } } diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/User.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/User.java index a58f6dd9e5..e3d7925d56 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/User.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/moderatedomain/User.java @@ -9,9 +9,7 @@ import jakarta.persistence.OneToMany; import jakarta.persistence.Table; import java.util.List; import java.util.Objects; -import lombok.Data; -@Data @Entity(name = "simple_user") @Table(name = "simple_user") public class User { @@ -25,6 +23,41 @@ public class User { @OneToMany(cascade = CascadeType.ALL, mappedBy = "author", fetch = FetchType.EAGER) protected List posts; + public User() { + } + + public Long getId() { + return this.id; + } + + public String getUsername() { + return this.username; + } + + public String getEmail() { + return this.email; + } + + public List getPosts() { + return this.posts; + } + + public void setId(Long id) { + this.id = id; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setEmail(String email) { + this.email = email; + } + + public void setPosts(List posts) { + this.posts = posts; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -43,4 +76,9 @@ public class User { public int hashCode() { return id != null ? id.hashCode() : 0; } + + public String toString() { + return "User(id=" + this.getId() + ", username=" + this.getUsername() + ", email=" + this.getEmail() + ", posts=" + this.getPosts() + + ")"; + } } \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/Post.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/Post.java index 35c436357f..159e95bd70 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/Post.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/Post.java @@ -5,10 +5,9 @@ import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Lob; import jakarta.persistence.ManyToOne; -import lombok.Data; +import java.util.Objects; @Entity -@Data public class Post { @Id @@ -20,4 +19,54 @@ public class Post { @JsonBackReference @ManyToOne private User author; + + public Post() { + } + + public Long getId() { + return this.id; + } + + public String getContent() { + return this.content; + } + + public User getAuthor() { + return this.author; + } + + public void setId(Long id) { + this.id = id; + } + + public void setContent(String content) { + this.content = content; + } + + public void setAuthor(User author) { + this.author = author; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Post post = (Post) o; + + return Objects.equals(id, post.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + public String toString() { + return "Post(id=" + this.getId() + ", content=" + this.getContent() + ", author=" + this.getAuthor() + ")"; + } } diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/User.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/User.java index 6495761c18..ba861b8bc1 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/User.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/list/simpledomain/User.java @@ -8,9 +8,8 @@ import jakarta.persistence.Id; import jakarta.persistence.OneToMany; import jakarta.persistence.Table; import java.util.List; -import lombok.Data; +import java.util.Objects; -@Data @Entity(name = "simple_user") @Table(name = "simple_user") public class User { @@ -23,4 +22,63 @@ public class User { @JsonManagedReference @OneToMany(cascade = CascadeType.ALL, mappedBy = "author", fetch = FetchType.EAGER) protected List posts; + + public User() { + } + + public Long getId() { + return this.id; + } + + public String getUsername() { + return this.username; + } + + public String getEmail() { + return this.email; + } + + public List getPosts() { + return this.posts; + } + + public void setId(Long id) { + this.id = id; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setEmail(String email) { + this.email = email; + } + + public void setPosts(List posts) { + this.posts = posts; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + User user = (User) o; + + return Objects.equals(id, user.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + public String toString() { + return "User(id=" + this.getId() + ", username=" + this.getUsername() + ", email=" + this.getEmail() + ", posts=" + this.getPosts() + + ")"; + } } \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Comment.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Comment.java index ab935de4ee..be80c53308 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Comment.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Comment.java @@ -5,9 +5,7 @@ import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.ManyToOne; import java.util.Objects; -import lombok.Data; -@Data @Entity public class Comment { @@ -23,6 +21,41 @@ public class Comment { @ManyToOne private Post post; + public Comment() { + } + + public Long getId() { + return this.id; + } + + public String getText() { + return this.text; + } + + public User getAuthor() { + return this.author; + } + + public Post getPost() { + return this.post; + } + + public void setId(Long id) { + this.id = id; + } + + public void setText(String text) { + this.text = text; + } + + public void setAuthor(User author) { + this.author = author; + } + + public void setPost(Post post) { + this.post = post; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -41,4 +74,9 @@ public class Comment { public int hashCode() { return id != null ? id.hashCode() : 0; } + + public String toString() { + return "Comment(id=" + this.getId() + ", text=" + this.getText() + ", author=" + this.getAuthor() + ", post=" + this.getPost() + + ")"; + } } diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Group.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Group.java index de0ba9a59d..dc8cc7dcb1 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Group.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Group.java @@ -7,9 +7,7 @@ import jakarta.persistence.ManyToMany; import jakarta.persistence.Table; import java.util.Objects; import java.util.Set; -import lombok.Data; -@Data @Entity(name = "interest_group") @Table(name = "interest_group") public class Group { @@ -22,6 +20,33 @@ public class Group { @ManyToMany(fetch = FetchType.EAGER) private Set members; + public Group() { + } + + public Long getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public Set getMembers() { + return this.members; + } + + public void setId(Long id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public void setMembers(Set members) { + this.members = members; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -40,4 +65,8 @@ public class Group { public int hashCode() { return id != null ? id.hashCode() : 0; } + + public String toString() { + return "Group(id=" + this.getId() + ", name=" + this.getName() + ", members=" + this.getMembers() + ")"; + } } diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Post.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Post.java index 7c4913fbec..1486c6fe03 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Post.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Post.java @@ -11,10 +11,8 @@ import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; import java.util.Objects; import java.util.Set; -import lombok.Data; @Entity -@Data public class Post { @Id @@ -31,6 +29,41 @@ public class Post { @ManyToOne private User author; + public Post() { + } + + public Long getId() { + return this.id; + } + + public String getContent() { + return this.content; + } + + public Set getComments() { + return this.comments; + } + + public User getAuthor() { + return this.author; + } + + public void setId(Long id) { + this.id = id; + } + + public void setContent(String content) { + this.content = content; + } + + public void setComments(Set comments) { + this.comments = comments; + } + + public void setAuthor(User author) { + this.author = author; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -49,4 +82,9 @@ public class Post { public int hashCode() { return id != null ? id.hashCode() : 0; } + + public String toString() { + return "Post(id=" + this.getId() + ", content=" + this.getContent() + ", comments=" + this.getComments() + ", author=" + + this.getAuthor() + ")"; + } } diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Profile.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Profile.java index 914702a373..f13fc276ca 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Profile.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/Profile.java @@ -6,10 +6,9 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.Lob; import jakarta.persistence.OneToOne; -import lombok.Data; +import java.util.Objects; @Entity -@Data public class Profile { @Id @@ -24,5 +23,72 @@ public class Profile { @OneToOne(mappedBy = "profile") @JoinColumn(unique = true) private User user; + + public Profile() { + } + + public Long getId() { + return this.id; + } + + public String getBiography() { + return this.biography; + } + + public String getWebsite() { + return this.website; + } + + public String getProfilePictureUrl() { + return this.profilePictureUrl; + } + + public User getUser() { + return this.user; + } + + public void setId(Long id) { + this.id = id; + } + + public void setBiography(String biography) { + this.biography = biography; + } + + public void setWebsite(String website) { + this.website = website; + } + + public void setProfilePictureUrl(String profilePictureUrl) { + this.profilePictureUrl = profilePictureUrl; + } + + public void setUser(User user) { + this.user = user; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Profile profile = (Profile) o; + + return Objects.equals(id, profile.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + public String toString() { + return "Profile(id=" + this.getId() + ", biography=" + this.getBiography() + ", website=" + this.getWebsite() + + ", profilePictureUrl=" + this.getProfilePictureUrl() + ", user=" + this.getUser() + ")"; + } } diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/User.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/User.java index a0efbac57a..0fe9603e9b 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/User.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/fulldomain/User.java @@ -11,9 +11,7 @@ import jakarta.persistence.OneToOne; import jakarta.persistence.Table; import java.util.Objects; import java.util.Set; -import lombok.Data; -@Data @Entity(name = "simple_user") @Table(name = "simple_user") public class User { @@ -35,6 +33,57 @@ public class User { @ManyToMany(mappedBy = "members", fetch = FetchType.EAGER) private Set groups; + public User() { + } + + public Long getId() { + return this.id; + } + + public String getUsername() { + return this.username; + } + + public String getEmail() { + return this.email; + } + + public Profile getProfile() { + return this.profile; + } + + public Set getPosts() { + return this.posts; + } + + public Set getGroups() { + return this.groups; + } + + public void setId(Long id) { + this.id = id; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setEmail(String email) { + this.email = email; + } + + public void setProfile(Profile profile) { + this.profile = profile; + } + + public void setPosts(Set posts) { + this.posts = posts; + } + + public void setGroups(Set groups) { + this.groups = groups; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -53,4 +102,9 @@ public class User { public int hashCode() { return id != null ? id.hashCode() : 0; } + + public String toString() { + return "User(id=" + this.getId() + ", username=" + this.getUsername() + ", email=" + this.getEmail() + ", profile=" + + this.getProfile() + ", posts=" + this.getPosts() + ", groups=" + this.getGroups() + ")"; + } } \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Group.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Group.java index 28e94f542b..3165441ae4 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Group.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Group.java @@ -4,10 +4,9 @@ import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.ManyToMany; import jakarta.persistence.Table; +import java.util.Objects; import java.util.Set; -import lombok.Data; -@Data @Entity(name = "interest_group") @Table(name = "interest_group") public class Group { @@ -19,4 +18,54 @@ public class Group { @ManyToMany private Set members; + + public Group() { + } + + public Long getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public Set getMembers() { + return this.members; + } + + public void setId(Long id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public void setMembers(Set members) { + this.members = members; + } + + @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(id, group.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + public String toString() { + return "Group(id=" + this.getId() + ", name=" + this.getName() + ", members=" + this.getMembers() + ")"; + } } diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Post.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Post.java index 00edc08e5f..f1a8aadc15 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Post.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Post.java @@ -6,10 +6,8 @@ import jakarta.persistence.Id; import jakarta.persistence.Lob; import jakarta.persistence.ManyToOne; import java.util.Objects; -import lombok.Data; @Entity -@Data public class Post { @Id @@ -22,6 +20,33 @@ public class Post { @ManyToOne private User author; + public Post() { + } + + public Long getId() { + return this.id; + } + + public String getContent() { + return this.content; + } + + public User getAuthor() { + return this.author; + } + + public void setId(Long id) { + this.id = id; + } + + public void setContent(String content) { + this.content = content; + } + + public void setAuthor(User author) { + this.author = author; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -40,4 +65,8 @@ public class Post { public int hashCode() { return id != null ? id.hashCode() : 0; } + + public String toString() { + return "Post(id=" + this.getId() + ", content=" + this.getContent() + ", author=" + this.getAuthor() + ")"; + } } diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/User.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/User.java index adb4db8921..fdba1e7efc 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/User.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/User.java @@ -8,9 +8,7 @@ import jakarta.persistence.OneToMany; import jakarta.persistence.Table; import java.util.Objects; import java.util.Set; -import lombok.Data; -@Data @Entity(name = "simple_user") @Table(name = "simple_user") public class User { @@ -24,6 +22,41 @@ public class User { @OneToMany(cascade = CascadeType.ALL, mappedBy = "author") protected Set posts; + public User() { + } + + public Long getId() { + return this.id; + } + + public String getUsername() { + return this.username; + } + + public String getEmail() { + return this.email; + } + + public Set getPosts() { + return this.posts; + } + + public void setId(Long id) { + this.id = id; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setEmail(String email) { + this.email = email; + } + + public void setPosts(Set posts) { + this.posts = posts; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -42,4 +75,9 @@ public class User { public int hashCode() { return id != null ? id.hashCode() : 0; } + + public String toString() { + return "User(id=" + this.getId() + ", username=" + this.getUsername() + ", email=" + this.getEmail() + ", posts=" + this.getPosts() + + ")"; + } } \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/Group.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/Group.java index 6331183ac9..470204074c 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/Group.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/Group.java @@ -5,10 +5,9 @@ import jakarta.persistence.FetchType; import jakarta.persistence.Id; import jakarta.persistence.ManyToMany; import jakarta.persistence.Table; +import java.util.Objects; import java.util.Set; -import lombok.Data; -@Data @Entity(name = "interest_group") @Table(name = "interest_group") public class Group { @@ -20,4 +19,54 @@ public class Group { @ManyToMany(fetch = FetchType.EAGER) private Set members; + + public Group() { + } + + public Long getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public Set getMembers() { + return this.members; + } + + public void setId(Long id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public void setMembers(Set members) { + this.members = members; + } + + @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(id, group.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + public String toString() { + return "Group(id=" + this.getId() + ", name=" + this.getName() + ", members=" + this.getMembers() + ")"; + } } diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/Post.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/Post.java index 02449a3402..c81ffae02d 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/Post.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/Post.java @@ -6,10 +6,8 @@ import jakarta.persistence.Id; import jakarta.persistence.Lob; import jakarta.persistence.ManyToOne; import java.util.Objects; -import lombok.Data; @Entity -@Data public class Post { @Id @@ -22,6 +20,33 @@ public class Post { @ManyToOne private User author; + public Post() { + } + + public Long getId() { + return this.id; + } + + public String getContent() { + return this.content; + } + + public User getAuthor() { + return this.author; + } + + public void setId(Long id) { + this.id = id; + } + + public void setContent(String content) { + this.content = content; + } + + public void setAuthor(User author) { + this.author = author; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -40,4 +65,8 @@ public class Post { public int hashCode() { return id != null ? id.hashCode() : 0; } + + public String toString() { + return "Post(id=" + this.getId() + ", content=" + this.getContent() + ", author=" + this.getAuthor() + ")"; + } } diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/User.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/User.java index 89f9736c41..54a935f382 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/User.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/moderatedomain/User.java @@ -9,9 +9,7 @@ import jakarta.persistence.OneToMany; import jakarta.persistence.Table; import java.util.Objects; import java.util.Set; -import lombok.Data; -@Data @Entity(name = "simple_user") @Table(name = "simple_user") public class User { @@ -25,6 +23,41 @@ public class User { @OneToMany(cascade = CascadeType.ALL, mappedBy = "author", fetch = FetchType.EAGER) protected Set posts; + public User() { + } + + public Long getId() { + return this.id; + } + + public String getUsername() { + return this.username; + } + + public String getEmail() { + return this.email; + } + + public Set getPosts() { + return this.posts; + } + + public void setId(Long id) { + this.id = id; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setEmail(String email) { + this.email = email; + } + + public void setPosts(Set posts) { + this.posts = posts; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -43,4 +76,9 @@ public class User { public int hashCode() { return id != null ? id.hashCode() : 0; } + + public String toString() { + return "User(id=" + this.getId() + ", username=" + this.getUsername() + ", email=" + this.getEmail() + ", posts=" + this.getPosts() + + ")"; + } } \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/Post.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/Post.java index 69c137e350..fa0f334aba 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/Post.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/Post.java @@ -6,10 +6,8 @@ import jakarta.persistence.Id; import jakarta.persistence.Lob; import jakarta.persistence.ManyToOne; import java.util.Objects; -import lombok.Data; @Entity -@Data public class Post { @Id @@ -22,6 +20,33 @@ public class Post { @ManyToOne private User author; + public Post() { + } + + public Long getId() { + return this.id; + } + + public String getContent() { + return this.content; + } + + public User getAuthor() { + return this.author; + } + + public void setId(Long id) { + this.id = id; + } + + public void setContent(String content) { + this.content = content; + } + + public void setAuthor(User author) { + this.author = author; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -40,4 +65,8 @@ public class Post { public int hashCode() { return id != null ? id.hashCode() : 0; } + + public String toString() { + return "Post(id=" + this.getId() + ", content=" + this.getContent() + ", author=" + this.getAuthor() + ")"; + } } diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/User.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/User.java index 481ef14499..a571c50f95 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/User.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/simpledomain/User.java @@ -7,10 +7,9 @@ import jakarta.persistence.FetchType; import jakarta.persistence.Id; import jakarta.persistence.OneToMany; import jakarta.persistence.Table; +import java.util.Objects; import java.util.Set; -import lombok.Data; -@Data @Entity(name = "simple_user") @Table(name = "simple_user") public class User { @@ -24,4 +23,63 @@ public class User { @OneToMany(cascade = CascadeType.ALL, mappedBy = "author", fetch = FetchType.EAGER) protected Set posts; + public User() { + } + + public Long getId() { + return this.id; + } + + public String getUsername() { + return this.username; + } + + public String getEmail() { + return this.email; + } + + public Set getPosts() { + return this.posts; + } + + public void setId(Long id) { + this.id = id; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setEmail(String email) { + this.email = email; + } + + public void setPosts(Set posts) { + this.posts = posts; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + User user = (User) o; + + return Objects.equals(id, user.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + public String toString() { + return "User(id=" + this.getId() + ", username=" + this.getUsername() + ", email=" + this.getEmail() + ", posts=" + this.getPosts() + + ")"; + } } \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Group.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Group.java index f74272cb99..3a20ccf8fb 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Group.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Group.java @@ -5,9 +5,8 @@ import jakarta.persistence.Id; import jakarta.persistence.ManyToMany; import jakarta.persistence.Table; import java.util.List; -import lombok.Data; +import java.util.Objects; -@Data @Entity(name = "interest_group") @Table(name = "interest_group") public class Group { @@ -19,4 +18,54 @@ public class Group { @ManyToMany private List members; + + public Group() { + } + + public Long getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public List getMembers() { + return this.members; + } + + public void setId(Long id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public void setMembers(List members) { + this.members = members; + } + + @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(id, group.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + public String toString() { + return "Group(id=" + this.getId() + ", name=" + this.getName() + ", members=" + this.getMembers() + ")"; + } } diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/GroupService.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/GroupService.java index 7ee2b83566..4bd746fef3 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/GroupService.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/GroupService.java @@ -25,6 +25,7 @@ public class GroupService { public List findAll() { return groupRepository.findAll(); } + public int countNumberOfRequestsWithFunction(ToIntFunction> function) { return function.applyAsInt(groupRepository.findAll()); } diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Post.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Post.java index 3d2dc2a89e..3d7eb1b6d9 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Post.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Post.java @@ -5,10 +5,9 @@ import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Lob; import jakarta.persistence.ManyToOne; -import lombok.Data; +import java.util.Objects; @Entity -@Data public class Post { @Id @@ -20,4 +19,54 @@ public class Post { @JsonBackReference @ManyToOne private User author; + + public Post() { + } + + public Long getId() { + return this.id; + } + + public String getContent() { + return this.content; + } + + public User getAuthor() { + return this.author; + } + + public void setId(Long id) { + this.id = id; + } + + public void setContent(String content) { + this.content = content; + } + + public void setAuthor(User author) { + this.author = author; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Post post = (Post) o; + + return Objects.equals(id, post.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + public String toString() { + return "Post(id=" + this.getId() + ", content=" + this.getContent() + ", author=" + this.getAuthor() + ")"; + } } diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/User.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/User.java index d2c19febca..c3b238d626 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/User.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/User.java @@ -8,9 +8,7 @@ import jakarta.persistence.OneToMany; import jakarta.persistence.Table; import java.util.List; import java.util.Objects; -import lombok.Data; -@Data @Entity(name = "simple_user") @Table(name = "simple_user") public class User { @@ -24,6 +22,9 @@ public class User { @OneToMany(cascade = CascadeType.ALL, mappedBy = "author") protected List posts; + public User() { + } + @Override public boolean equals(Object o) { if (this == o) { @@ -42,4 +43,41 @@ public class User { public int hashCode() { return id != null ? id.hashCode() : 0; } + + public Long getId() { + return this.id; + } + + public String getUsername() { + return this.username; + } + + public String getEmail() { + return this.email; + } + + public List getPosts() { + return this.posts; + } + + public void setId(Long id) { + this.id = id; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setEmail(String email) { + this.email = email; + } + + public void setPosts(List posts) { + this.posts = posts; + } + + public String toString() { + return "User(id=" + this.getId() + ", username=" + this.getUsername() + ", email=" + this.getEmail() + ", posts=" + this.getPosts() + + ")"; + } } \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/Post.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/Post.java index b0ad40ec06..271b6578e1 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/Post.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/Post.java @@ -5,10 +5,9 @@ import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Lob; import jakarta.persistence.ManyToOne; -import lombok.Data; +import java.util.Objects; @Entity -@Data public class Post { @Id @@ -20,4 +19,47 @@ public class Post { @JsonBackReference @ManyToOne private User author; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public User getAuthor() { + return author; + } + + public void setAuthor(User author) { + this.author = author; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Post post = (Post) o; + + return Objects.equals(id, post.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } } diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/User.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/User.java index 81b570a292..e5c5090d38 100644 --- a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/User.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/User.java @@ -7,9 +7,8 @@ import jakarta.persistence.Id; import jakarta.persistence.OneToMany; import jakarta.persistence.Table; import java.util.List; -import lombok.Data; +import java.util.Objects; -@Data @Entity(name = "simple_user") @Table(name = "simple_user") public class User { @@ -21,5 +20,56 @@ public class User { @JsonManagedReference @OneToMany(cascade = CascadeType.ALL, mappedBy = "author") - protected List posts; + private List posts; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public List getPosts() { + return posts; + } + + public void setPosts(List posts) { + this.posts = posts; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + User user = (User) o; + + return Objects.equals(id, user.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } } \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/BaseNPlusOneIntegrationTest.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/BaseNPlusOneIntegrationTest.java index 4e669dadc4..adc4d07170 100644 --- a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/BaseNPlusOneIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/BaseNPlusOneIntegrationTest.java @@ -58,16 +58,16 @@ abstract public class BaseNPlusOneIntegrationTest extends ParametrizationAwar @Test void givenCorrectConfigurationWhenStartContextThenRepositoryIsPresent() { - assertThat(getService()).isNotNull(); + assertThat(getUserService()).isNotNull(); } @Test void givenCorrectDatabaseWhenStartThenDatabaseIsNotEmpty() { - List result = getService().findAll(); + List result = getUserService().findAll(); assertThat(result).isNotEmpty(); } - protected Service getService() { + protected Service getUserService() { Class parametrization = getParametrizationClass().get(0); return (Service) serviceMap.get(parametrization); } diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/lazy/list/NPlusOneLazyModerateDomainIntegrationTest.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/lazy/list/NPlusOneLazyModerateDomainIntegrationTest.java index 2544a73b24..f4a35a8e38 100644 --- a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/lazy/list/NPlusOneLazyModerateDomainIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/lazy/list/NPlusOneLazyModerateDomainIntegrationTest.java @@ -31,14 +31,14 @@ class NPlusOneLazyModerateDomainIntegrationTest extends BaseNPlusOneIntegrationT @Test void givenLazyListBasedUser_whenFetchingAllUsers_thenIssueOneRequest() { - getService().findAll(); + getUserService().findAll(); assertSelectCount(1); } @ParameterizedTest @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) void givenLazyListBasedUser_whenFetchingOneUser_thenIssueOneRequest(Long id) { - getService().getUserById(id); + getUserService().getUserById(id); assertSelectCount(1); } diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/lazy/list/NPlusOneLazySimpleDomainIntegrationTest.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/lazy/list/NPlusOneLazySimpleDomainIntegrationTest.java index 5d61b76d5d..583b67ff0c 100644 --- a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/lazy/list/NPlusOneLazySimpleDomainIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/lazy/list/NPlusOneLazySimpleDomainIntegrationTest.java @@ -22,13 +22,13 @@ class NPlusOneLazySimpleDomainIntegrationTest extends BaseNPlusOneIntegrationTes @Test void givenLazyListBasedUser_WhenFetchingAllUsers_ThenIssueOneRequests() { - getService().findAll(); + getUserService().findAll(); assertSelectCount(1); } @Test void givenLazyListBasedUser_WhenFetchingAllUsersCheckingPosts_ThenIssueNPlusOneRequests() { - int numberOfRequests = getService().countNumberOfRequestsWithFunction(users -> { + int numberOfRequests = getUserService().countNumberOfRequestsWithFunction(users -> { List> usersWithPosts = users.stream() .map(User::getPosts) @@ -42,7 +42,7 @@ class NPlusOneLazySimpleDomainIntegrationTest extends BaseNPlusOneIntegrationTes @ParameterizedTest @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) void givenLazyListBasedUser_WhenFetchingOneUser_ThenIssueTwoRequest(Long id) { - getService().getUserByIdWithPredicate(id, user -> !user.getPosts().isEmpty()); + getUserService().getUserByIdWithPredicate(id, user -> !user.getPosts().isEmpty()); assertSelectCount(2); } diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerFullDomainIntegrationTest.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerFullDomainIntegrationTest.java index 3e7c46f47c..b281bd715f 100644 --- a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerFullDomainIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerFullDomainIntegrationTest.java @@ -37,7 +37,7 @@ class NPlusOneEagerFullDomainIntegrationTest extends BaseNPlusOneIntegrationTest @ParameterizedTest @MethodSource void givenEagerListBasedUser_WhenFetchingAllUsers_ThenIssueNPlusOneRequests(ToIntFunction> function) { - int numberOfRequests = getService().countNumberOfRequestsWithFunction(function); + int numberOfRequests = getUserService().countNumberOfRequestsWithFunction(function); assertSelectCount(numberOfRequests); } @@ -58,7 +58,7 @@ class NPlusOneEagerFullDomainIntegrationTest extends BaseNPlusOneIntegrationTest @ParameterizedTest @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) void givenEagerListBasedUser_WhenFetchingOneUser_ThenUseDFS(Long id) { - int numberOfRequests = getService().getUserByIdWithFunction(id, this::countNumberOfRequests); + int numberOfRequests = getUserService().getUserByIdWithFunction(id, this::countNumberOfRequests); assertSelectCount(numberOfRequests); } diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerModerateDomainIntegrationTest.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerModerateDomainIntegrationTest.java index 5e5549122f..a0b0f4eb10 100644 --- a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerModerateDomainIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerModerateDomainIntegrationTest.java @@ -34,14 +34,14 @@ class NPlusOneEagerModerateDomainIntegrationTest extends BaseNPlusOneIntegration @Test void givenEagerListBasedUser_whenFetchingAllUsers_thenIssueNPlusOneRequests() { - List users = getService().findAll(); + List users = getUserService().findAll(); assertSelectCount(users.size() + 1); } @ParameterizedTest @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) void givenEagerListBasedUser_whenFetchingOneUser_thenIssueOneRequest(Long id) { - getService().getUserById(id); + getUserService().getUserById(id); assertSelectCount(1); } diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerSimpleDomainIntegrationTest.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerSimpleDomainIntegrationTest.java index 0c14ce8e50..957e36e028 100644 --- a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerSimpleDomainIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/list/NPlusOneEagerSimpleDomainIntegrationTest.java @@ -26,21 +26,21 @@ class NPlusOneEagerSimpleDomainIntegrationTest extends BaseNPlusOneIntegrationTe @Test void givenEagerListBasedUser_WhenFetchingAllUsers_ThenIssueNPlusOneRequests() { - List users = getService().findAll(); + List users = getUserService().findAll(); assertSelectCount(users.size() + 1); } @ParameterizedTest @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) void givenEagerListBasedUser_WhenFetchingOneUser_ThenIssueOneRequest(Long id) { - getService().getUserById(id); + getUserService().getUserById(id); assertSelectCount(1); } @ParameterizedTest @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) void givenEagerListBasedUser_whenDeletePost_ThenIssueSingleUpdate(Long id) { - Optional optionalUser = getService().getUserById(id); + Optional optionalUser = getUserService().getUserById(id); assertSelectCount(1); optionalUser.ifPresent(user -> { List posts = user.getPosts(); @@ -48,10 +48,10 @@ class NPlusOneEagerSimpleDomainIntegrationTest extends BaseNPlusOneIntegrationTe reset(); if (!posts.isEmpty()) { posts.get(0).setAuthor(null); - getService().save(user); + getUserService().save(user); assertSelectCount(1); assertUpdateCount(1); - getService().getUserById(id).ifPresent(updatedUser -> { + getUserService().getUserById(id).ifPresent(updatedUser -> { assertThat(updatedUser.getPosts()).hasSize(originalNumberOfPosts - 1); }); } diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerFullDomainJoinIntegrationTest.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerFullDomainJoinIntegrationTest.java index 001398607d..0239993741 100644 --- a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerFullDomainJoinIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerFullDomainJoinIntegrationTest.java @@ -33,7 +33,7 @@ class NPlusOneEagerFullDomainJoinIntegrationTest extends BaseNPlusOneIntegration @Test void givenEagerSetBasedUser_WhenFetchingAllUsers_ThenIssueNPlusOneRequests() { - List users = getService().findAll(); + List users = getUserService().findAll(); assertSelectCount(users.size() + 1); } @@ -43,7 +43,7 @@ class NPlusOneEagerFullDomainJoinIntegrationTest extends BaseNPlusOneIntegration HashMap> visitedMap = new HashMap<>(); visitedMap.put(POSTS, new HashSet<>()); visitedMap.put(USERS, new HashSet<>()); - int numberOfRequests = getService() + int numberOfRequests = getUserService() .getUserByIdWithFunction(id, user -> { int result = 1; visitedMap.get(USERS).add(user.getId()); diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerModerateDomainIntegrationTest.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerModerateDomainIntegrationTest.java index 55b7bfb287..47211e7bca 100644 --- a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerModerateDomainIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerModerateDomainIntegrationTest.java @@ -33,14 +33,14 @@ class NPlusOneEagerModerateDomainIntegrationTest extends BaseNPlusOneIntegration @Test void givenEagerSetBasedUser_whenFetchingAllUsers_thenIssueNPlusOneRequests() { - List users = getService().findAll(); + List users = getUserService().findAll(); assertSelectCount(users.size() + 1); } @ParameterizedTest @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) void givenEagerSetBasedUser_whenFetchingOneUser_thenIssueOneRequest(Long id) { - getService().getUserById(id); + getUserService().getUserById(id); assertSelectCount(1); } diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerSimpleDomainIntegrationTest.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerSimpleDomainIntegrationTest.java index e6161fa57b..4b939307b6 100644 --- a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerSimpleDomainIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/listvsset/set/NPlusOneEagerSimpleDomainIntegrationTest.java @@ -27,21 +27,21 @@ class NPlusOneEagerSimpleDomainIntegrationTest extends BaseNPlusOneIntegrationTe @Test void givenEagerSetBasedUser_WhenFetchingAllUsers_ThenIssueNPlusOneRequests() { - List users = getService().findAll(); + List users = getUserService().findAll(); assertSelectCount(users.size() + 1); } @ParameterizedTest @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) void givenEagerSetBasedUser_WhenFetchingOneUser_ThenIssueOneRequest(Long id) { - getService().getUserById(id); + getUserService().getUserById(id); assertSelectCount(1); } @ParameterizedTest @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) void givenEagerListBasedUser_whenDeletePost_ThenIssueSingleUpdate(Long id) { - Optional optionalUser = getService().getUserById(id); + Optional optionalUser = getUserService().getUserById(id); assertSelectCount(1); optionalUser.ifPresent(user -> { Set posts = user.getPosts(); @@ -49,10 +49,10 @@ class NPlusOneEagerSimpleDomainIntegrationTest extends BaseNPlusOneIntegrationTe reset(); if (!posts.isEmpty()) { posts.iterator().next().setAuthor(null); - getService().save(user); + getUserService().save(user); assertSelectCount(1); assertUpdateCount(1); - getService().getUserById(id).ifPresent(updatedUser -> { + getUserService().getUserById(id).ifPresent(updatedUser -> { assertThat(updatedUser.getPosts()).hasSize(originalNumberOfPosts - 1); }); } From 6c53d9f828fc3fd301527e53d689a84fad628f6a Mon Sep 17 00:00:00 2001 From: Eugene Kovko <37694937+eukovko@users.noreply.github.com> Date: Thu, 25 Jan 2024 19:56:45 +0100 Subject: [PATCH 109/132] BAEL-7063: OOM example (#15730) --- .../com/baeldung/oom/OomCrashUnitTest.java | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 core-java-modules/core-java-perf-2/src/test/java/com/baeldung/oom/OomCrashUnitTest.java diff --git a/core-java-modules/core-java-perf-2/src/test/java/com/baeldung/oom/OomCrashUnitTest.java b/core-java-modules/core-java-perf-2/src/test/java/com/baeldung/oom/OomCrashUnitTest.java new file mode 100644 index 0000000000..21b7c83ad4 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/test/java/com/baeldung/oom/OomCrashUnitTest.java @@ -0,0 +1,52 @@ +package com.baeldung.oom; + +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +@Disabled +class OomCrashUnitTest { + + public static final Runnable MEMORY_LEAK = () -> { + List list = new ArrayList<>(); + while (true) { + list.add(tenMegabytes()); + } + }; + + @Test + void givenMemoryLeakCode_whenRunInsideThread_thenMainAppDoestFail() throws InterruptedException { + Thread memoryLeakThread = new Thread(MEMORY_LEAK); + memoryLeakThread.start(); + memoryLeakThread.join(); + } + + @Test + void givenMemoryLeakCode_whenRunSeveralTimesInsideThread_thenMainAppDoestFail() throws InterruptedException { + for (int i = 0; i < 5; i++) { + Thread memoryLeakThread = new Thread(MEMORY_LEAK); + memoryLeakThread.start(); + memoryLeakThread.join(); + } + } + + @Test + void givenBadExample_whenUseItInProductionCode_thenQuestionedByEmployerAndProbablyFired() + throws InterruptedException { + Thread npeThread = new Thread(() -> { + String nullString = null; + try { + nullString.isEmpty(); + } catch (NullPointerException e) { + throw new OutOfMemoryError(e.getMessage()); + } + }); + npeThread.start(); + npeThread.join(); + } + + private static byte[] tenMegabytes() { + return new byte[1024 * 1014 * 10]; + } +} From 25c40ac1ca61f4e77b4af4e0fe0cfa667b51b275 Mon Sep 17 00:00:00 2001 From: DiegoMarti2 <150871541+DiegoMarti2@users.noreply.github.com> Date: Thu, 25 Jan 2024 20:58:17 +0200 Subject: [PATCH 110/132] baeldung-articles : BAEL-6777 (#15719) * baeldung-articles : BAEL-6777 Normalize a URL in Java (commit) * Update URLNormalizationUnitTest.java --- .../URLNormalizationUnitTest.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 core-java-modules/core-java-networking-4/urlnormalization/URLNormalizationUnitTest.java diff --git a/core-java-modules/core-java-networking-4/urlnormalization/URLNormalizationUnitTest.java b/core-java-modules/core-java-networking-4/urlnormalization/URLNormalizationUnitTest.java new file mode 100644 index 0000000000..13d2abc62c --- /dev/null +++ b/core-java-modules/core-java-networking-4/urlnormalization/URLNormalizationUnitTest.java @@ -0,0 +1,50 @@ +package com.baeldung.urlnormalization; + +import org.junit.jupiter.api.Test; +import org.apache.commons.validator.routines.UrlValidator; + +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class URLNormalizationUnitTest { + String originalUrl = "https://www.example.com:8080/path/to/resource?param1=value1¶m2=value2#fragment"; + String expectedNormalizedUrl = "https://www.example.com:8080/path/to/resource"; + + @Test + public void givenOriginalUrl_whenUsingApacheCommonsValidator_thenValidatedAndMaybeManuallyNormalized() { + UrlValidator urlValidator = new UrlValidator(); + if (urlValidator.isValid(originalUrl)) { + String normalizedUri = originalUrl.split("\\?")[0]; + assertEquals(expectedNormalizedUrl, normalizedUri); + } else { + throw new IllegalArgumentException("Invalid URL: " + originalUrl); + } + } + + @Test + public void givenOriginalUrl_whenUsingJavaURIClass_thenNormalizedUrl() throws URISyntaxException { + URI uri = new URI(originalUrl); + URI normalizedUri = new URI(uri.getScheme(), uri.getAuthority(), uri.getPath(), null, null); + String normalizedUrl = normalizedUri.toString(); + assertEquals(expectedNormalizedUrl, normalizedUrl); + } + + @Test + public void givenOriginalUrl_whenUsingRegularExpression_thenNormalizedUrl() throws URISyntaxException, UnsupportedEncodingException { + String regex = "^(https?://[^/]+/[^?#]+)"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(originalUrl); + + if (matcher.find()) { + String normalizedUrl = matcher.group(1); + assertEquals(expectedNormalizedUrl, normalizedUrl); + } else { + throw new IllegalArgumentException("Invalid URL: " + originalUrl); + } + } +} From dcb4eecaf51e1aa95e3ecf217035aa46925ee17b Mon Sep 17 00:00:00 2001 From: Viren Baraiya Date: Thu, 25 Jan 2024 19:24:18 -0800 Subject: [PATCH 111/132] Event driven microservices tutorial (#15646) * even driven microservices tutorial * restructure the project * remove mvn files * formatting --- .../event-driven-microservice/.gitignore | 27 +++++++ .../event-driven-microservice/README.md | 13 ++++ .../event-driven-microservice/pom.xml | 76 +++++++++++++++++++ .../io/orkes/demo/banking/Application.java | 28 +++++++ .../banking/controller/APIController.java | 41 ++++++++++ .../demo/banking/pojos/DepositDetail.java | 19 +++++ .../banking/service/FraudCheckService.java | 29 +++++++ .../demo/banking/service/WorkflowService.java | 71 +++++++++++++++++ .../banking/workers/ConductorWorkers.java | 34 +++++++++ .../banking/workers/FraudCheckResult.java | 15 ++++ .../src/main/resources/application.properties | 11 +++ .../orkes/demo/banking/ApplicationTests.java | 14 ++++ .../event-driven-microservice/style.xml | 65 ++++++++++++++++ microservices-modules/pom.xml | 1 + 14 files changed, 444 insertions(+) create mode 100644 microservices-modules/event-driven-microservice/.gitignore create mode 100644 microservices-modules/event-driven-microservice/README.md create mode 100644 microservices-modules/event-driven-microservice/pom.xml create mode 100644 microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/Application.java create mode 100644 microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/controller/APIController.java create mode 100644 microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/pojos/DepositDetail.java create mode 100644 microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/service/FraudCheckService.java create mode 100644 microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/service/WorkflowService.java create mode 100644 microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/workers/ConductorWorkers.java create mode 100644 microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/workers/FraudCheckResult.java create mode 100644 microservices-modules/event-driven-microservice/src/main/resources/application.properties create mode 100644 microservices-modules/event-driven-microservice/src/test/java/io/orkes/demo/banking/ApplicationTests.java create mode 100644 microservices-modules/event-driven-microservice/style.xml diff --git a/microservices-modules/event-driven-microservice/.gitignore b/microservices-modules/event-driven-microservice/.gitignore new file mode 100644 index 0000000000..98c0d387a6 --- /dev/null +++ b/microservices-modules/event-driven-microservice/.gitignore @@ -0,0 +1,27 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* + +.idea/ +target/ diff --git a/microservices-modules/event-driven-microservice/README.md b/microservices-modules/event-driven-microservice/README.md new file mode 100644 index 0000000000..657f2ec6b7 --- /dev/null +++ b/microservices-modules/event-driven-microservice/README.md @@ -0,0 +1,13 @@ +# Event Driven Microservices using Conductor + +This is an example project showing how to build event driven applications using [Conductor](https://github.com/conductor-oss/conductor) + +# Pre-requisites +1. Docker +2. Running conductor server + +**Start the conductor server** + +```shell +docker run --init -p 8080:8080 -p 1234:5000 conductoross/conductor-standalone:3.15.0 +``` \ No newline at end of file diff --git a/microservices-modules/event-driven-microservice/pom.xml b/microservices-modules/event-driven-microservice/pom.xml new file mode 100644 index 0000000000..a1ba8d6e35 --- /dev/null +++ b/microservices-modules/event-driven-microservice/pom.xml @@ -0,0 +1,76 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 3.2.0 + + + + io.orkes.demo + event-driven-microservice + 0.1 + + event-driven-microservice + Demo Project for Orkes Conductor on Spring Boot + + + + + + org.springframework.boot + spring-boot-starter-web + + + + io.orkes.conductor + orkes-conductor-client + ${conductor.client.version} + + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + ${spring.webmvc.version} + + + + org.projectlombok + lombok + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + + 17 + 2.0.8 + 2.1.0 + + + diff --git a/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/Application.java b/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/Application.java new file mode 100644 index 0000000000..441f85f23c --- /dev/null +++ b/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/Application.java @@ -0,0 +1,28 @@ +package io.orkes.demo.banking; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.netflix.conductor.common.config.ObjectMapperProvider; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +@SpringBootApplication +@ComponentScan(basePackages = { "io.orkes" }) +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + // ObjectMapper instance used for JSON serialization - can be modified to configure additional modules + @Bean + public ObjectMapper getObjectMapper() { + return new ObjectMapperProvider().getObjectMapper(); + } + +} diff --git a/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/controller/APIController.java b/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/controller/APIController.java new file mode 100644 index 0000000000..6b89bdddae --- /dev/null +++ b/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/controller/APIController.java @@ -0,0 +1,41 @@ +package io.orkes.demo.banking.controller; + +import java.util.Map; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import io.orkes.demo.banking.pojos.DepositDetail; +import io.orkes.demo.banking.service.FraudCheckService; +import io.orkes.demo.banking.service.WorkflowService; +import io.orkes.demo.banking.workers.FraudCheckResult; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@AllArgsConstructor +@RestController +public class APIController { + + private final FraudCheckService fraudCheckService; + + private final WorkflowService workflowService; + + @PostMapping(value = "/triggerDeposit", produces = "application/json") + public ResponseEntity triggerDeposit(@RequestBody DepositDetail depositDetail) { + log.info("Checking for fraud: {}", depositDetail); + return ResponseEntity.ok(fraudCheckService.checkForFraud(depositDetail)); + } + + // docs-marker-start-1 + @PostMapping(value = "/checkForFraud", produces = "application/json") + public Map checkForFraud(@RequestBody DepositDetail depositDetail) throws Exception { + log.info("Checking if fraud check is required for: {}", depositDetail); + return workflowService.executeWorkflow(depositDetail); + } + + // docs-marker-end-1 + +} diff --git a/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/pojos/DepositDetail.java b/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/pojos/DepositDetail.java new file mode 100644 index 0000000000..7c382398eb --- /dev/null +++ b/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/pojos/DepositDetail.java @@ -0,0 +1,19 @@ +package io.orkes.demo.banking.pojos; + +import java.math.BigDecimal; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DepositDetail { + + private String accountId; + private BigDecimal amount; + +} diff --git a/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/service/FraudCheckService.java b/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/service/FraudCheckService.java new file mode 100644 index 0000000000..80bd8b8886 --- /dev/null +++ b/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/service/FraudCheckService.java @@ -0,0 +1,29 @@ +package io.orkes.demo.banking.service; + +import static io.orkes.demo.banking.workers.FraudCheckResult.Result.FAIL; +import static io.orkes.demo.banking.workers.FraudCheckResult.Result.PASS; + +import java.math.BigDecimal; + +import org.springframework.stereotype.Service; + +import io.orkes.demo.banking.pojos.DepositDetail; +import io.orkes.demo.banking.workers.FraudCheckResult; + +@Service +public class FraudCheckService { + + public FraudCheckResult checkForFraud(DepositDetail depositDetail) { + FraudCheckResult fcr = new FraudCheckResult(); + if (depositDetail.getAmount() + .compareTo(BigDecimal.valueOf(100000)) > 0) { + fcr.setResult(FAIL); + fcr.setReason("Amount too large"); + } else { + fcr.setResult(PASS); + fcr.setReason("All good!"); + } + return fcr; + } + +} diff --git a/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/service/WorkflowService.java b/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/service/WorkflowService.java new file mode 100644 index 0000000000..843508d190 --- /dev/null +++ b/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/service/WorkflowService.java @@ -0,0 +1,71 @@ +package io.orkes.demo.banking.service; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.springframework.stereotype.Service; + +import com.netflix.conductor.common.metadata.workflow.StartWorkflowRequest; + +import io.orkes.conductor.client.WorkflowClient; +import io.orkes.conductor.common.model.WorkflowRun; +import io.orkes.demo.banking.pojos.DepositDetail; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@AllArgsConstructor +@Service +public class WorkflowService { + + private final WorkflowClient workflowClient; + + /** + * Starts the workflow execution asynchronously + * @param depositDetail + * @return + */ + public Map startDepositWorkflow(DepositDetail depositDetail) { + StartWorkflowRequest request = new StartWorkflowRequest(); + request.setName("microservice_orchestration"); + Map inputData = new HashMap<>(); + inputData.put("amount", depositDetail.getAmount()); + inputData.put("accountId", depositDetail.getAccountId()); + request.setInput(inputData); + + String workflowId = workflowClient.startWorkflow(request); + log.info("Workflow id: {}", workflowId); + return Map.of("workflowId", workflowId); + } + + /** + * Executes the workflow, waits for it to complete and returns the output of the workflow + * @param depositDetail + * @return + * @throws ExecutionException + * @throws InterruptedException + * @throws TimeoutException + */ + public Map executeWorkflow(DepositDetail depositDetail) throws ExecutionException, InterruptedException, TimeoutException { + StartWorkflowRequest request = new StartWorkflowRequest(); + request.setName("microservice_orchestration"); + request.setVersion(1); + Map inputData = new HashMap<>(); + inputData.put("amount", depositDetail.getAmount()); + inputData.put("accountId", depositDetail.getAccountId()); + request.setInput(inputData); + + CompletableFuture workflowRun = workflowClient.executeWorkflow(request, UUID.randomUUID() + .toString(), 10); + log.info("Workflow id: {}", workflowRun); + + return workflowRun.get(10, TimeUnit.SECONDS) + .getOutput(); + } + +} diff --git a/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/workers/ConductorWorkers.java b/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/workers/ConductorWorkers.java new file mode 100644 index 0000000000..5f5256a3ca --- /dev/null +++ b/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/workers/ConductorWorkers.java @@ -0,0 +1,34 @@ +package io.orkes.demo.banking.workers; + +import java.math.BigDecimal; + +import org.springframework.stereotype.Component; + +import com.netflix.conductor.sdk.workflow.task.InputParam; +import com.netflix.conductor.sdk.workflow.task.WorkerTask; + +import io.orkes.demo.banking.pojos.DepositDetail; +import io.orkes.demo.banking.service.FraudCheckService; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@AllArgsConstructor +@Component +@Slf4j +public class ConductorWorkers { + + private final FraudCheckService fraudCheckService; + + /** + * + * @param amount + * @return Given the amount, the service check if the fraud check should done before executing the transaction + */ + @WorkerTask(value = "fraud-check-required") + public FraudCheckResult simpleWorker(@InputParam("amount") BigDecimal amount) { + DepositDetail dd = new DepositDetail(); + dd.setAmount(amount); + return fraudCheckService.checkForFraud(dd); + } + +} diff --git a/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/workers/FraudCheckResult.java b/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/workers/FraudCheckResult.java new file mode 100644 index 0000000000..b4e667910f --- /dev/null +++ b/microservices-modules/event-driven-microservice/src/main/java/io/orkes/demo/banking/workers/FraudCheckResult.java @@ -0,0 +1,15 @@ +package io.orkes.demo.banking.workers; + +import lombok.Data; + +@Data +public class FraudCheckResult { + + public enum Result { + PASS, + FAIL; + } + + private Result result; + private String reason; +} diff --git a/microservices-modules/event-driven-microservice/src/main/resources/application.properties b/microservices-modules/event-driven-microservice/src/main/resources/application.properties new file mode 100644 index 0000000000..6f31f7f1f2 --- /dev/null +++ b/microservices-modules/event-driven-microservice/src/main/resources/application.properties @@ -0,0 +1,11 @@ +# swagger-ui custom path +springdoc.swagger-ui.path=/swagger-ui.html +management.endpoints.enabled-by-default=false +management.endpoint.info.enabled=false +server.port=8081 +# If you want to use Orkes Playground, then change the server url to https://play.orkes.io/api/ +# Obtain key and secret by logging into +# and navigating to applications menu, create an application and generate key/secret +conductor.security.client.key-id=CHANGE_ME +conductor.security.client.secret=CHANGE_ME +conductor.server.url=https://play.orkes.io/api/ \ No newline at end of file diff --git a/microservices-modules/event-driven-microservice/src/test/java/io/orkes/demo/banking/ApplicationTests.java b/microservices-modules/event-driven-microservice/src/test/java/io/orkes/demo/banking/ApplicationTests.java new file mode 100644 index 0000000000..9e5fe270b1 --- /dev/null +++ b/microservices-modules/event-driven-microservice/src/test/java/io/orkes/demo/banking/ApplicationTests.java @@ -0,0 +1,14 @@ +package io.orkes.demo.banking; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class ApplicationTests { + + @Test + void contextLoads() { + + } + +} diff --git a/microservices-modules/event-driven-microservice/style.xml b/microservices-modules/event-driven-microservice/style.xml new file mode 100644 index 0000000000..e99b59d78e --- /dev/null +++ b/microservices-modules/event-driven-microservice/style.xml @@ -0,0 +1,65 @@ + + diff --git a/microservices-modules/pom.xml b/microservices-modules/pom.xml index a88b6e0fd6..0f0baac488 100644 --- a/microservices-modules/pom.xml +++ b/microservices-modules/pom.xml @@ -22,6 +22,7 @@ msf4j open-liberty rest-express + event-driven-microservice \ No newline at end of file From 899104d579667f246599dd7d582d9c2445e203ff Mon Sep 17 00:00:00 2001 From: Azhwani <13301425+azhwani@users.noreply.github.com> Date: Fri, 26 Jan 2024 18:03:11 +0100 Subject: [PATCH 112/132] BAEL-6357: Convert Long to Date in Java (#15691) Co-authored-by: Luis Javier Peris Morillo --- .../core-java-date-operations-4/README.md | 1 - .../core-java-date-operations-4/pom.xml | 3 +- .../longtodate/LongToDateUnitTest.java | 74 +++++++++++++++++++ 3 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 core-java-modules/core-java-date-operations-4/src/test/java/com/baeldung/longtodate/LongToDateUnitTest.java diff --git a/core-java-modules/core-java-date-operations-4/README.md b/core-java-modules/core-java-date-operations-4/README.md index e023a5ca53..b7817ebd1e 100644 --- a/core-java-modules/core-java-date-operations-4/README.md +++ b/core-java-modules/core-java-date-operations-4/README.md @@ -3,4 +3,3 @@ This module contains articles about date operations in Java. ### Relevant Articles: - diff --git a/core-java-modules/core-java-date-operations-4/pom.xml b/core-java-modules/core-java-date-operations-4/pom.xml index 5153b4b354..317b2cb6e7 100644 --- a/core-java-modules/core-java-date-operations-4/pom.xml +++ b/core-java-modules/core-java-date-operations-4/pom.xml @@ -5,6 +5,7 @@ 4.0.0 core-java-date-operations-4 core-java-date-operations-4 + @@ -39,7 +40,7 @@ - 2.12.5 + 2.12.6 \ No newline at end of file diff --git a/core-java-modules/core-java-date-operations-4/src/test/java/com/baeldung/longtodate/LongToDateUnitTest.java b/core-java-modules/core-java-date-operations-4/src/test/java/com/baeldung/longtodate/LongToDateUnitTest.java new file mode 100644 index 0000000000..589411114c --- /dev/null +++ b/core-java-modules/core-java-date-operations-4/src/test/java/com/baeldung/longtodate/LongToDateUnitTest.java @@ -0,0 +1,74 @@ +package com.baeldung.longtodate; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +import org.joda.time.DateTimeZone; +import org.joda.time.Instant; +import org.junit.jupiter.api.Test; + +class LongToDateUnitTest { + + @Test + void givenLongValue_whenUsingInstantClass_thenConvert() { + Instant expectedDate = Instant.parse("2020-09-08T12:16:40Z"); + long seconds = 1599567400L; + + Instant date = Instant.ofEpochSecond(seconds); + + assertEquals(expectedDate, date); + } + + @Test + void givenLongValue_whenUsingLocalDateClass_thenConvert() { + LocalDate expectedDate = LocalDate.of(2023, 10, 17); + long epochDay = 19647L; + + LocalDate date = LocalDate.ofEpochDay(epochDay); + + assertEquals(expectedDate, date); + } + + @Test + void givenLongValue_whenUsingDateClass_thenConvert() throws ParseException { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + Date expectedDate = dateFormat.parse("2023-07-15 22:00:00"); + long milliseconds = 1689458400000L; + + Date date = new Date(milliseconds); + + assertEquals(expectedDate, date); + } + + @Test + void givenLongValue_whenUsingCalendarClass_thenConvert() throws ParseException { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + Date expectedDate = dateFormat.parse("2023-07-15 22:00:00"); + long milliseconds = 1689458400000L; + + Calendar calendar = Calendar.getInstance(); + calendar.setTimeZone(TimeZone.getTimeZone("UTC")); + calendar.setTimeInMillis(milliseconds); + + assertEquals(expectedDate, calendar.getTime()); + } + + @Test + void givenLongValue_whenUsingJodaTimeLocalDateClass_thenConvert() { + org.joda.time.LocalDate expectedDate = new org.joda.time.LocalDate(2023, 7, 15); + long milliseconds = 1689458400000L; + + org.joda.time.LocalDate date = new org.joda.time.LocalDate(milliseconds, DateTimeZone.UTC); + + assertEquals(expectedDate, date); + } + +} From c72cb4238cb76eee504314958d5178307af84df8 Mon Sep 17 00:00:00 2001 From: Graham Cox Date: Fri, 26 Jan 2024 18:41:08 +0000 Subject: [PATCH 113/132] Calculate Weighted Mean in Java (#15644) Co-authored-by: Grzegorz Piwowarek --- .../WeightedAverageUnitTest.java | 153 ++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/weightedaverage/WeightedAverageUnitTest.java diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/weightedaverage/WeightedAverageUnitTest.java b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/weightedaverage/WeightedAverageUnitTest.java new file mode 100644 index 0000000000..24082d6ac7 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/weightedaverage/WeightedAverageUnitTest.java @@ -0,0 +1,153 @@ +package com.baeldung.algorithms.weightedaverage; + +import org.junit.jupiter.api.Test; + +import java.util.*; +import java.util.function.BiConsumer; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collector; +import java.util.stream.IntStream; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class WeightedAverageUnitTest { + + private List values = Arrays.asList( + new Values(1, 10), + new Values(3, 20), + new Values(5, 30), + new Values(7, 50), + new Values(9, 40) + ); + + private Double expected = 6.2; + + @Test + void twoPass() { + double top = values.stream() + .mapToDouble(v -> v.value * v.weight) + .sum(); + double bottom = values.stream() + .mapToDouble(v -> v.weight) + .sum(); + + double result = top / bottom; + assertEquals(expected, result); + } + + @Test + void onePass() { + double top = 0; + double bottom = 0; + + for (Values v : values) { + top += (v.value * v.weight); + bottom += v.weight; + } + + double result = top / bottom; + assertEquals(expected, result); + } + + @Test + void expanding() { + double result = values.stream() + .flatMap(v -> Collections.nCopies(v.weight, v.value).stream()) + .mapToInt(v -> v) + .average() + .getAsDouble(); + assertEquals(expected, result); + } + + @Test + void reduce() { + class WeightedAverage { + final double top; + final double bottom; + + public WeightedAverage(double top, double bottom) { + this.top = top; + this.bottom = bottom; + } + + double average() { + return top / bottom; + } + } + + double result = values.stream() + .reduce(new WeightedAverage(0, 0), + (acc, next) -> new WeightedAverage( + acc.top + (next.value * next.weight), + acc.bottom + next.weight), + (left, right) -> new WeightedAverage( + left.top + right.top, + left.bottom + right.bottom)) + .average(); + assertEquals(expected, result); + } + + @Test + void customCollector() { + class WeightedAverage implements Collector { + class RunningTotals { + double top; + double bottom; + + public RunningTotals() { + this.top = 0; + this.bottom = 0; + } + } + + @Override + public Supplier supplier() { + return RunningTotals::new; + } + + @Override + public BiConsumer accumulator() { + return (current, next) -> { + current.top += (next.value * next.weight); + current.bottom += next.weight; + }; + } + + @Override + public BinaryOperator combiner() { + return (left, right) -> { + left.top += right.top; + left.bottom += right.bottom; + + return left; + }; + } + + @Override + public Function finisher() { + return rt -> rt.top / rt.bottom; + } + + @Override + public Set characteristics() { + return Collections.singleton(Characteristics.UNORDERED); + } + } + + double result = values.stream() + .collect(new WeightedAverage()); + assertEquals(expected, result); + } + + private static class Values { + int value; + int weight; + + public Values(int value, int weight) { + this.value = value; + this.weight = weight; + } + } +} From d59f1de56a8752bb2fbf798aa68dd705b6ebaf0a Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Sat, 27 Jan 2024 12:21:03 +0530 Subject: [PATCH 114/132] backlink added --- core-java-modules/core-java-io-5/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-io-5/README.md b/core-java-modules/core-java-io-5/README.md index 141d840498..f0dafe2e4b 100644 --- a/core-java-modules/core-java-io-5/README.md +++ b/core-java-modules/core-java-io-5/README.md @@ -7,5 +7,6 @@ This module contains articles about core Java input and output (IO) - [How to Remove Line Breaks From a File in Java](https://www.baeldung.com/java-file-remove-line-breaks) - [Difference Between ZipFile and ZipInputStream in Java](https://www.baeldung.com/java-zipfile-vs-zipinputstream) - [How to Write Strings to OutputStream in Java](https://www.baeldung.com/java-write-string-outputstream) +- [Read a File and Split It Into Multiple Files in Java](https://www.baeldung.com/java-read-file-split-into-several) - [[<-- Prev]](/core-java-modules/core-java-io-4) From 15f6e37175d5fd4c77c17bcde48c7b9c0ffea61a Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Sat, 27 Jan 2024 12:22:21 +0530 Subject: [PATCH 115/132] backlink added --- core-java-modules/core-java-string-operations-7/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-string-operations-7/README.md b/core-java-modules/core-java-string-operations-7/README.md index de45ee0cec..ca99e181f8 100644 --- a/core-java-modules/core-java-string-operations-7/README.md +++ b/core-java-modules/core-java-string-operations-7/README.md @@ -10,4 +10,5 @@ - [Java’s String.length() and String.getBytes().length](https://www.baeldung.com/java-string-length-vs-getbytes-length) - [Replace Non-Printable Unicode Characters in Java](https://www.baeldung.com/java-replace-non-printable-unicode-characters) - [Check If a Java StringBuilder Object Contains a Character](https://www.baeldung.com/java-check-stringbuilder-object-contains-character) +- [Comparing One String With Multiple Values in One Expression in Java](https://www.baeldung.com/java-compare-string-multiple-values-one-expression) - [UTF-8 Validation in Java](https://www.baeldung.com/java-utf-8-validation) From 688c4e7879015b5b591a86b16f5f1bb4f81c7a70 Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Sat, 27 Jan 2024 12:23:35 +0530 Subject: [PATCH 116/132] backlink added --- core-java-modules/core-java-8-datetime-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-8-datetime-2/README.md b/core-java-modules/core-java-8-datetime-2/README.md index 799e5f6a49..8a508404ee 100644 --- a/core-java-modules/core-java-8-datetime-2/README.md +++ b/core-java-modules/core-java-8-datetime-2/README.md @@ -10,4 +10,5 @@ - [Representing Furthest Possible Date in Java](https://www.baeldung.com/java-date-represent-max) - [Retrieving Unix Time in Java](https://www.baeldung.com/java-retrieve-unix-time) - [Calculate Months Between Two Dates in Java](https://www.baeldung.com/java-months-difference-two-dates) +- [Format LocalDate to ISO 8601 With T and Z](https://www.baeldung.com/java-format-localdate-iso-8601-t-z) - [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1) From 9c8f0e52814f46c3b53e4f9cb0538926cfbbff15 Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Sat, 27 Jan 2024 12:24:43 +0530 Subject: [PATCH 117/132] backlink added --- persistence-modules/spring-data-jpa-repo-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/spring-data-jpa-repo-3/README.md b/persistence-modules/spring-data-jpa-repo-3/README.md index 623ac66bb3..03b0e7f76b 100644 --- a/persistence-modules/spring-data-jpa-repo-3/README.md +++ b/persistence-modules/spring-data-jpa-repo-3/README.md @@ -8,4 +8,5 @@ This module contains articles about Spring Data JPA. - [Hibernate Natural IDs in Spring Boot](https://www.baeldung.com/spring-boot-hibernate-natural-ids) - [Correct Use of flush() in JPA](https://www.baeldung.com/spring-jpa-flush) - [Difference Between findBy and findOneBy in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-findby-vs-findoneby) +- [How to Get Last Record in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-last-record) - More articles: [[<-- prev]](../spring-data-jpa-repo-2) From 3ad32f2c5466aca29aa6ad0917a8f256b8926c47 Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Sat, 27 Jan 2024 12:29:51 +0530 Subject: [PATCH 118/132] backlink added --- libraries-data/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries-data/README.md b/libraries-data/README.md index 7e87475328..fa4193867a 100644 --- a/libraries-data/README.md +++ b/libraries-data/README.md @@ -9,4 +9,5 @@ This module contains articles about libraries for data processing in Java. - [A Guide to Apache Crunch](https://www.baeldung.com/apache-crunch) - [Intro to Apache Storm](https://www.baeldung.com/apache-storm) - [Guide to JMapper](https://www.baeldung.com/jmapper) -More articles: [[next -->]](/../libraries-data-2) \ No newline at end of file +- [What Does It Mean to Hydrate an Object?](https://www.baeldung.com/java-object-hydration) +More articles: [[next -->]](/../libraries-data-2) From 34c04afe80e6695abe772d2658d76500780612f6 Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Sat, 27 Jan 2024 12:30:35 +0530 Subject: [PATCH 119/132] updated --- libraries-data/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries-data/README.md b/libraries-data/README.md index fa4193867a..9a8b1fbe4c 100644 --- a/libraries-data/README.md +++ b/libraries-data/README.md @@ -10,4 +10,4 @@ This module contains articles about libraries for data processing in Java. - [Intro to Apache Storm](https://www.baeldung.com/apache-storm) - [Guide to JMapper](https://www.baeldung.com/jmapper) - [What Does It Mean to Hydrate an Object?](https://www.baeldung.com/java-object-hydration) -More articles: [[next -->]](/../libraries-data-2) +- More articles: [[next -->]](/../libraries-data-2) From 3f39eac2d561d2bf33b3c580127123265e3c5162 Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Sat, 27 Jan 2024 12:31:48 +0530 Subject: [PATCH 120/132] backlink added --- core-java-modules/core-java-function/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-function/README.md b/core-java-modules/core-java-function/README.md index eb27aea153..b750ad8a5a 100644 --- a/core-java-modules/core-java-function/README.md +++ b/core-java-modules/core-java-function/README.md @@ -6,3 +6,4 @@ - [Java 8 Predicate Chain](https://www.baeldung.com/java-predicate-chain) - [Use Cases for Static Methods in Java](https://www.baeldung.com/java-static-methods-use-cases) - [TriFunction Interface in Java](https://www.baeldung.com/java-trifunction) +- [Lazy Field Initialization with Lambdas](https://www.baeldung.com/java-lambda-lazy-field-initialization) From eedc5edc0cf52036097d4547df0c6bdccae98308 Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Sat, 27 Jan 2024 12:34:26 +0530 Subject: [PATCH 121/132] backlink added --- core-java-modules/core-java-lang-6/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-lang-6/README.md b/core-java-modules/core-java-lang-6/README.md index 6343f38e91..f50e0b0cd5 100644 --- a/core-java-modules/core-java-lang-6/README.md +++ b/core-java-modules/core-java-lang-6/README.md @@ -13,3 +13,4 @@ This module contains articles about core features in the Java language - [Compress and Uncompress Byte Array Using Deflater/Inflater](https://www.baeldung.com/java-compress-uncompress-byte-array) - [Static Final Variables in Java](https://www.baeldung.com/java-static-final-variables) - [What Is the Error: “Non-static method cannot be referenced from a static context”?](https://www.baeldung.com/java-non-static-method-cannot-be-referenced-from-a-static-context) +- [Recursively Sum the Integers in an Array](https://www.baeldung.com/java-recursive-sum-integer-array) From 574aafd91c0e3fbd3f449b5e9826905bf9a78256 Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Sat, 27 Jan 2024 12:42:09 +0530 Subject: [PATCH 122/132] backlink updated --- core-java-modules/core-java-collections-maps-7/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-collections-maps-7/README.md b/core-java-modules/core-java-collections-maps-7/README.md index 73b36394a3..54668e13e5 100644 --- a/core-java-modules/core-java-collections-maps-7/README.md +++ b/core-java-modules/core-java-collections-maps-7/README.md @@ -5,6 +5,6 @@ - [How to Get First or Last Entry From a LinkedHashMap in Java](https://www.baeldung.com/java-linkedhashmap-first-last-key-value-pair) - [How to Write and Read a File with a Java HashMap](https://www.baeldung.com/java-hashmap-write-read-file) - [Limiting the Max Size of a HashMap in Java](https://www.baeldung.com/java-hashmap-size-bound) -- [How to Sort LinkedHashMap By Values in Java](https://www.baeldung.com/java-sort-linkedhashmap-using-values) +- [How to Sort LinkedHashMap by Values in Java](https://www.baeldung.com/java-sort-linkedhashmap-using-values) - [How to Increment a Map Value in Java](https://www.baeldung.com/java-increment-map-value) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-6) From 4b67c0b3da08242ef834f10344f756882f3193b2 Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Sat, 27 Jan 2024 12:43:58 +0530 Subject: [PATCH 123/132] backlink updated --- core-java-modules/core-java-string-operations-7/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-string-operations-7/README.md b/core-java-modules/core-java-string-operations-7/README.md index ca99e181f8..2c112cf24a 100644 --- a/core-java-modules/core-java-string-operations-7/README.md +++ b/core-java-modules/core-java-string-operations-7/README.md @@ -3,7 +3,7 @@ - [How to Center Text Output in Java](https://www.baeldung.com/java-center-text-output) - [Capitalize the First Letter of Each Word in a String](https://www.baeldung.com/java-string-initial-capital-letter-every-word) - [Check if a String Contains Only Unicode Letters](https://www.baeldung.com/java-string-all-unicode-characters) -- [Create a Mutable String in Java](https://www.baeldung.com/java-mutable-string) +- [Create a “Mutable” String in Java](https://www.baeldung.com/java-mutable-string) - [Check if a String Contains a Number Value in Java](https://www.baeldung.com/java-string-number-presence) - [Difference Between String isEmpty() and isBlank()](https://www.baeldung.com/java-string-isempty-vs-isblank) - [String’s Maximum Length in Java](https://www.baeldung.com/java-strings-maximum-length) From 62c6faf840fe1c44278f31f39f3798d12316619b Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Sat, 27 Jan 2024 13:12:51 +0530 Subject: [PATCH 124/132] backlink updated --- core-java-modules/core-java-numbers-conversions/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-numbers-conversions/README.md b/core-java-modules/core-java-numbers-conversions/README.md index e2031f0ee1..9f2a1d07b8 100644 --- a/core-java-modules/core-java-numbers-conversions/README.md +++ b/core-java-modules/core-java-numbers-conversions/README.md @@ -2,7 +2,7 @@ - [Convert a Number to a Letter in Java](https://www.baeldung.com/java-convert-number-to-letter) - [Convert Long to BigDecimal in Java](https://www.baeldung.com/java-convert-long-bigdecimal) - [Convert int to Long in Java](https://www.baeldung.com/java-convert-int-long) -- [How To Convert Double To Float In Java](https://www.baeldung.com/java-convert-double-float) +- [How to Convert Double to Float in Java](https://www.baeldung.com/java-convert-double-float) - [Converting from float to BigDecimal in Java](https://www.baeldung.com/java-convert-float-bigdecimal) - [Convert Positive Integer to Negative and Vice Versa in Java](https://www.baeldung.com/java-negating-integer) - [Rounding Up a Number to Nearest Multiple of 5 in Java](https://www.baeldung.com/java-round-nearest-multiple-five) From be415032aacbc05db40672a3b70f486d8d540b26 Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Sat, 27 Jan 2024 13:15:10 +0530 Subject: [PATCH 125/132] backlink updated --- core-java-modules/core-java-regex-2/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-regex-2/README.md b/core-java-modules/core-java-regex-2/README.md index 404b33b65f..5f08a521c1 100644 --- a/core-java-modules/core-java-regex-2/README.md +++ b/core-java-modules/core-java-regex-2/README.md @@ -9,5 +9,5 @@ - [Regular Expression: \z vs \Z Anchors in Java](https://www.baeldung.com/java-regular-expression-z-vs-z-anchors) - [Extract Text Between Square Brackets](https://www.baeldung.com/java-get-content-between-square-brackets) - [Get the Indexes of Regex Pattern Matches in Java](https://www.baeldung.com/java-indexes-regex-pattern-matches) -- [Check if a String is Strictly Alphanumeric With Java](https://www.baeldung.com/java-check-string-contains-only-letters-numbers) +- [Check if a String Is Strictly Alphanumeric With Java](https://www.baeldung.com/java-check-string-contains-only-letters-numbers) - More articles: [[<-- prev]](/core-java-modules/core-java-regex) From c99962d10af99ddabfa389d3cf523b9b453a8adf Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Sat, 27 Jan 2024 13:16:38 +0530 Subject: [PATCH 126/132] backlink updated --- persistence-modules/spring-jdbc/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence-modules/spring-jdbc/README.md b/persistence-modules/spring-jdbc/README.md index 19f8537a4e..de2153088f 100644 --- a/persistence-modules/spring-jdbc/README.md +++ b/persistence-modules/spring-jdbc/README.md @@ -7,4 +7,4 @@ - [Obtaining Auto-generated Keys in Spring JDBC](https://www.baeldung.com/spring-jdbc-autogenerated-keys) - [Spring JDBC Batch Inserts](https://www.baeldung.com/spring-jdbc-batch-inserts) - [Fix EmptyResultDataAccessException When Using JdbcTemplate](https://www.baeldung.com/jdbctemplate-fix-emptyresultdataaccessexception) -- [How to replace deprecated jdbcTemplate.queryForObject and jdbcTemplate.query in spring boot 2.4.X and above](https://www.baeldung.com/spring-boot-replace-deprecated-jdbctemplate-queryforobject-query) +- [How to Replace Deprecated jdbcTemplate.queryForObject and jdbcTemplate.query in Spring Boot 2.4.X and above](https://www.baeldung.com/spring-boot-replace-deprecated-jdbctemplate-queryforobject-query) From 06768c61cb343d410b704616aaa4eafb0430bad5 Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Sat, 27 Jan 2024 13:18:19 +0530 Subject: [PATCH 127/132] backlink updated --- core-java-modules/core-java-io-apis/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core-java-modules/core-java-io-apis/README.md b/core-java-modules/core-java-io-apis/README.md index b00b0a6022..faf7067f74 100644 --- a/core-java-modules/core-java-io-apis/README.md +++ b/core-java-modules/core-java-io-apis/README.md @@ -11,5 +11,5 @@ This module contains articles about core Java input/output(IO) APIs. - [Quick Use of FilenameFilter](https://www.baeldung.com/java-filename-filter) - [Guide to BufferedReader](https://www.baeldung.com/java-buffered-reader) - [Difference Between FileReader and BufferedReader in Java](https://www.baeldung.com/java-filereader-vs-bufferedreader) -- [Java: Read Multiple Inputs on Same Line](https://www.baeldung.com/java-read-multiple-inputs-same-line) -- [Write Console Output to Text File in Java](https://www.baeldung.com/java-write-console-output-file) \ No newline at end of file +- [Read Multiple Inputs on the Same Line in Java](https://www.baeldung.com/java-read-multiple-inputs-same-line) +- [Write Console Output to Text File in Java](https://www.baeldung.com/java-write-console-output-file) From 8a18afd05aa9c81d7d7832516177bef2153c0774 Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Sat, 27 Jan 2024 13:19:28 +0530 Subject: [PATCH 128/132] backlink updated --- spring-boot-modules/spring-boot-3-observation/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-modules/spring-boot-3-observation/README.md b/spring-boot-modules/spring-boot-3-observation/README.md index 6d8c02af67..ae812d5f56 100644 --- a/spring-boot-modules/spring-boot-3-observation/README.md +++ b/spring-boot-modules/spring-boot-3-observation/README.md @@ -1,3 +1,3 @@ ## Relevant Articles -- [Observability with Spring Boot 3](https://www.baeldung.com/spring-boot-3-observability) +- [Observability With Spring Boot 3](https://www.baeldung.com/spring-boot-3-observability) - [Intercept SQL Logging with P6Spy](https://www.baeldung.com/java-p6spy-intercept-sql-logging) From 1e57e8c90c394e02a884c044109bb2a231727c17 Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Sat, 27 Jan 2024 13:20:41 +0530 Subject: [PATCH 129/132] backlink updated --- core-java-modules/core-java-io-4/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-io-4/README.md b/core-java-modules/core-java-io-4/README.md index 7856fbaf41..4b2bba6a50 100644 --- a/core-java-modules/core-java-io-4/README.md +++ b/core-java-modules/core-java-io-4/README.md @@ -9,7 +9,7 @@ This module contains articles about core Java input and output (IO) - [SequenceInputStream Class in Java](https://www.baeldung.com/java-sequenceinputstream) - [Read a File Into a Map in Java](https://www.baeldung.com/java-read-file-into-map) - [Read User Input Until a Condition Is Met](https://www.baeldung.com/java-read-input-until-condition) -- [Java Scanner.skip method with examples](https://www.baeldung.com/java-scanner-skip) +- [Java Scanner.skip Method with Examples](https://www.baeldung.com/java-scanner-skip) - [Generate the MD5 Checksum for a File in Java](https://www.baeldung.com/java-md5-checksum-file) - [Getting the Filename From a String Containing an Absolute File Path](https://www.baeldung.com/java-filename-full-path) - [Mocking Java InputStream Object](https://www.baeldung.com/java-mocking-inputstream) From 1a5434e7ed26fc5c31e55150bd708ebaf49d055b Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Sat, 27 Jan 2024 13:22:01 +0530 Subject: [PATCH 130/132] backlink updated --- spring-reactive-modules/spring-reactive-2/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-reactive-modules/spring-reactive-2/README.md b/spring-reactive-modules/spring-reactive-2/README.md index dbaebc370e..c635d4c9b5 100644 --- a/spring-reactive-modules/spring-reactive-2/README.md +++ b/spring-reactive-modules/spring-reactive-2/README.md @@ -2,7 +2,7 @@ This module contains articles about reactive Spring Boot. -- [Validation for Functional Endpoints in Spring 5](https://www.baeldung.com/spring-functional-endpoints-validation) +- [Validation for Functional Endpoints in Spring 6](https://www.baeldung.com/spring-functional-endpoints-validation) - [Testing Reactive Streams Using StepVerifier and TestPublisher](https://www.baeldung.com/reactive-streams-step-verifier-test-publisher) - [Static Content in Spring WebFlux](https://www.baeldung.com/spring-webflux-static-content) - [Server-Sent Events in Spring](https://www.baeldung.com/spring-server-sent-events) From 7e5a3cc9e023bdd40ae68414a0698a309a3b4a0b Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Sat, 27 Jan 2024 13:23:42 +0530 Subject: [PATCH 131/132] backlink updated --- spring-web-modules/spring-rest-http/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-web-modules/spring-rest-http/README.md b/spring-web-modules/spring-rest-http/README.md index 4c160ee513..04aed3d076 100644 --- a/spring-web-modules/spring-rest-http/README.md +++ b/spring-web-modules/spring-rest-http/README.md @@ -7,7 +7,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: -- [How to Set a Header on a Response with Spring 5](https://www.baeldung.com/spring-response-header) +- [How to Set a Header on a Response with Spring 6](https://www.baeldung.com/spring-response-header) - [Returning Custom Status Codes from Spring Controllers](https://www.baeldung.com/spring-mvc-controller-custom-http-status-code) - [Spring RequestMapping](https://www.baeldung.com/spring-requestmapping) - [Guide to DeferredResult in Spring](https://www.baeldung.com/spring-deferred-result) From 002384b66831ee46cfe2c7b7c8f6fc67dd6b0600 Mon Sep 17 00:00:00 2001 From: Manfred <77407079+manfred106@users.noreply.github.com> Date: Sun, 28 Jan 2024 01:14:00 +0000 Subject: [PATCH 132/132] BAEL-6753: Storing PostgreSQL jsonb Using SpringBoot and JPA (#15632) * BAEL-6753: Storing PostgreSQL jsonb Using SpringBoot and JPA * BAEL-6753: Storing PostgreSQL jsonb Using SpringBoot and JPA --- .../spring-data-jpa-repo-4/pom.xml | 34 +++++++++ .../spring/data/persistence/json/Address.java | 15 ++++ .../json/AddressAttributeConverter.java | 36 +++++++++ .../json/JsonAttributeApplication.java | 13 ++++ .../data/persistence/json/StudentEntity.java | 31 ++++++++ .../persistence/json/StudentRepository.java | 16 ++++ .../persistence/json/StudentStrEntity.java | 27 +++++++ .../json/StudentStrRepository.java | 16 ++++ .../json/JsonAttributeLiveTest.java | 76 +++++++++++++++++++ 9 files changed, 264 insertions(+) create mode 100644 persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/Address.java create mode 100644 persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/AddressAttributeConverter.java create mode 100644 persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/JsonAttributeApplication.java create mode 100644 persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/StudentEntity.java create mode 100644 persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/StudentRepository.java create mode 100644 persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/StudentStrEntity.java create mode 100644 persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/StudentStrRepository.java create mode 100644 persistence-modules/spring-data-jpa-repo-4/src/test/java/com/baeldung/spring/data/persistence/json/JsonAttributeLiveTest.java diff --git a/persistence-modules/spring-data-jpa-repo-4/pom.xml b/persistence-modules/spring-data-jpa-repo-4/pom.xml index c823391d9f..9b03f7fdfb 100644 --- a/persistence-modules/spring-data-jpa-repo-4/pom.xml +++ b/persistence-modules/spring-data-jpa-repo-4/pom.xml @@ -30,6 +30,11 @@ org.springframework.boot spring-boot-starter-data-jpa + + io.hypersistence + hypersistence-utils-hibernate-55 + ${hypersistance-utils-hibernate-55.version} + com.h2database h2 @@ -47,6 +52,30 @@ guava ${guava.version} + + org.projectlombok + lombok + + + org.postgresql + postgresql + ${postgresql.version} + + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + ch.qos.logback + logback-core + ${logback.version} + + + ch.qos.logback + logback-classic + ${logback.version} + @@ -98,4 +127,9 @@ + + 3.7.0 + 42.7.1 + + \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/Address.java b/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/Address.java new file mode 100644 index 0000000000..976a232082 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/Address.java @@ -0,0 +1,15 @@ +package com.baeldung.spring.data.persistence.json; + +import lombok.*; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode +public class Address { + + private String postCode; + + private String city; + +} diff --git a/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/AddressAttributeConverter.java b/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/AddressAttributeConverter.java new file mode 100644 index 0000000000..736f5e8ec2 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/AddressAttributeConverter.java @@ -0,0 +1,36 @@ +package com.baeldung.spring.data.persistence.json; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; + +import javax.persistence.AttributeConverter; +import javax.persistence.Converter; + +@Converter +@Slf4j +public class AddressAttributeConverter implements AttributeConverter { + + private static final ObjectMapper objectMapper = new ObjectMapper(); + + @Override + public String convertToDatabaseColumn(Address address) { + try { + return objectMapper.writeValueAsString(address); + } catch (JsonProcessingException jpe) { + log.warn("Cannot convert Address into JSON"); + return null; + } + } + + @Override + public Address convertToEntityAttribute(String value) { + try { + return objectMapper.readValue(value, Address.class); + } catch (JsonProcessingException e) { + log.warn("Cannot convert JSON into Address"); + return null; + } + } + +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/JsonAttributeApplication.java b/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/JsonAttributeApplication.java new file mode 100644 index 0000000000..708b43a534 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/JsonAttributeApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.spring.data.persistence.json; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class JsonAttributeApplication { + + public static void main(String[] args) { + SpringApplication.run(JsonAttributeApplication.class, args); + } + +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/StudentEntity.java b/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/StudentEntity.java new file mode 100644 index 0000000000..c5fd31ddd3 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/StudentEntity.java @@ -0,0 +1,31 @@ +package com.baeldung.spring.data.persistence.json; + +import javax.persistence.*; + +import io.hypersistence.utils.hibernate.type.json.JsonBinaryType; +import lombok.*; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; + +@Entity +@Table(name = "student") +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(of = {"id"}) +@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class) +public class StudentEntity { + + @Id + @Column(name = "student_id", length = 8) + private String id; + + @Column(name = "admit_year", length = 4) + private String admitYear; + + @Type(type = "jsonb") + @Column(name = "address", columnDefinition = "jsonb") + private Address address; + +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/StudentRepository.java b/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/StudentRepository.java new file mode 100644 index 0000000000..bae8ab6ad9 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/StudentRepository.java @@ -0,0 +1,16 @@ +package com.baeldung.spring.data.persistence.json; + +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface StudentRepository extends CrudRepository { + + @Query(value = "SELECT * FROM student WHERE address->>'postCode' = :postCode", nativeQuery = true) + List findByAddressPostCode(@Param("postCode") String postCode); + +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/StudentStrEntity.java b/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/StudentStrEntity.java new file mode 100644 index 0000000000..552cdeaed6 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/StudentStrEntity.java @@ -0,0 +1,27 @@ +package com.baeldung.spring.data.persistence.json; + +import javax.persistence.*; + +import lombok.*; + +@Entity +@Table(name = "student_str") +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(of = {"id"}) +public class StudentStrEntity { + + @Id + @Column(name = "student_id", length = 8) + private String id; + + @Column(name = "admit_year", length = 4) + private String admitYear; + + @Convert(converter = AddressAttributeConverter.class) + @Column(name = "address", length = 500) + private Address address; + +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/StudentStrRepository.java b/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/StudentStrRepository.java new file mode 100644 index 0000000000..ce40166b22 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-4/src/main/java/com/baeldung/spring/data/persistence/json/StudentStrRepository.java @@ -0,0 +1,16 @@ +package com.baeldung.spring.data.persistence.json; + +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface StudentStrRepository extends CrudRepository { + + @Query(value = "SELECT * FROM student WHERE address->>'postCode' = :postCode", nativeQuery = true) + List findByAddressPostCode(@Param("postCode") String postCode); + +} diff --git a/persistence-modules/spring-data-jpa-repo-4/src/test/java/com/baeldung/spring/data/persistence/json/JsonAttributeLiveTest.java b/persistence-modules/spring-data-jpa-repo-4/src/test/java/com/baeldung/spring/data/persistence/json/JsonAttributeLiveTest.java new file mode 100644 index 0000000000..1242b3f2f4 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-4/src/test/java/com/baeldung/spring/data/persistence/json/JsonAttributeLiveTest.java @@ -0,0 +1,76 @@ +package com.baeldung.spring.data.persistence.json; + +import org.junit.jupiter.api.*; +import org.springframework.boot.test.context.SpringBootTest; + +import javax.inject.Inject; +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = JsonAttributeApplication.class) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +class JsonAttributeLiveTest { + + @Inject + private StudentStrRepository studentStrRepository; + + @Inject + private StudentRepository studentRepository; + + @Test + @Order(10) + void whenSaveAnStudentStrEntityAndFindById_thenTheRecordPresentsInDb() { + String studentId = "23876371"; + String postCode = "KT6 7BB"; + + Address address = new Address(postCode, "London"); + StudentStrEntity studentStrEntity = StudentStrEntity.builder() + .id(studentId) + .admitYear("2023") + .address(address) + .build(); + + StudentStrEntity savedStudentStrEntity = studentStrRepository.save(studentStrEntity); + + Optional studentEntityOptional = studentStrRepository.findById(studentId); + assertThat(studentEntityOptional.isPresent()).isTrue(); + + studentStrEntity = studentEntityOptional.get(); + assertThat(studentStrEntity.getId()).isEqualTo(studentId); + assertThat(studentStrEntity.getAddress().getPostCode()).isEqualTo(postCode); + } + + @Test + @Order(20) + void whenSaveAnStudentEntityAndFindById_thenTheRecordPresentsInDb() { + String studentId = "23876371"; + String postCode = "KT6 7BB"; + + Address address = new Address(postCode, "London"); + StudentEntity studentEntity = StudentEntity.builder() + .id(studentId) + .admitYear("2023") + .address(address) + .build(); + + StudentEntity savedStudentEntity = studentRepository.save(studentEntity); + + Optional studentEntityOptional = studentRepository.findById(studentId); + assertThat(studentEntityOptional.isPresent()).isTrue(); + + studentEntity = studentEntityOptional.get(); + assertThat(studentEntity.getId()).isEqualTo(studentId); + assertThat(studentEntity.getAddress().getPostCode()).isEqualTo(postCode); + } + + @Test + @Order(50) + void whenFindByAddressPostCode_thenReturnListIsNotEmpty() { + String postCode = "KT6 7BB"; + List studentStrEntityList = studentStrRepository.findByAddressPostCode(postCode); + assertThat(studentStrEntityList).isNotEmpty(); + } + +} \ No newline at end of file