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) 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; + } + } +} 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) 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) 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)); + } +} diff --git a/core-java-modules/core-java-arrays-convert/src/test/java/com/baeldung/array/conversions/ByteArrayToPrimitiveByteArrayUnitTest.java b/core-java-modules/core-java-arrays-convert/src/test/java/com/baeldung/array/conversions/ByteArrayToPrimitiveByteArrayUnitTest.java new file mode 100644 index 0000000000..758fe74685 --- /dev/null +++ b/core-java-modules/core-java-arrays-convert/src/test/java/com/baeldung/array/conversions/ByteArrayToPrimitiveByteArrayUnitTest.java @@ -0,0 +1,36 @@ +package com.baeldung.array.conversions; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.apache.commons.lang3.ArrayUtils; +import org.junit.jupiter.api.Test; + +public class ByteArrayToPrimitiveByteArrayUnitTest { + private static final byte[] EXPECTED_ARRAY_VALUES = {65, 66, 67, 68}; + private static final Byte[] BYTE_ARRAY = {65, 66, 67, 68}; + + @Test + public void givenByteArray_whenConvertingUsingByteValue_thenGiveExpectedResult() { + byte[] newByteArray = new byte[BYTE_ARRAY.length]; + for (int i = 0; i < BYTE_ARRAY.length; i++) { + newByteArray[i] = BYTE_ARRAY[i].byteValue(); + } + assertThat(newByteArray).containsExactly(EXPECTED_ARRAY_VALUES); + } + + @Test + public void givenByteArray_whenConvertingUsingUnboxing_thenGiveExpectedResult() { + byte[] newByteArray = new byte[BYTE_ARRAY.length]; + for (int i = 0; i < BYTE_ARRAY.length; i++) { + newByteArray[i] = BYTE_ARRAY[i]; + } + assertThat(newByteArray).containsExactly(EXPECTED_ARRAY_VALUES); + } + + @Test + public void givenByteArray_whenConvertingArrayUtils_thenGiveExpectedResult() { + byte[] newByteArray = ArrayUtils.toPrimitive(BYTE_ARRAY); + + assertThat(newByteArray).containsExactly(EXPECTED_ARRAY_VALUES); + } +} diff --git a/core-java-modules/core-java-arrays-convert/src/test/java/com/baeldung/array/conversions/PrimitiveByteArrayToByteArrayUnitTest.java b/core-java-modules/core-java-arrays-convert/src/test/java/com/baeldung/array/conversions/PrimitiveByteArrayToByteArrayUnitTest.java new file mode 100644 index 0000000000..8c0bd4401c --- /dev/null +++ b/core-java-modules/core-java-arrays-convert/src/test/java/com/baeldung/array/conversions/PrimitiveByteArrayToByteArrayUnitTest.java @@ -0,0 +1,47 @@ +package com.baeldung.array.conversions; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; + +import org.apache.commons.lang3.ArrayUtils; +import org.junit.jupiter.api.Test; + +public class PrimitiveByteArrayToByteArrayUnitTest { + private static final byte[] PRIMITIVE_BYTE_ARRAY = {65, 66, 67, 68}; + private static final Byte[] EXPECTED_ARRAY_VALUES = {65, 66, 67, 68}; + + @Test + public void givenPrimitiveByteArray_whenConvertingUsingByteValueOf_thenGiveExpectedResult() { + Byte[] newByteArray = new Byte[PRIMITIVE_BYTE_ARRAY.length]; + for (int i = 0; i < PRIMITIVE_BYTE_ARRAY.length; i++) { + newByteArray[i] = Byte.valueOf(PRIMITIVE_BYTE_ARRAY[i]); + } + assertThat(newByteArray).containsExactly(EXPECTED_ARRAY_VALUES); + } + + @Test + public void givenPrimitiveByteArray_whenConvertingUsingAutoboxing_thenGiveExpectedResult() { + Byte[] newByteArray = new Byte[PRIMITIVE_BYTE_ARRAY.length]; + for (int i = 0; i < PRIMITIVE_BYTE_ARRAY.length; i++) { + newByteArray[i] = PRIMITIVE_BYTE_ARRAY[i]; + } + assertThat(newByteArray).containsExactly(EXPECTED_ARRAY_VALUES); + } + + @Test + public void givenPrimitiveByteArray_whenConvertingUsingAutoboxingAndArraysSetAll_thenGiveExpectedResult() { + Byte[] newByteArray = new Byte[PRIMITIVE_BYTE_ARRAY.length]; + Arrays.setAll(newByteArray, n -> PRIMITIVE_BYTE_ARRAY[n]); + + assertThat(newByteArray) + .containsExactly(EXPECTED_ARRAY_VALUES); + } + + @Test + public void givenPrimitiveByteArray_whenConvertingUsingArrayUtils_thenGiveExpectedResult() { + Byte[] newByteArray = ArrayUtils.toObject(PRIMITIVE_BYTE_ARRAY); + + assertThat(newByteArray).containsExactly(EXPECTED_ARRAY_VALUES); + } +} 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 diff --git a/core-java-modules/core-java-collections-5/README.md b/core-java-modules/core-java-collections-5/README.md index c9fce58ac2..cf731e8f09 100644 --- a/core-java-modules/core-java-collections-5/README.md +++ b/core-java-modules/core-java-collections-5/README.md @@ -11,4 +11,6 @@ - [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) +- [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) 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..30ae5eb2dd 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,5 @@ ## 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) +- [Sorting One List Based on Another List in Java](https://www.baeldung.com/java-sorting-one-list-using-another) 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) 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) 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..b7817ebd1e --- /dev/null +++ b/core-java-modules/core-java-date-operations-4/README.md @@ -0,0 +1,5 @@ +## 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..317b2cb6e7 --- /dev/null +++ b/core-java-modules/core-java-date-operations-4/pom.xml @@ -0,0 +1,46 @@ + + + 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.6 + + + \ 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..05a2202682 --- /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.jupiter.api.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 + void givenTwoDaysOnSameWeekend_whenUsingStreams_thenCalculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithStream(startTomorrow, endTomorrow); + assertEquals(0, result); + } + + @Test + void givenTwoDaysOnSameWeekend_whenUsingMaths_thenCalculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithoutStream(startTomorrow, endTomorrow); + assertEquals(0, result); + } + + @Test + void givenAThreeWeekGapMidweekDates_whenUsingStreams_thenCalculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithStream(startThreeWeeks, endThreeWeeks); + assertEquals(17, result); + } + + @Test + void givenAThreeWeekGapMidweekDates_whenUsingMaths_thenCalculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithoutStream(startThreeWeeks, endThreeWeeks); + assertEquals(17, result); + } + + @Test + void givenThreeWeekGapMidweekAndWeekendDates_whenUsingStreams_thenCalculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithStream(startThreeWeeksWeekend, endThreeWeeksWeekend); + assertEquals(5, result); + } + + @Test + void givenThreeWeekGapMidweekAndWeekendDates_whenUsingMaths_thenCalculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithoutStream(startThreeWeeksWeekend, endThreeWeeksWeekend); + assertEquals(5, result); + } + + @Test + void givenThreeWeekGapWeekendDates_whenUsingStreams_thenCalculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithStream(startThreeWeeks2, endThreeWeeks2); + assertEquals(40, result); + } + + @Test + void givenThreeWeekGapWeekendDates_whenUsingMaths_thenCalculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithoutStream(startThreeWeeks2, endThreeWeeks2); + assertEquals(40, result); + } + +} 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); + } + +} 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/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) 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/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) 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..29666826a8 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,5 @@ 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) +- [Difference Between flush() and close() in Java FileWriter](https://www.baeldung.com/java-filewriter-flush-vs-close) 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/README.md b/core-java-modules/core-java-lang-6/README.md index 214409dd04..6343f38e91 100644 --- a/core-java-modules/core-java-lang-6/README.md +++ b/core-java-modules/core-java-lang-6/README.md @@ -10,4 +10,6 @@ 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) +- [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) 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..7cd44430fa --- /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 ENV_VARIABLE_VALUE = "Hello World"; + + @ParameterizedTest + @CsvSource({ENV_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_whenGetEnv_thenVariablesArePresent() { + Map environment = System.getenv(); + assertThat(environment).isNotNull(); + } + + @Test + @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(ENV_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); + } +} 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) 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) 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); + } + } +} 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) 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) 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]; + } +} 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..cbd1f1da58 --- /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_LENGTH = "8"; + String MAX_LENGTH = "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_LENGTH + "," + MAX_LENGTH + "}"; + 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/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) 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) 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) 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..de45ee0cec 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,7 @@ - [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) +- [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) 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); } } 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) 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/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) diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index f4722855bc..568fc37811 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 @@ -199,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 @@ -209,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 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/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) 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 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 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) 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..0e7b9717f8 --- /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()); + } + +} 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 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) 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/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/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..3165441ae4 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Group.java @@ -0,0 +1,71 @@ +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.Objects; +import java.util.Set; + +@Entity(name = "interest_group") +@Table(name = "interest_group") +public class Group { + + @Id + private Long id; + + private String name; + + @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/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..f1a8aadc15 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/Post.java @@ -0,0 +1,72 @@ +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; + +@Entity +public class Post { + + @Id + private Long id; + + @Lob + private String content; + + @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/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..fdba1e7efc --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/eager/set/lazy/moderatedomain/User.java @@ -0,0 +1,83 @@ +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; + +@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; + + 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/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/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/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..3a20ccf8fb --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Group.java @@ -0,0 +1,71 @@ +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 java.util.Objects; + +@Entity(name = "interest_group") +@Table(name = "interest_group") +public class Group { + + @Id + private Long id; + + private String name; + + @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/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..4bd746fef3 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/GroupService.java @@ -0,0 +1,36 @@ +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..3d7eb1b6d9 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/Post.java @@ -0,0 +1,72 @@ +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 java.util.Objects; + +@Entity +public class Post { + + @Id + private Long id; + + @Lob + private String content; + + @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/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..c3b238d626 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/listvsset/lazy/list/moderatedomain/User.java @@ -0,0 +1,83 @@ +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; + +@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; + + public User() { + } + + @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 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/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..271b6578e1 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/Post.java @@ -0,0 +1,65 @@ +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 java.util.Objects; + +@Entity +public class Post { + + @Id + private Long id; + + @Lob + private String content; + + @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/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..e5c5090d38 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/nplusone/defaultfetch/list/User.java @@ -0,0 +1,75 @@ +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 java.util.Objects; + +@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") + 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/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/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 new file mode 100644 index 0000000000..f4a35a8e38 --- /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() { + getUserService().findAll(); + assertSelectCount(1); + } + + @ParameterizedTest + @ValueSource(longs = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) + void givenLazyListBasedUser_whenFetchingOneUser_thenIssueOneRequest(Long id) { + getUserService().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..583b67ff0c --- /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() { + getUserService().findAll(); + assertSelectCount(1); + } + + @Test + void givenLazyListBasedUser_WhenFetchingAllUsersCheckingPosts_ThenIssueNPlusOneRequests() { + int numberOfRequests = getUserService().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) { + getUserService().getUserByIdWithPredicate(id, user -> !user.getPosts().isEmpty()); + assertSelectCount(2); + } + + + 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/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); }); } diff --git a/persistence-modules/spring-data-jpa-query-3/README.md b/persistence-modules/spring-data-jpa-query-3/README.md index 8b094e66b2..99032138a6 100644 --- a/persistence-modules/spring-data-jpa-query-3/README.md +++ b/persistence-modules/spring-data-jpa-query-3/README.md @@ -8,7 +8,9 @@ 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) +- [@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 diff --git a/persistence-modules/spring-data-jpa-repo-4/README.md b/persistence-modules/spring-data-jpa-repo-4/README.md index a8afbbe733..f0cfdedab0 100644 --- a/persistence-modules/spring-data-jpa-repo-4/README.md +++ b/persistence-modules/spring-data-jpa-repo-4/README.md @@ -4,4 +4,6 @@ - [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) 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 diff --git a/pom.xml b/pom.xml index e0e9629b98..a73d508d89 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 @@ -1215,7 +1215,7 @@ 3.21.0 1.18.30 2.1.214 - 32.1.3-jre + 33.0.0-jre 3.3.0 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(); 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) 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"); } 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 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) 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(); } 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; 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) 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 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 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 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()); 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=/"}) 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) 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); } 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) 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)