diff --git a/algorithms-modules/algorithms-miscellaneous-7/README.md b/algorithms-modules/algorithms-miscellaneous-7/README.md
index a08948eda5..266d79cdfa 100644
--- a/algorithms-modules/algorithms-miscellaneous-7/README.md
+++ b/algorithms-modules/algorithms-miscellaneous-7/README.md
@@ -10,8 +10,4 @@
- [Check if Two Strings Are Rotations of Each Other](https://www.baeldung.com/java-string-check-strings-rotations)
- [Find the Largest Prime Under the Given Number in Java](https://www.baeldung.com/java-largest-prime-lower-threshold)
- [Count the Number of Unique Digits in an Integer using Java](https://www.baeldung.com/java-int-count-unique-digits)
-- [Generate Juggler Sequence in Java](https://www.baeldung.com/java-generate-juggler-sequence)
-- [Finding the Parent of a Node in a Binary Search Tree with Java](https://www.baeldung.com/java-find-parent-node-binary-search-tree)
-- [Check if a Number Is a Happy Number in Java](https://www.baeldung.com/java-happy-sad-number-test)
-- [Find the Largest Number Possible After Removing k Digits of a Number](https://www.baeldung.com/java-find-largest-number-remove-k-digits)
- More articles: [[<-- prev]](/algorithms-miscellaneous-6)
diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/README.md b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/README.md
deleted file mode 100644
index 55bc2abec5..0000000000
--- a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-## Relevant Articles
-- [Implement Connect 4 Game with Java](https://www.baeldung.com/java-connect-4-game)
diff --git a/algorithms-modules/algorithms-miscellaneous-8/README.md b/algorithms-modules/algorithms-miscellaneous-8/README.md
index e2c5047136..8bd185a7ba 100644
--- a/algorithms-modules/algorithms-miscellaneous-8/README.md
+++ b/algorithms-modules/algorithms-miscellaneous-8/README.md
@@ -1,3 +1,9 @@
### Relevant Articles:
- [Vigenère Cipher in Java](https://www.baeldung.com/java-vigenere-cipher)
- [Merge Overlapping Intervals in a Java Collection](https://www.baeldung.com/java-collection-merge-overlapping-intervals)
+- [Generate Juggler Sequence in Java](https://www.baeldung.com/java-generate-juggler-sequence)
+- [Finding the Parent of a Node in a Binary Search Tree with Java](https://www.baeldung.com/java-find-parent-node-binary-search-tree)
+- [Check if a Number Is a Happy Number in Java](https://www.baeldung.com/java-happy-sad-number-test)
+- [Find the Largest Number Possible After Removing k Digits of a Number](https://www.baeldung.com/java-find-largest-number-remove-k-digits)
+- [Implement Connect 4 Game with Java](https://www.baeldung.com/java-connect-4-game)
+- More articles: [[<-- prev]](/algorithms-miscellaneous-7)
\ No newline at end of file
diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigits.java b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigits.java
similarity index 98%
rename from algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigits.java
rename to algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigits.java
index 79086fc61f..51e8350afc 100644
--- a/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigits.java
+++ b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigits.java
@@ -1,6 +1,6 @@
package com.baeldung.algorithms.largestNumberRemovingK;
-import java.util.*;
+import java.util.Stack;
public class LargestNumberRemoveKDigits {
public static int findLargestNumberUsingArithmetic(int num, int k) {
diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/parentnodebinarytree/ParentKeeperTreeNode.java b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/parentnodebinarytree/ParentKeeperTreeNode.java
similarity index 100%
rename from algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/parentnodebinarytree/ParentKeeperTreeNode.java
rename to algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/parentnodebinarytree/ParentKeeperTreeNode.java
diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/parentnodebinarytree/TreeNode.java b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/parentnodebinarytree/TreeNode.java
similarity index 100%
rename from algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/parentnodebinarytree/TreeNode.java
rename to algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/parentnodebinarytree/TreeNode.java
diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/GameBoard.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/connect4/GameBoard.java
similarity index 100%
rename from algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/GameBoard.java
rename to algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/connect4/GameBoard.java
diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/GameUnitTest.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/connect4/GameUnitTest.java
similarity index 100%
rename from algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/GameUnitTest.java
rename to algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/connect4/GameUnitTest.java
diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/Piece.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/connect4/Piece.java
similarity index 100%
rename from algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/Piece.java
rename to algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/connect4/Piece.java
diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/happynumber/HappyNumberUnitTest.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/happynumber/HappyNumberUnitTest.java
similarity index 100%
rename from algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/happynumber/HappyNumberUnitTest.java
rename to algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/happynumber/HappyNumberUnitTest.java
diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/jugglersequence/JugglerSequenceUnitTest.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/jugglersequence/JugglerSequenceUnitTest.java
similarity index 100%
rename from algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/jugglersequence/JugglerSequenceUnitTest.java
rename to algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/jugglersequence/JugglerSequenceUnitTest.java
diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigitsUnitTest.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigitsUnitTest.java
similarity index 100%
rename from algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigitsUnitTest.java
rename to algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigitsUnitTest.java
diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/parentnodebinarytree/BinaryTreeParentNodeFinderUnitTest.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/parentnodebinarytree/BinaryTreeParentNodeFinderUnitTest.java
similarity index 94%
rename from algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/parentnodebinarytree/BinaryTreeParentNodeFinderUnitTest.java
rename to algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/parentnodebinarytree/BinaryTreeParentNodeFinderUnitTest.java
index d3f0ec7997..ff31f99ed6 100644
--- a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/parentnodebinarytree/BinaryTreeParentNodeFinderUnitTest.java
+++ b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/parentnodebinarytree/BinaryTreeParentNodeFinderUnitTest.java
@@ -5,7 +5,9 @@ import org.junit.jupiter.api.Test;
import java.util.NoSuchElementException;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertNull;
class BinaryTreeParentNodeFinderUnitTest {
diff --git a/apache-poi/pom.xml b/apache-poi/pom.xml
index 876fca0efe..027ee06968 100644
--- a/apache-poi/pom.xml
+++ b/apache-poi/pom.xml
@@ -40,6 +40,16 @@
fastexcel-reader
${fastexcel.version}
+
+ org.apache.logging.log4j
+ log4j-api
+ ${log4j.version}
+
+
+ org.apache.logging.log4j
+ log4j-core
+ ${log4j.version}
+
@@ -64,6 +74,7 @@
1.0.9
0.17.0
3.3.1
+ 2.23.1
\ No newline at end of file
diff --git a/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/pom.xml b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/pom.xml
index acc14b55ff..2aa48a2f92 100644
--- a/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/pom.xml
+++ b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/pom.xml
@@ -71,7 +71,7 @@
org.mockito
mockito-core
- ${mockito-core.version}
+ ${mockito.version}
test
@@ -112,7 +112,6 @@
11.2
5.1.0
2.0.2
- 4.1.0
3.19.0
5.8.1
diff --git a/azure/pom.xml b/azure/pom.xml
index 61ae0c7d68..52d7fa4864 100644
--- a/azure/pom.xml
+++ b/azure/pom.xml
@@ -11,9 +11,9 @@
com.baeldung
- parent-boot-2
+ parent-boot-3
0.0.1-SNAPSHOT
- ../parent-boot-2
+ ../parent-boot-3
@@ -98,7 +98,7 @@
spring.datasource.password
-
+ test
@@ -113,6 +113,14 @@
+
+
+
+ javax.xml.bind
+ jaxb-api
+ 2.4.0-b180830.0359
+
+
diff --git a/azure/src/main/java/com/baeldung/springboot/azure/User.java b/azure/src/main/java/com/baeldung/springboot/azure/User.java
index d7a25aa246..1e7954d9b0 100644
--- a/azure/src/main/java/com/baeldung/springboot/azure/User.java
+++ b/azure/src/main/java/com/baeldung/springboot/azure/User.java
@@ -1,9 +1,9 @@
package com.baeldung.springboot.azure;
-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;
/**
* @author aiet
diff --git a/core-java-modules/core-java-11/src/main/java/com/baeldung/Unrelated.java b/core-java-modules/core-java-11/src/main/java/com/baeldung/Unrelated.java
new file mode 100644
index 0000000000..f122b89f6e
--- /dev/null
+++ b/core-java-modules/core-java-11/src/main/java/com/baeldung/Unrelated.java
@@ -0,0 +1,4 @@
+package com.baeldung;
+
+public class Unrelated {
+}
diff --git a/core-java-modules/core-java-11/src/test/java/com/baeldung/OuterUnitTest.java b/core-java-modules/core-java-11/src/test/java/com/baeldung/OuterUnitTest.java
index 9e6bd72680..8699e94b47 100644
--- a/core-java-modules/core-java-11/src/test/java/com/baeldung/OuterUnitTest.java
+++ b/core-java-modules/core-java-11/src/test/java/com/baeldung/OuterUnitTest.java
@@ -1,7 +1,7 @@
package com.baeldung;
-import static org.junit.Assert.assertTrue;
import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Set;
@@ -14,22 +14,22 @@ public class OuterUnitTest {
@Test
public void whenGetNestHostFromOuter_thenGetNestHost() {
- is(Outer.class.getNestHost().getName()).equals(NEST_HOST_NAME);
+ assertEquals(NEST_HOST_NAME, Outer.class.getNestHost().getName());
}
@Test
public void whenGetNestHostFromInner_thenGetNestHost() {
- is(Outer.Inner.class.getNestHost().getName()).equals(NEST_HOST_NAME);
+ assertEquals(NEST_HOST_NAME, Outer.Inner.class.getNestHost().getName());
}
@Test
public void whenCheckNestmatesForNestedClasses_thenGetTrue() {
- is(Outer.Inner.class.isNestmateOf(Outer.class)).equals(true);
+ assertTrue(Outer.Inner.class.isNestmateOf(Outer.class));
}
@Test
public void whenCheckNestmatesForUnrelatedClasses_thenGetFalse() {
- is(Outer.Inner.class.isNestmateOf(Outer.class)).equals(false);
+ assertFalse(Outer.Inner.class.isNestmateOf(Unrelated.class));
}
@Test
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 04461663e3..29ceaf29e1 100644
--- a/core-java-modules/core-java-8-datetime-2/README.md
+++ b/core-java-modules/core-java-8-datetime-2/README.md
@@ -9,9 +9,4 @@
- [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)
-- [Format LocalDate to ISO 8601 With T and Z](https://www.baeldung.com/java-format-localdate-iso-8601-t-z)
-- [Check if Two Date Ranges Overlap](https://www.baeldung.com/java-check-two-date-ranges-overlap)
-- [Difference between ZoneOffset.UTC and ZoneId.of(“UTC”)](https://www.baeldung.com/java-zoneoffset-utc-zoneid-of)
-- [Check if a Given Time Lies Between Two Times Regardless of Date](https://www.baeldung.com/java-check-between-two-times)
-- [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1)
+- [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1) [[Next -->]](/core-java-modules/core-java-8-datetime-3)
diff --git a/core-java-modules/core-java-8-datetime-3/README.md b/core-java-modules/core-java-8-datetime-3/README.md
new file mode 100644
index 0000000000..d320466814
--- /dev/null
+++ b/core-java-modules/core-java-8-datetime-3/README.md
@@ -0,0 +1,8 @@
+### Relevant Articles:
+
+- [Calculate Months Between Two Dates in Java](https://www.baeldung.com/java-months-difference-two-dates)
+- [Format LocalDate to ISO 8601 With T and Z](https://www.baeldung.com/java-format-localdate-iso-8601-t-z)
+- [Check if Two Date Ranges Overlap](https://www.baeldung.com/java-check-two-date-ranges-overlap)
+- [Difference between ZoneOffset.UTC and ZoneId.of(“UTC”)](https://www.baeldung.com/java-zoneoffset-utc-zoneid-of)
+- [Check if a Given Time Lies Between Two Times Regardless of Date](https://www.baeldung.com/java-check-between-two-times)
+- [[<-- Prev]](/core-java-modules/core-java-8-datetime-2)
diff --git a/core-java-modules/core-java-8-datetime-3/pom.xml b/core-java-modules/core-java-8-datetime-3/pom.xml
new file mode 100644
index 0000000000..4e32190fcf
--- /dev/null
+++ b/core-java-modules/core-java-8-datetime-3/pom.xml
@@ -0,0 +1,55 @@
+
+
+ 4.0.0
+ core-java-8-datetime-3
+ jar
+ core-java-8-datetime-3
+
+
+ com.baeldung.core-java-modules
+ core-java-modules
+ 0.0.1-SNAPSHOT
+
+
+
+
+ org.apache.commons
+ commons-lang3
+ ${commons-lang3.version}
+
+
+ joda-time
+ joda-time
+ ${joda-time.version}
+
+
+
+
+
+
+ src/main/resources
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ ${maven.compiler.source}
+ ${maven.compiler.target}
+
+
+
+
+
+
+ 1.8
+ 1.8
+ 2.12.5
+
+
+
\ No newline at end of file
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-3/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java
similarity index 100%
rename from core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java
rename to core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java
index 9b898c87f5..9fbe4bc7fe 100644
--- 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-3/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java
@@ -1,11 +1,11 @@
package com.baeldung.daterangeoverlap;
-import java.time.LocalDate;
-import java.util.Calendar;
-
import org.joda.time.DateTime;
import org.joda.time.Interval;
+import java.time.LocalDate;
+import java.util.Calendar;
+
public class DateRangeOverlapChecker {
public static boolean isOverlapUsingCalendarAndDuration(Calendar start1, Calendar end1, Calendar start2, Calendar end2) {
diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/localdatetoiso/LocalDateToISO.java b/core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/localdatetoiso/LocalDateToISO.java
similarity index 92%
rename from core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/localdatetoiso/LocalDateToISO.java
rename to core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/localdatetoiso/LocalDateToISO.java
index e09d823ce4..adf6c09107 100644
--- a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/localdatetoiso/LocalDateToISO.java
+++ b/core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/localdatetoiso/LocalDateToISO.java
@@ -1,20 +1,16 @@
package com.baeldung.localdatetoiso;
+import org.apache.commons.lang3.time.FastDateFormat;
+import org.joda.time.DateTimeZone;
+import org.joda.time.format.ISODateTimeFormat;
+
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Date;
-
-import org.apache.commons.lang3.time.DateFormatUtils;
-
-import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
-import org.joda.time.format.DateTimeFormat;
-import org.joda.time.format.ISODateTimeFormat;
-
-import org.apache.commons.lang3.time.FastDateFormat;
+import java.util.TimeZone;
public class LocalDateToISO {
public String formatUsingDateTimeFormatter(LocalDate localDate) {
diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/monthintervalbetweentwodates/MonthInterval.java b/core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/monthintervalbetweentwodates/MonthInterval.java
similarity index 100%
rename from core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/monthintervalbetweentwodates/MonthInterval.java
rename to core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/monthintervalbetweentwodates/MonthInterval.java
diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/checkiftimebetweentwotimes/CheckIfTimeBetweenTwoTimesUnitTest.java b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/checkiftimebetweentwotimes/CheckIfTimeBetweenTwoTimesUnitTest.java
similarity index 97%
rename from core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/checkiftimebetweentwotimes/CheckIfTimeBetweenTwoTimesUnitTest.java
rename to core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/checkiftimebetweentwotimes/CheckIfTimeBetweenTwoTimesUnitTest.java
index 1ffddaa241..e2f526947e 100644
--- a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/checkiftimebetweentwotimes/CheckIfTimeBetweenTwoTimesUnitTest.java
+++ b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/checkiftimebetweentwotimes/CheckIfTimeBetweenTwoTimesUnitTest.java
@@ -1,45 +1,45 @@
-package com.baeldung.checkiftimebetweentwotimes;
-
-import org.junit.Test;
-
-import java.time.LocalTime;
-import java.util.Calendar;
-import java.util.Date;
-
-import static org.junit.Assert.assertTrue;
-
-public class CheckIfTimeBetweenTwoTimesUnitTest {
- private LocalTime startTime = LocalTime.parse("09:00:00");
- private LocalTime endTime = LocalTime.parse("17:00:00");
- private LocalTime targetTime = LocalTime.parse("12:30:00");
-
- @Test
- public void givenLocalTime_whenUsingIsAfterIsBefore_thenTimeIsBetween() {
- assertTrue(!targetTime.isBefore(startTime) && !targetTime.isAfter(endTime));
- }
-
- @Test
- public void givenLocalTime_whenUsingCompareTo_thenTimeIsBetween() {
- assertTrue(targetTime.compareTo(startTime) >= 0 && targetTime.compareTo(endTime) <= 0);
- }
-
- @Test
- public void givenDate_whenUsingAfterBefore_thenTimeIsBetween() {
- Calendar startCalendar = Calendar.getInstance();
- startCalendar.set(Calendar.HOUR_OF_DAY, 9);
- startCalendar.set(Calendar.MINUTE, 0);
- Date startTime = startCalendar.getTime();
-
- Calendar endCalendar = Calendar.getInstance();
- endCalendar.set(Calendar.HOUR_OF_DAY, 17);
- endCalendar.set(Calendar.MINUTE, 0);
- Date endTime = endCalendar.getTime();
-
- Calendar targetCalendar = Calendar.getInstance();
- targetCalendar.set(Calendar.HOUR_OF_DAY, 12);
- targetCalendar.set(Calendar.MINUTE, 30);
- Date targetTime = targetCalendar.getTime();
-
- assertTrue(!targetTime.before(startTime) && !targetTime.after(endTime));
- }
+package com.baeldung.checkiftimebetweentwotimes;
+
+import org.junit.Test;
+
+import java.time.LocalTime;
+import java.util.Calendar;
+import java.util.Date;
+
+import static org.junit.Assert.assertTrue;
+
+public class CheckIfTimeBetweenTwoTimesUnitTest {
+ private LocalTime startTime = LocalTime.parse("09:00:00");
+ private LocalTime endTime = LocalTime.parse("17:00:00");
+ private LocalTime targetTime = LocalTime.parse("12:30:00");
+
+ @Test
+ public void givenLocalTime_whenUsingIsAfterIsBefore_thenTimeIsBetween() {
+ assertTrue(!targetTime.isBefore(startTime) && !targetTime.isAfter(endTime));
+ }
+
+ @Test
+ public void givenLocalTime_whenUsingCompareTo_thenTimeIsBetween() {
+ assertTrue(targetTime.compareTo(startTime) >= 0 && targetTime.compareTo(endTime) <= 0);
+ }
+
+ @Test
+ public void givenDate_whenUsingAfterBefore_thenTimeIsBetween() {
+ Calendar startCalendar = Calendar.getInstance();
+ startCalendar.set(Calendar.HOUR_OF_DAY, 9);
+ startCalendar.set(Calendar.MINUTE, 0);
+ Date startTime = startCalendar.getTime();
+
+ Calendar endCalendar = Calendar.getInstance();
+ endCalendar.set(Calendar.HOUR_OF_DAY, 17);
+ endCalendar.set(Calendar.MINUTE, 0);
+ Date endTime = endCalendar.getTime();
+
+ Calendar targetCalendar = Calendar.getInstance();
+ targetCalendar.set(Calendar.HOUR_OF_DAY, 12);
+ targetCalendar.set(Calendar.MINUTE, 30);
+ Date targetTime = targetCalendar.getTime();
+
+ assertTrue(!targetTime.before(startTime) && !targetTime.after(endTime));
+ }
}
\ No newline at end of file
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-3/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java
similarity index 100%
rename from core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java
rename to core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java
index 5811cb6552..fa8145f71c 100644
--- 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-3/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java
@@ -1,13 +1,13 @@
package com.baeldung.daterangeoverlap;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import org.joda.time.DateTime;
+import org.junit.Test;
import java.time.LocalDate;
import java.util.Calendar;
-import org.joda.time.DateTime;
-import org.junit.Test;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
public class DateRangeOverlapCheckerUnitTest {
diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/localdatetoiso/LocalDateToISOUnitTest.java b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/localdatetoiso/LocalDateToISOUnitTest.java
similarity index 81%
rename from core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/localdatetoiso/LocalDateToISOUnitTest.java
rename to core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/localdatetoiso/LocalDateToISOUnitTest.java
index 1979c91eca..c82cc2766d 100644
--- a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/localdatetoiso/LocalDateToISOUnitTest.java
+++ b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/localdatetoiso/LocalDateToISOUnitTest.java
@@ -1,13 +1,14 @@
package com.baeldung.localdatetoiso;
+import org.junit.Test;
+
+import java.time.LocalDate;
+
import static org.junit.Assert.assertEquals;
-import org.junit.Test;
-import java.time.LocalDate;
-
public class LocalDateToISOUnitTest {
@Test
- void givenLocalDate_whenUsingDateTimeFormatter_thenISOFormat(){
+ public void givenLocalDate_whenUsingDateTimeFormatter_thenISOFormat(){
LocalDateToISO localDateToISO = new LocalDateToISO();
LocalDate localDate = LocalDate.of(2023, 11, 6);
@@ -17,7 +18,7 @@ public class LocalDateToISOUnitTest {
}
@Test
- void givenLocalDate_whenUsingSimpleDateFormat_thenISOFormat(){
+ public void givenLocalDate_whenUsingSimpleDateFormat_thenISOFormat(){
LocalDateToISO localDateToISO = new LocalDateToISO();
LocalDate localDate = LocalDate.of(2023, 11, 6);
@@ -27,17 +28,18 @@ public class LocalDateToISOUnitTest {
}
@Test
- void givenLocalDate_whenUsingJodaTime_thenISOFormat() {
+ public void givenLocalDate_whenUsingJodaTime_thenISOFormat() {
LocalDateToISO localDateToISO = new LocalDateToISO();
org.joda.time.LocalDate localDate = new org.joda.time.LocalDate(2023, 11, 6);
String expected = "2023-11-06T00:00:00.000Z";
String actual = localDateToISO.formatUsingJodaTime(localDate);
assertEquals(expected, actual);
+ assertEquals(expected, actual);
}
@Test
- void givenLocalDate_whenUsingApacheCommonsLang_thenISOFormat() {
+ public void givenLocalDate_whenUsingApacheCommonsLang_thenISOFormat() {
LocalDateToISO localDateToISO = new LocalDateToISO();
LocalDate localDate = LocalDate.of(2023, 11, 6);
diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/monthintervalbetweentwodates/MonthIntervalUnitTest.java b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/monthintervalbetweentwodates/MonthIntervalUnitTest.java
similarity index 100%
rename from core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/monthintervalbetweentwodates/MonthIntervalUnitTest.java
rename to core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/monthintervalbetweentwodates/MonthIntervalUnitTest.java
diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java
similarity index 96%
rename from core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java
rename to core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java
index 84f40c3cd5..298963fd70 100644
--- a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java
+++ b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java
@@ -1,25 +1,25 @@
-package com.baeldung.zoneoffsetandzoneidof;
-
-import org.junit.jupiter.api.Test;
-
-import java.time.OffsetDateTime;
-import java.time.ZoneId;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-public class ZoneOffSetAndZoneIdOfUnitTest {
-
- @Test
- public void givenOffsetDateTimeWithUTCZoneOffset_thenOffsetShouldBeUTC() {
- OffsetDateTime dateTimeWithOffset = OffsetDateTime.now(ZoneOffset.UTC);
- assertEquals(dateTimeWithOffset.getOffset(), ZoneOffset.UTC);
- }
-
- @Test
- public void givenZonedDateTimeWithUTCZoneId_thenZoneShouldBeUTC() {
- ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("UTC"));
- assertEquals(zonedDateTime.getZone(), ZoneId.of("UTC"));
- }
-}
+package com.baeldung.zoneoffsetandzoneidof;
+
+import org.junit.jupiter.api.Test;
+
+import java.time.OffsetDateTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class ZoneOffSetAndZoneIdOfUnitTest {
+
+ @Test
+ public void givenOffsetDateTimeWithUTCZoneOffset_thenOffsetShouldBeUTC() {
+ OffsetDateTime dateTimeWithOffset = OffsetDateTime.now(ZoneOffset.UTC);
+ assertEquals(dateTimeWithOffset.getOffset(), ZoneOffset.UTC);
+ }
+
+ @Test
+ public void givenZonedDateTimeWithUTCZoneId_thenZoneShouldBeUTC() {
+ ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("UTC"));
+ assertEquals(zonedDateTime.getZone(), ZoneId.of("UTC"));
+ }
+}
diff --git a/core-java-modules/core-java-collections-5/README.md b/core-java-modules/core-java-collections-5/README.md
index 4f174b5163..2fc7f7c699 100644
--- a/core-java-modules/core-java-collections-5/README.md
+++ b/core-java-modules/core-java-collections-5/README.md
@@ -9,7 +9,6 @@
- [Skipping the First Iteration in Java](https://www.baeldung.com/java-skip-first-iteration)
- [Remove Elements From a Queue Using Loop](https://www.baeldung.com/java-remove-elements-queue)
- [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)
diff --git a/core-java-modules/core-java-collections-5/pom.xml b/core-java-modules/core-java-collections-5/pom.xml
index 939e479ba1..227b80ac4a 100644
--- a/core-java-modules/core-java-collections-5/pom.xml
+++ b/core-java-modules/core-java-collections-5/pom.xml
@@ -55,8 +55,8 @@
org.apache.maven.plugins
maven-compiler-plugin
- 9
- 9
+ 16
+ 16
diff --git a/core-java-modules/core-java-collections-6/README.md b/core-java-modules/core-java-collections-6/README.md
new file mode 100644
index 0000000000..736e91f110
--- /dev/null
+++ b/core-java-modules/core-java-collections-6/README.md
@@ -0,0 +1,7 @@
+=========
+
+## Core Java Collections Cookbooks and Examples
+
+### Relevant Articles:
+
+- More articles: [[<-- prev]](/core-java-modules/core-java-collections-5)
diff --git a/core-java-modules/core-java-collections-6/pom.xml b/core-java-modules/core-java-collections-6/pom.xml
new file mode 100644
index 0000000000..3d38c3de35
--- /dev/null
+++ b/core-java-modules/core-java-collections-6/pom.xml
@@ -0,0 +1,71 @@
+
+
+ 4.0.0
+ core-java-collections-6
+ jar
+ core-java-collections-6
+
+
+ com.baeldung.core-java-modules
+ core-java-modules
+ 0.0.1-SNAPSHOT
+
+
+
+
+ org.junit.platform
+ junit-platform-runner
+ ${junit-platform.version}
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter
+ ${junit.version}
+ test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ ${junit.version}
+ test
+
+
+ org.roaringbitmap
+ RoaringBitmap
+ ${roaringbitmap.version}
+
+
+ org.openjdk.jmh
+ jmh-generator-annprocess
+ ${jmh.version}
+
+
+ org.openjdk.jmh
+ jmh-core
+ ${jmh.version}
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 9
+ 9
+
+
+
+
+
+
+ 5.9.2
+ 0.9.38
+ 1.36
+
+
+
diff --git a/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java b/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java
new file mode 100644
index 0000000000..ca9390a3ee
--- /dev/null
+++ b/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java
@@ -0,0 +1,64 @@
+package com.baeldung.iteratorvsforeach;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertIterableEquals;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+class IteratorVsForeachUnitTest {
+
+ private static Stream listProvider() {
+ return Stream.of(Arguments.of(List.of("String1", "String2", "unwanted"), List.of("String1", "String2")));
+ }
+
+ @Test
+ public void givenEmptyCollection_whenUsingForEach_thenNoElementsAreIterated() {
+ List names = Collections.emptyList();
+ StringBuilder stringBuilder = new StringBuilder();
+ names.forEach(stringBuilder::append);
+ assertEquals("", stringBuilder.toString());
+ }
+
+ @ParameterizedTest
+ @MethodSource("listProvider")
+ public void givenCollectionWithElements_whenRemovingElementDuringForEachIteration_thenElementIsRemoved(List input, List expected) {
+ List mutableList = new ArrayList<>(input);
+ // Separate collection for items to be removed
+ List toRemove = new ArrayList<>();
+
+ // Using forEach to identify items to remove
+ input.forEach(item -> {
+ if (item.equals("unwanted")) {
+ toRemove.add(item);
+ }
+ });
+
+ // Removing the identified items from the original list
+ mutableList.removeAll(toRemove);
+ assertIterableEquals(expected, mutableList);
+ }
+
+ @ParameterizedTest
+ @MethodSource("listProvider")
+ public void givenCollectionWithElements_whenRemovingElementDuringIteratorIteration_thenElementIsRemoved(List input, List expected) {
+ List mutableList = new ArrayList<>(input);
+ Iterator it = mutableList.iterator();
+ while (it.hasNext()) {
+ String item = it.next();
+ if (item.equals("unwanted")) {
+ it.remove(); // Safely remove item
+ }
+ }
+ assertIterableEquals(expected, mutableList);
+ }
+
+}
diff --git a/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/listiteration/ListIterationUnitTest.java b/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/listiteration/ListIterationUnitTest.java
new file mode 100644
index 0000000000..2f1b2cc083
--- /dev/null
+++ b/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/listiteration/ListIterationUnitTest.java
@@ -0,0 +1,71 @@
+package com.baeldung.listiteration;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.junit.jupiter.api.Assertions.assertIterableEquals;
+
+public class ListIterationUnitTest {
+
+ List programmingLanguages = new ArrayList<>(List.of("Java", "Python", "C++"));
+ List numbers = new ArrayList<>(List.of(1, 2, 3));
+
+ @Test
+ public void givenStringList_whenAddElementWithListIterator_thenModifiedList() {
+ ListIterator listIterator = programmingLanguages.listIterator();
+ while (listIterator.hasNext()) {
+ String language = listIterator.next();
+ if (language.equals("Python")) {
+ listIterator.add("JavaScript");
+ }
+ }
+
+ assertIterableEquals(Arrays.asList("Java", "Python", "JavaScript", "C++"), programmingLanguages);
+ }
+
+ @Test
+ public void givenNumericalList_whenMultiplyElementWithListIterator_thenModifiedList() {
+ ListIterator listIterator = numbers.listIterator();
+ while (listIterator.hasNext()) {
+ int num = listIterator.next();
+ if (num == 2) {
+ listIterator.add(num * 10);
+ }
+ }
+ assertIterableEquals(Arrays.asList(1, 2, 20, 3), numbers);
+ }
+
+ @Test
+ public void givenStringList_whenAddElementWithEnhancedForLoopAndCopy_thenModifiedList() {
+ List copyOfWords = new ArrayList<>(programmingLanguages);
+ for (String word : copyOfWords) {
+ programmingLanguages.add(word.toUpperCase()); // Modified: Convert to uppercase
+ }
+ assertIterableEquals(Arrays.asList("Java", "Python", "C++", "JAVA", "PYTHON", "C++"), programmingLanguages);
+ }
+
+ @Test
+ public void givenNumericalList_whenMultiplyElementWithEnhancedForLoopAndCopy_thenModifiedList() {
+ List copyOfNumbers = new ArrayList<>(numbers);
+ for (int num : copyOfNumbers) {
+ numbers.add(num * 2);
+ }
+ assertIterableEquals(Arrays.asList(1, 2, 3, 2, 4, 6), numbers);
+ }
+
+ @Test
+ public void givenStringList_whenConvertToUpperCaseWithJava8Stream_thenModifiedList() {
+ programmingLanguages = programmingLanguages.stream().map(String::toUpperCase).collect(Collectors.toList());
+ assertIterableEquals(Arrays.asList("JAVA", "PYTHON", "C++"), programmingLanguages);
+ }
+
+ @Test
+ public void givenNumericalList_whenMultiplyByThreeWithJava8Stream_thenModifiedList() {
+ numbers = numbers.stream().map(num -> num * 3).collect(Collectors.toList());
+ assertIterableEquals(Arrays.asList(3, 6, 9), numbers);
+ }
+
+}
diff --git a/core-java-modules/core-java-collections-conversions-3/README.md b/core-java-modules/core-java-collections-conversions-3/README.md
index 959e4e8160..96727e8d88 100644
--- a/core-java-modules/core-java-collections-conversions-3/README.md
+++ b/core-java-modules/core-java-collections-conversions-3/README.md
@@ -5,3 +5,4 @@ This module contains articles about conversions among Collection types in Java.
### Relevant Articles:
- [Converting HashMap Values to an ArrayList in Java](https://www.baeldung.com/java-hashmap-arraylist)
- [Joining a List in Java With Commas and “and”](https://www.baeldung.com/java-string-concatenation-natural-language)
+- [HashSet toArray() Method in Java](https://www.baeldung.com/java-hashset-toarray)
diff --git a/core-java-modules/core-java-collections-5/toarraymethod/ConvertingHashSetToArrayUnitTest.java b/core-java-modules/core-java-collections-conversions-3/src/test/java/com/baeldung/toarraymethod/ConvertingHashSetToArrayUnitTest.java
similarity index 100%
rename from core-java-modules/core-java-collections-5/toarraymethod/ConvertingHashSetToArrayUnitTest.java
rename to core-java-modules/core-java-collections-conversions-3/src/test/java/com/baeldung/toarraymethod/ConvertingHashSetToArrayUnitTest.java
diff --git a/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listInitialization/ListInitializationUnitTest.java b/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listInitialization/ListInitializationUnitTest.java
deleted file mode 100644
index 25f39e9a13..0000000000
--- a/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listInitialization/ListInitializationUnitTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.baeldung.java.listInitialization;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import lombok.extern.java.Log;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-@Log
-public class ListInitializationUnitTest {
-
- @Test
- public void givenAnonymousInnerClass_thenInitialiseList() {
- List cities = new ArrayList() {
- {
- add("New York");
- add("Rio");
- add("Tokyo");
- }
- };
-
- Assert.assertTrue(cities.contains("New York"));
- }
-
- @Test
- public void givenArraysAsList_thenInitialiseList() {
- List list = Arrays.asList("foo", "bar");
-
- Assert.assertTrue(list.contains("foo"));
- }
-
- @Test(expected = UnsupportedOperationException.class)
- public void givenArraysAsList_whenAdd_thenUnsupportedException() {
- List list = Arrays.asList("foo", "bar");
-
- list.add("baz");
- }
-
- @Test
- public void givenArraysAsList_whenCreated_thenShareReference() {
- String[] array = { "foo", "bar" };
- List list = Arrays.asList(array);
- array[0] = "baz";
- Assert.assertEquals("baz", list.get(0));
- }
-
- @Test
- public void givenStream_thenInitializeList() {
- List list = Stream.of("foo", "bar")
- .collect(Collectors.toList());
-
- Assert.assertTrue(list.contains("foo"));
- }
-}
diff --git a/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listinitialization/ListInitializationUnitTest.java b/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listinitialization/ListInitializationUnitTest.java
new file mode 100644
index 0000000000..4b06621fef
--- /dev/null
+++ b/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listinitialization/ListInitializationUnitTest.java
@@ -0,0 +1,91 @@
+package com.baeldung.java.listinitialization;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.junit.Test;
+
+import lombok.extern.java.Log;
+
+@Log
+public class ListInitializationUnitTest {
+
+ @Test
+ public void givenAnonymousInnerClass_thenInitialiseList() {
+ List cities = new ArrayList() {
+ {
+ add("New York");
+ add("Rio");
+ add("Tokyo");
+ }
+ };
+
+ assertTrue(cities.contains("New York"));
+ }
+
+ @Test
+ public void givenArraysAsList_thenInitialiseList() {
+ List list = Arrays.asList("foo", "bar");
+
+ assertTrue(list.contains("foo"));
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void givenArraysAsList_whenAdd_thenUnsupportedException() {
+ List list = Arrays.asList("foo", "bar");
+
+ list.add("baz");
+ }
+
+ @Test
+ public void givenArraysAsList_whenUsingArrayListConstructor_thenWeCanAddOrRemove() {
+ List list = new ArrayList<>(Arrays.asList("foo", "bar"));
+
+ list.add("baz");
+ assertEquals(List.of("foo", "bar","baz"), list);
+
+ list.remove("baz");
+ assertEquals(List.of("foo", "bar"), list);
+ }
+
+ @Test
+ public void givenArraysAsList_whenCreated_thenShareReference() {
+ String[] array = { "foo", "bar" };
+ List list = Arrays.asList(array);
+ array[0] = "baz";
+ assertEquals("baz", list.get(0));
+ }
+
+ @Test
+ public void givenIntNumbers_whenRequiredLong_thenCastAutomatically() {
+ int intNum = 42;
+ long longNum = intNum;
+
+ assertEquals(42L, longNum);
+ }
+
+ @Test
+ public void givenArrayAsList_whenRequiredLongList_thenGetExpectedResult() {
+ List listOfLongFixedSize = Arrays.asList(1L, 2L, 3L);
+ List listOfLong = new ArrayList<>(Arrays.asList(1L, 2L, 3L));
+
+ List expected = List.of(1L, 2L, 3L);
+
+ assertEquals(expected, listOfLongFixedSize);
+ assertEquals(expected, listOfLong);
+ }
+
+ @Test
+ public void givenStream_thenInitializeList() {
+ List list = Stream.of("foo", "bar")
+ .collect(Collectors.toList());
+
+ assertTrue(list.contains("foo"));
+ }
+}
\ No newline at end of file
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 2b08736a11..c8472f088e 100644
--- a/core-java-modules/core-java-io-apis-2/README.md
+++ b/core-java-modules/core-java-io-apis-2/README.md
@@ -12,3 +12,4 @@ This module contains articles about core Java input/output(IO) APIs.
- [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)
- [Get a Path to a Resource in a Java JAR File](https://www.baeldung.com/java-get-path-resource-jar)
+- [Java InputStream vs. InputStreamReader](https://www.baeldung.com/java-inputstream-vs-inputstreamreader)
diff --git a/core-java-modules/core-java-io-apis/README.md b/core-java-modules/core-java-io-apis/README.md
index ee8547f0c5..faf7067f74 100644
--- a/core-java-modules/core-java-io-apis/README.md
+++ b/core-java-modules/core-java-io-apis/README.md
@@ -13,4 +13,3 @@ This module contains articles about core Java input/output(IO) APIs.
- [Difference Between FileReader and BufferedReader in Java](https://www.baeldung.com/java-filereader-vs-bufferedreader)
- [Read Multiple Inputs on the Same Line in Java](https://www.baeldung.com/java-read-multiple-inputs-same-line)
- [Write Console Output to Text File in Java](https://www.baeldung.com/java-write-console-output-file)
-- [Java InputStream vs. InputStreamReader](https://www.baeldung.com/java-inputstream-vs-inputstreamreader)
diff --git a/core-java-modules/core-java-jar/pom.xml b/core-java-modules/core-java-jar/pom.xml
index 460adf45e7..e87fba922e 100644
--- a/core-java-modules/core-java-jar/pom.xml
+++ b/core-java-modules/core-java-jar/pom.xml
@@ -260,7 +260,6 @@
0.4
1.8.7
- 4.6.1
1.1
3.6.2
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 d4eef0f1b9..473369beef 100644
--- a/core-java-modules/core-java-lang-math-3/README.md
+++ b/core-java-modules/core-java-lang-math-3/README.md
@@ -7,15 +7,11 @@
- [Evaluating a Math Expression in Java](https://www.baeldung.com/java-evaluate-math-expression-string)
- [Swap Two Variables in Java](https://www.baeldung.com/java-swap-two-variables)
- [Java Program to Find the Roots of a Quadratic Equation](https://www.baeldung.com/roots-quadratic-equation)
-- [Create a BMI Calculator in Java](https://www.baeldung.com/java-body-mass-index-calculator)
- [Java Program to Calculate the Standard Deviation](https://www.baeldung.com/java-calculate-standard-deviation)
- [Java Program to Print Pascal’s Triangle](https://www.baeldung.com/java-pascal-triangle)
- [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)
- [Validate if a String Is a Valid Geo Coordinate](https://www.baeldung.com/java-geo-coordinates-validation)
-- [Rotate a Vertex Around a Certain Point in Java](https://www.baeldung.com/java-rotate-vertex-around-point)
- [Calculating the Power of Any Number in Java Without Using Math pow() Method](https://www.baeldung.com/java-calculating-the-power-without-math-pow)
-- [Solving Rod Cutting Problem in Java](https://www.baeldung.com/java-rod-cutting-problem)
- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2)
diff --git a/core-java-modules/core-java-lang-math-4/README.md b/core-java-modules/core-java-lang-math-4/README.md
index 377c51848d..0efe87f7ff 100644
--- a/core-java-modules/core-java-lang-math-4/README.md
+++ b/core-java-modules/core-java-lang-math-4/README.md
@@ -2,3 +2,7 @@
### Relevant articles:
- [Calculate Percentiles in Java](https://www.baeldung.com/java-compute-percentiles)
+- [Solving Rod Cutting Problem in Java](https://www.baeldung.com/java-rod-cutting-problem)
+- [Rotate a Vertex Around a Certain Point in Java](https://www.baeldung.com/java-rotate-vertex-around-point)
+- [Create a BMI Calculator in Java](https://www.baeldung.com/java-body-mass-index-calculator)
+- [Check if a Point Is Between Two Points Drawn on a Straight Line in Java](https://www.baeldung.com/java-check-point-straight-line)
diff --git a/core-java-modules/core-java-lang-math-4/pom.xml b/core-java-modules/core-java-lang-math-4/pom.xml
index e818855d36..ccafb4a894 100644
--- a/core-java-modules/core-java-lang-math-4/pom.xml
+++ b/core-java-modules/core-java-lang-math-4/pom.xml
@@ -12,4 +12,8 @@
0.0.1-SNAPSHOT
+
+ 17
+
+
diff --git a/core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/bmicalculator/BMICalculator.java b/core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/bmicalculator/BMICalculator.java
similarity index 100%
rename from core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/bmicalculator/BMICalculator.java
rename to core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/bmicalculator/BMICalculator.java
diff --git a/core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPoints.java b/core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPoints.java
similarity index 100%
rename from core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPoints.java
rename to core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPoints.java
diff --git a/core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/rodcutting/RodCuttingProblem.java b/core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/rodcutting/RodCuttingProblem.java
similarity index 100%
rename from core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/rodcutting/RodCuttingProblem.java
rename to core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/rodcutting/RodCuttingProblem.java
diff --git a/core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/rotatevertex/VertexRotation.java b/core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/rotatevertex/VertexRotation.java
similarity index 100%
rename from core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/rotatevertex/VertexRotation.java
rename to core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/rotatevertex/VertexRotation.java
diff --git a/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/bmicalculator/BMICalculatorUnitTest.java b/core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/bmicalculator/BMICalculatorUnitTest.java
similarity index 100%
rename from core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/bmicalculator/BMICalculatorUnitTest.java
rename to core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/bmicalculator/BMICalculatorUnitTest.java
diff --git a/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPointsUnitTest.java b/core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPointsUnitTest.java
similarity index 100%
rename from core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPointsUnitTest.java
rename to core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPointsUnitTest.java
diff --git a/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/rodcutting/RodCuttingProblemUnitTest.java b/core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/rodcutting/RodCuttingProblemUnitTest.java
similarity index 100%
rename from core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/rodcutting/RodCuttingProblemUnitTest.java
rename to core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/rodcutting/RodCuttingProblemUnitTest.java
diff --git a/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/rotatevertex/VertexRotationUnitTest.java b/core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/rotatevertex/VertexRotationUnitTest.java
similarity index 100%
rename from core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/rotatevertex/VertexRotationUnitTest.java
rename to core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/rotatevertex/VertexRotationUnitTest.java
diff --git a/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/Example.java b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/Example.java
new file mode 100644
index 0000000000..0557e032ad
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/Example.java
@@ -0,0 +1,13 @@
+package com.baeldung.passclassasparameter;
+
+public class Example {
+ public static void processClass(Class> clazz) {
+ System.out.println("Processing class: " + clazz.getName());
+ }
+
+ public static void main(String[] args) {
+ processClass(String.class);
+ processClass(Integer.class);
+ processClass(Double.class);
+ }
+}
diff --git a/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/GenericExample.java b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/GenericExample.java
new file mode 100644
index 0000000000..c72d57743c
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/GenericExample.java
@@ -0,0 +1,22 @@
+package com.baeldung.passclassasparameter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class GenericExample {
+ public static void printListElements(Class clazz, List list) {
+ System.out.println("Elements of " + clazz.getSimpleName() + " list:");
+ for (T element : list) {
+ System.out.println(element);
+ }
+ }
+
+ public static void main(String[] args) {
+ List stringList = new ArrayList<>();
+ stringList.add("Java");
+ stringList.add("is");
+ stringList.add("awesome");
+
+ printListElements(String.class, stringList);
+ }
+}
diff --git a/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/ReflectionExample.java b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/ReflectionExample.java
new file mode 100644
index 0000000000..04c9dc3414
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/ReflectionExample.java
@@ -0,0 +1,21 @@
+package com.baeldung.passclassasparameter;
+
+import java.lang.reflect.Method;
+
+public class ReflectionExample {
+ public static void processClass(Class> clazz, String methodName) throws Exception {
+ Method method = clazz.getMethod(methodName);
+ Object instance = clazz.getDeclaredConstructor().newInstance();
+ method.invoke(instance);
+ }
+
+ public static void main(String[] args) throws Exception {
+ processClass(ReflectionTarget.class, "sayHello");
+ }
+}
+
+class ReflectionTarget {
+ public void sayHello() {
+ System.out.println("Hello, Reflection!");
+ }
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/symmetricsubstringlength/SymmetricSubstringMaxLengthUnitTest.java b/core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/symmetricsubstringlength/SymmetricSubstringMaxLengthUnitTest.java
new file mode 100644
index 0000000000..2ae37862dd
--- /dev/null
+++ b/core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/symmetricsubstringlength/SymmetricSubstringMaxLengthUnitTest.java
@@ -0,0 +1,77 @@
+package com.baeldung.symmetricsubstringlength;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class SymmetricSubstringMaxLengthUnitTest {
+ String input = "<>?>>";
+ int expected = 4;
+
+ @Test
+ public void givenString_whenUsingSymmetricSubstringExpansion_thenFindLongestSymmetricSubstring() {
+ int start = 0;
+ int mid = 0;
+ int last_gt = 0;
+ int end = 0;
+ int best = 0;
+
+ while (start < input.length()) {
+ int current = Math.min(mid - start, end - mid);
+ if (best < current) {
+ best = current;
+ }
+
+ if (end - mid == current && end < input.length()) {
+ if (input.charAt(end) == '?') {
+ end++;
+ } else if (input.charAt(end) == '>') {
+ end++;
+ last_gt = end;
+ } else {
+ end++;
+ mid = end;
+ start = Math.max(start, last_gt);
+ }
+ } else if (mid < input.length() && input.charAt(mid) == '?') {
+ mid++;
+ } else if (start < mid) {
+ start++;
+ } else {
+ start = Math.max(start, last_gt);
+ mid++;
+ end = Math.max(mid, end);
+ }
+ }
+ int result = 2 * best;
+
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void givenString_whenUsingBruteForce_thenFindLongestSymmetricSubstring() {
+ int max = 0;
+ for (int i = 0; i < input.length(); i++) {
+ for (int j = i + 1; j <= input.length(); j++) {
+ String t = input.substring(i, j);
+ if (t.length() % 2 == 0) {
+ int k = 0, l = t.length() - 1;
+ boolean isSym = true;
+ while (k < l && isSym) {
+ if (!(t.charAt(k) == '<' || t.charAt(k) == '?') && (t.charAt(l) == '>' || t.charAt(l) == '?')) {
+ isSym = false;
+ }
+ k++;
+ l--;
+ }
+ if (isSym) {
+ max = Math.max(max, t.length());
+ }
+ }
+ }
+ }
+
+ assertEquals(expected, max);
+ }
+
+}
diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml
index bd7aae6410..f6c5f8191a 100644
--- a/core-java-modules/pom.xml
+++ b/core-java-modules/pom.xml
@@ -89,6 +89,7 @@
core-java-collections-3
core-java-collections-4
core-java-collections-5
+ core-java-collections-6
core-java-collections-conversions
core-java-collections-set-2
core-java-collections-list
diff --git a/graphql-modules/pom.xml b/graphql-modules/pom.xml
index 2525f75eff..ef05e3eea6 100644
--- a/graphql-modules/pom.xml
+++ b/graphql-modules/pom.xml
@@ -20,7 +20,7 @@
org.springframework.boot
spring-boot-dependencies
- 2.6.4
+ 2.6.15
pom
import
@@ -34,4 +34,9 @@
graphql-spqr-boot-starter
+
+
+ 4.4.0
+
+
\ No newline at end of file
diff --git a/image-processing/pom.xml b/image-processing/pom.xml
index 5c59a53337..b40c56e539 100644
--- a/image-processing/pom.xml
+++ b/image-processing/pom.xml
@@ -12,6 +12,13 @@
1.0.0-SNAPSHOT
+
+
+ maven
+ https://maven.openimaj.org/
+
+
+
net.imagej
diff --git a/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/Shape.java b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/Shape.java
new file mode 100644
index 0000000000..b5d32a529b
--- /dev/null
+++ b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/Shape.java
@@ -0,0 +1,5 @@
+package com.baeldung.gson.polymorphic;
+
+public interface Shape {
+ double getArea();
+}
diff --git a/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/ShapeTypeAdapter.java b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/ShapeTypeAdapter.java
new file mode 100644
index 0000000000..cbdff9c6be
--- /dev/null
+++ b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/ShapeTypeAdapter.java
@@ -0,0 +1,27 @@
+package com.baeldung.gson.polymorphic;
+
+import com.google.gson.*;
+
+import java.lang.reflect.Type;
+
+public class ShapeTypeAdapter implements JsonSerializer, JsonDeserializer {
+ @Override
+ public JsonElement serialize(Shape shape, Type type, JsonSerializationContext context) {
+ JsonElement elem = new Gson().toJsonTree(shape);
+ elem.getAsJsonObject().addProperty("type", shape.getClass().getName());
+ return elem;
+ }
+
+ @Override
+ public Shape deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
+ JsonObject jsonObject = json.getAsJsonObject();
+ String typeName = jsonObject.get("type").getAsString();
+
+ try {
+ Class extends Shape> cls = (Class extends Shape>) Class.forName(typeName);
+ return new Gson().fromJson(json, cls);
+ } catch (ClassNotFoundException e) {
+ throw new JsonParseException(e);
+ }
+ }
+}
diff --git a/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/TypeAdapterUnitTest.java b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/TypeAdapterUnitTest.java
new file mode 100644
index 0000000000..81d5f5a9f2
--- /dev/null
+++ b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/TypeAdapterUnitTest.java
@@ -0,0 +1,117 @@
+package com.baeldung.gson.polymorphic;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.reflect.TypeToken;
+import org.junit.jupiter.api.Test;
+
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class TypeAdapterUnitTest {
+ @Test
+ void testSerialize() {
+ List shapes = Arrays.asList(
+ new Circle(4d),
+ new Square(5d)
+ );
+
+ GsonBuilder builder = new GsonBuilder();
+ builder.registerTypeHierarchyAdapter(Shape.class, new ShapeTypeAdapter());
+ Gson gson = builder.create();
+
+ String json = gson.toJson(shapes);
+
+ assertEquals("[" +
+ "{" +
+ "\"radius\":4.0," +
+ "\"area\":50.26548245743669," +
+ "\"type\":\"com.baeldung.gson.polymorphic.TypeAdapterUnitTest$Circle\"" +
+ "},{" +
+ "\"side\":5.0," +
+ "\"area\":25.0," +
+ "\"type\":\"com.baeldung.gson.polymorphic.TypeAdapterUnitTest$Square\"" +
+ "}]", json);
+ }
+
+
+ @Test
+ void testDeserializeWrapper() {
+ List shapes = Arrays.asList(
+ new Circle(4d),
+ new Square(5d)
+ );
+
+ GsonBuilder builder = new GsonBuilder();
+ builder.registerTypeHierarchyAdapter(Shape.class, new ShapeTypeAdapter());
+ Gson gson = builder.create();
+
+ String json = gson.toJson(shapes);
+
+ Type collectionType = new TypeToken>(){}.getType();
+ List result = gson.fromJson(json, collectionType);
+
+ assertEquals(shapes, result);
+ }
+
+ private static class Square implements Shape {
+ private final double side;
+ private final double area;
+
+ public Square(double side) {
+ this.side = side;
+ this.area = side * side;
+ }
+
+ @Override
+ public double getArea() {
+ return area;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Square square = (Square) o;
+ return Double.compare(square.side, side) == 0 && Double.compare(square.area, area) == 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(side, area);
+ }
+ }
+
+ private static class Circle implements Shape {
+ private final double radius;
+
+ private final double area;
+
+ public Circle(double radius) {
+ this.radius = radius;
+ this.area = Math.PI * radius * radius;
+ }
+
+ @Override
+ public double getArea() {
+ return area;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Circle circle = (Circle) o;
+ return Double.compare(circle.radius, radius) == 0 && Double.compare(circle.area, area) == 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(radius, area);
+ }
+ }
+}
diff --git a/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/TypeFieldUnitTest.java b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/TypeFieldUnitTest.java
new file mode 100644
index 0000000000..e6917b2065
--- /dev/null
+++ b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/TypeFieldUnitTest.java
@@ -0,0 +1,67 @@
+package com.baeldung.gson.polymorphic;
+
+import com.google.gson.Gson;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class TypeFieldUnitTest {
+ @Test
+ void testSerialize() {
+ List shapes = Arrays.asList(
+ new Circle(4d),
+ new Square(5d)
+ );
+
+ Gson gson = new Gson();
+ String json = gson.toJson(shapes);
+
+ assertEquals("[" +
+ "{" +
+ "\"type\":\"circle\"," +
+ "\"radius\":4.0," +
+ "\"area\":50.26548245743669" +
+ "},{" +
+ "\"type\":\"square\"," +
+ "\"side\":5.0," +
+ "\"area\":25.0" +
+ "}]", json);
+ }
+
+ private static class Square implements Shape {
+ private final String type = "square";
+ private final double side;
+ private final double area;
+
+ public Square(double side) {
+ this.side = side;
+ this.area = side * side;
+ }
+
+ @Override
+ public double getArea() {
+ return area;
+ }
+ }
+
+ private static class Circle implements Shape {
+ private final String type = "circle";
+ private final double radius;
+
+ private final double area;
+
+ public Circle(double radius) {
+ this.radius = radius;
+ this.area = Math.PI * radius * radius;
+ }
+
+ @Override
+ public double getArea() {
+ return area;
+ }
+ }
+
+}
diff --git a/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/WrapperUnitTest.java b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/WrapperUnitTest.java
new file mode 100644
index 0000000000..841f9c64d5
--- /dev/null
+++ b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/WrapperUnitTest.java
@@ -0,0 +1,148 @@
+package com.baeldung.gson.polymorphic;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import org.junit.jupiter.api.Test;
+
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class WrapperUnitTest {
+ @Test
+ void testSerializeWrapper() {
+ List shapes = Arrays.asList(
+ new Wrapper(new Circle(4d)),
+ new Wrapper(new Square(5d))
+ );
+
+ Gson gson = new Gson();
+ String json = gson.toJson(shapes);
+
+ assertEquals("[" +
+ "{" +
+ "\"circle\":{" +
+ "\"radius\":4.0," +
+ "\"area\":50.26548245743669" +
+ "}" +
+ "},{" +
+ "\"square\":{" +
+ "\"side\":5.0," +
+ "\"area\":25.0" +
+ "}" +
+ "}]", json);
+ }
+
+ @Test
+ void testDeserializeWrapper() {
+ List shapes = Arrays.asList(
+ new Wrapper(new Circle(4d)),
+ new Wrapper(new Square(5d))
+ );
+
+ Gson gson = new Gson();
+ String json = gson.toJson(shapes);
+
+ Type collectionType = new TypeToken>(){}.getType();
+ List result = gson.fromJson(json, collectionType);
+
+ assertEquals(shapes, result);
+ }
+
+ private static class Square implements Shape {
+ private final double side;
+ private final double area;
+
+ public Square(double side) {
+ this.side = side;
+ this.area = side * side;
+ }
+
+ @Override
+ public double getArea() {
+ return area;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Square square = (Square) o;
+ return Double.compare(square.side, side) == 0 && Double.compare(square.area, area) == 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(side, area);
+ }
+ }
+
+ private static class Circle implements Shape {
+ private final double radius;
+
+ private final double area;
+
+ public Circle(double radius) {
+ this.radius = radius;
+ this.area = Math.PI * radius * radius;
+ }
+
+ @Override
+ public double getArea() {
+ return area;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Circle circle = (Circle) o;
+ return Double.compare(circle.radius, radius) == 0 && Double.compare(circle.area, area) == 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(radius, area);
+ }
+ }
+
+ private static class Wrapper {
+ private final Circle circle;
+ private final Square square;
+
+ public Wrapper(Circle circle) {
+ this.circle = circle;
+ this.square = null;
+ }
+
+ public Wrapper(Square square) {
+ this.square = square;
+ this.circle = null;
+ }
+
+ public Circle getCircle() {
+ return circle;
+ }
+
+ public Square getSquare() {
+ return square;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Wrapper wrapper = (Wrapper) o;
+ return Objects.equals(circle, wrapper.circle) && Objects.equals(square, wrapper.square);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(circle, square);
+ }
+ }
+
+}
diff --git a/libraries-apache-commons-2/pom.xml b/libraries-apache-commons-2/pom.xml
index c555b83273..0f00bf5d84 100644
--- a/libraries-apache-commons-2/pom.xml
+++ b/libraries-apache-commons-2/pom.xml
@@ -44,15 +44,27 @@
${mockftpserver.version}
test
+
+ org.tukaani
+ xz
+ ${xz.version}
+
+
+ com.github.luben
+ zstd-jni
+ ${zstd-jni.version}
+
- 1.23.0
+ 1.26.1
1.10.13
2.9.0
1.10.0
3.6
2.7.1
+ 1.9
+ 1.5.5-11
\ No newline at end of file
diff --git a/libraries-apache-commons-2/src/main/java/com/baeldung/commons/compress/CompressUtils.java b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/compress/CompressUtils.java
new file mode 100644
index 0000000000..796b3fd22b
--- /dev/null
+++ b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/compress/CompressUtils.java
@@ -0,0 +1,119 @@
+package com.baeldung.commons.compress;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.zip.Deflater;
+import java.util.zip.ZipEntry;
+
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.ArchiveException;
+import org.apache.commons.compress.archivers.ArchiveInputStream;
+import org.apache.commons.compress.archivers.ArchiveOutputStream;
+import org.apache.commons.compress.archivers.ArchiveStreamFactory;
+import org.apache.commons.compress.archivers.examples.Archiver;
+import org.apache.commons.compress.archivers.examples.Expander;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
+import org.apache.commons.compress.compressors.CompressorException;
+import org.apache.commons.compress.compressors.CompressorInputStream;
+import org.apache.commons.compress.compressors.CompressorOutputStream;
+import org.apache.commons.compress.compressors.CompressorStreamFactory;
+import org.apache.commons.compress.utils.FileNameUtils;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOUtils;
+
+public class CompressUtils {
+
+ private CompressUtils() {
+ }
+
+ public static void archive(Path directory, Path destination) throws IOException, ArchiveException {
+ String format = FileNameUtils.getExtension(destination);
+ new Archiver().create(format, destination, directory);
+ }
+
+ public static void archiveAndCompress(String directory, Path destination) throws IOException, ArchiveException, CompressorException {
+ archiveAndCompress(Paths.get(directory), destination);
+ }
+
+ public static void archiveAndCompress(Path directory, Path destination) throws IOException, ArchiveException, CompressorException {
+ String compressionFormat = FileNameUtils.getExtension(destination);
+ String archiveFormat = FilenameUtils.getExtension(destination.getFileName()
+ .toString()
+ .replace("." + compressionFormat, ""));
+
+ try (OutputStream archive = Files.newOutputStream(destination);
+ BufferedOutputStream archiveBuffer = new BufferedOutputStream(archive);
+ CompressorOutputStream compressor = new CompressorStreamFactory().createCompressorOutputStream(compressionFormat, archiveBuffer);
+ ArchiveOutputStream> archiver = new ArchiveStreamFactory().createArchiveOutputStream(archiveFormat, compressor)) {
+ new Archiver().create(archiver, directory);
+ }
+ }
+
+ public static void decompress(Path file, Path destination) throws IOException, ArchiveException, CompressorException {
+ decompress(Files.newInputStream(file), destination);
+ }
+
+ public static void decompress(InputStream file, Path destination) throws IOException, ArchiveException, CompressorException {
+ try (InputStream in = file;
+ BufferedInputStream inputBuffer = new BufferedInputStream(in);
+ OutputStream out = Files.newOutputStream(destination);
+ CompressorInputStream decompressor = new CompressorStreamFactory().createCompressorInputStream(inputBuffer)) {
+ IOUtils.copy(decompressor, out);
+ }
+ }
+
+ public static void extract(Path archive, Path destination) throws IOException, ArchiveException, CompressorException {
+ new Expander().expand(archive, destination);
+ }
+
+ public static void compressFile(Path file, Path destination) throws IOException, CompressorException {
+ String format = FileNameUtils.getExtension(destination);
+
+ try (OutputStream out = Files.newOutputStream(destination);
+ BufferedOutputStream buffer = new BufferedOutputStream(out);
+ CompressorOutputStream compressor = new CompressorStreamFactory().createCompressorOutputStream(format, buffer)) {
+ IOUtils.copy(Files.newInputStream(file), compressor);
+ }
+ }
+
+ public static void zip(Path file, Path destination) throws IOException {
+ try (InputStream input = Files.newInputStream(file);
+ OutputStream output = Files.newOutputStream(destination);
+ ZipArchiveOutputStream archive = new ZipArchiveOutputStream(output)) {
+ archive.setLevel(Deflater.BEST_COMPRESSION);
+ archive.setMethod(ZipEntry.DEFLATED);
+
+ archive.putArchiveEntry(new ZipArchiveEntry(file.getFileName()
+ .toString()));
+ IOUtils.copy(input, archive);
+ archive.closeArchiveEntry();
+ }
+ }
+
+ public static void extractOne(Path archivePath, String fileName, Path destinationDirectory) throws IOException, ArchiveException {
+ try (InputStream input = Files.newInputStream(archivePath);
+ BufferedInputStream buffer = new BufferedInputStream(input);
+ ArchiveInputStream> archive = new ArchiveStreamFactory().createArchiveInputStream(buffer)) {
+
+ ArchiveEntry entry;
+ while ((entry = archive.getNextEntry()) != null) {
+ if (entry.getName()
+ .equals(fileName)) {
+ Path outFile = destinationDirectory.resolve(fileName);
+ Files.createDirectories(outFile.getParent());
+ try (OutputStream os = Files.newOutputStream(outFile)) {
+ IOUtils.copy(archive, os);
+ }
+ break;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/libraries-apache-commons-2/src/main/java/com/baeldung/commons/convertunicode/UnicodeConverterUtil.java b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/convertunicode/UnicodeConverterUtil.java
index c788f6ee61..997c5b61ff 100644
--- a/libraries-apache-commons-2/src/main/java/com/baeldung/commons/convertunicode/UnicodeConverterUtil.java
+++ b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/convertunicode/UnicodeConverterUtil.java
@@ -1,10 +1,10 @@
package com.baeldung.commons.convertunicode;
-import org.apache.commons.text.StringEscapeUtils;
-
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.apache.commons.text.StringEscapeUtils;
+
public class UnicodeConverterUtil {
public static String decodeWithApacheCommons(String input) {
@@ -15,7 +15,7 @@ public class UnicodeConverterUtil {
Pattern pattern = Pattern.compile("\\\\u[0-9a-fA-F]{4}");
Matcher matcher = pattern.matcher(input);
- StringBuilder decodedString = new StringBuilder();
+ StringBuffer decodedString = new StringBuffer();
while (matcher.find()) {
String unicodeSequence = matcher.group();
diff --git a/libraries-apache-commons-2/src/test/java/com/baeldung/commons/compress/CompressUtilsUnitTest.java b/libraries-apache-commons-2/src/test/java/com/baeldung/commons/compress/CompressUtilsUnitTest.java
new file mode 100644
index 0000000000..9bdaf0dfd4
--- /dev/null
+++ b/libraries-apache-commons-2/src/test/java/com/baeldung/commons/compress/CompressUtilsUnitTest.java
@@ -0,0 +1,135 @@
+package com.baeldung.commons.compress;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.apache.commons.compress.archivers.ArchiveException;
+import org.apache.commons.compress.compressors.CompressorException;
+import org.apache.commons.io.FileUtils;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+class CompressUtilsUnitTest {
+
+ static Path TMP;
+ static String ZIP_FILE = "new.txt.zip";
+ static String COMPRESSED_FILE = "new.txt.gz";
+ static String DECOMPRESSED_FILE = "decompressed-file.txt";
+ static String DECOMPRESSED_ARCHIVE = "decompressed-archive.tar";
+ static String COMPRESSED_ARCHIVE = "archive.tar.gz";
+ static String MODIFIED_ARCHIVE = "modified-archive.tar";
+ static String EXTRACTED_DIR = "extracted";
+
+ @BeforeAll
+ static void setup() throws IOException {
+ TMP = Files.createTempDirectory("compress-test")
+ .toAbsolutePath();
+ }
+
+ @AfterAll
+ static void destroy() throws IOException {
+ FileUtils.deleteDirectory(TMP.toFile());
+ }
+
+ @Test
+ @Order(1)
+ void givenFile_whenCompressing_thenCompressed() throws IOException, CompressorException, URISyntaxException {
+ Path destination = TMP.resolve(COMPRESSED_FILE);
+
+ CompressUtils.compressFile(TestResources.testFile(), destination);
+
+ assertTrue(Files.isRegularFile(destination));
+ }
+
+ @Test
+ @Order(2)
+ void givenFile_whenZipping_thenZipFileCreated() throws IOException, URISyntaxException {
+ Path destination = TMP.resolve(ZIP_FILE);
+
+ CompressUtils.zip(TestResources.testFile(), destination);
+
+ assertTrue(Files.isRegularFile(destination));
+ }
+
+ @Test
+ @Order(3)
+ void givenCompressedArchive_whenDecompressing_thenArchiveAvailable() throws IOException, ArchiveException, CompressorException {
+ Path destination = TMP.resolve(DECOMPRESSED_ARCHIVE);
+
+ CompressUtils.decompress(TestResources.compressedArchive(), destination);
+
+ assertTrue(Files.isRegularFile(destination));
+ }
+
+ @Test
+ @Order(4)
+ void givenCompressedFile_whenDecompressing_thenFileAvailable() throws IOException, ArchiveException, CompressorException {
+ Path destination = TMP.resolve(DECOMPRESSED_FILE);
+
+ CompressUtils.decompress(TMP.resolve(COMPRESSED_FILE), destination);
+
+ assertTrue(Files.isRegularFile(destination));
+ }
+
+ @Test
+ @Order(5)
+ void givenDecompressedArchive_whenUnarchiving_thenFilesAvailable() throws IOException, ArchiveException, CompressorException {
+ Path destination = TMP.resolve(EXTRACTED_DIR);
+
+ CompressUtils.extract(TMP.resolve(DECOMPRESSED_ARCHIVE), destination);
+
+ assertTrue(Files.isDirectory(destination));
+ }
+
+ @Test
+ @Order(6)
+ void givenDirectory_whenArchivingAndCompressing_thenCompressedArchiveAvailable() throws IOException, ArchiveException, CompressorException {
+ Path destination = TMP.resolve(COMPRESSED_ARCHIVE);
+
+ CompressUtils.archiveAndCompress(TMP.resolve(EXTRACTED_DIR), destination);
+
+ assertTrue(Files.isRegularFile(destination));
+ }
+
+ @Test
+ @Order(7)
+ void givenExistingArchive_whenAddingSingleEntry_thenArchiveModified() throws IOException, ArchiveException, CompressorException, URISyntaxException {
+ Path archive = TMP.resolve(DECOMPRESSED_ARCHIVE);
+ Path newArchive = TMP.resolve(MODIFIED_ARCHIVE);
+ Path tmpDir = TMP.resolve(newArchive + "-tmpd");
+
+ Path newEntry = TestResources.testFile();
+
+ CompressUtils.extract(archive, tmpDir);
+ assertTrue(Files.isDirectory(tmpDir));
+
+ Files.copy(newEntry, tmpDir.resolve(newEntry.getFileName()));
+ CompressUtils.archive(tmpDir, newArchive);
+ assertTrue(Files.isRegularFile(newArchive));
+
+ FileUtils.deleteDirectory(tmpDir.toFile());
+ Files.delete(archive);
+ Files.move(newArchive, archive);
+ assertTrue(Files.isRegularFile(archive));
+ }
+
+ @Test
+ @Order(8)
+ void givenExistingArchive_whenExtractingSingleEntry_thenFileExtracted() throws IOException, ArchiveException {
+ Path archive = TMP.resolve(DECOMPRESSED_ARCHIVE);
+ String targetFile = "sub/other.txt";
+
+ CompressUtils.extractOne(archive, targetFile, TMP);
+
+ assertTrue(Files.isRegularFile(TMP.resolve(targetFile)));
+ }
+}
diff --git a/libraries-apache-commons-2/src/test/java/com/baeldung/commons/compress/TestResources.java b/libraries-apache-commons-2/src/test/java/com/baeldung/commons/compress/TestResources.java
new file mode 100644
index 0000000000..6e1f4129cf
--- /dev/null
+++ b/libraries-apache-commons-2/src/test/java/com/baeldung/commons/compress/TestResources.java
@@ -0,0 +1,25 @@
+package com.baeldung.commons.compress;
+
+import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public interface TestResources {
+
+ String DIR = "/compress/";
+
+ static InputStream compressedArchive() {
+ return TestResources.class.getResourceAsStream(DIR + CompressUtilsUnitTest.COMPRESSED_ARCHIVE);
+ }
+
+ static Path testFile() throws URISyntaxException {
+ URL resource = TestResources.class.getResource(DIR + "new.txt");
+ if (resource == null) {
+ throw new IllegalArgumentException("file not found!");
+ } else {
+ return Paths.get(resource.toURI());
+ }
+ }
+}
\ No newline at end of file
diff --git a/libraries-apache-commons-2/src/test/resources/compress/archive.tar.gz b/libraries-apache-commons-2/src/test/resources/compress/archive.tar.gz
new file mode 100644
index 0000000000..cdb6fd3fd4
Binary files /dev/null and b/libraries-apache-commons-2/src/test/resources/compress/archive.tar.gz differ
diff --git a/libraries-apache-commons-2/src/test/resources/compress/new.txt b/libraries-apache-commons-2/src/test/resources/compress/new.txt
new file mode 100644
index 0000000000..f207b5eb40
--- /dev/null
+++ b/libraries-apache-commons-2/src/test/resources/compress/new.txt
@@ -0,0 +1,2 @@
+lorem ipsum
+dolor sit amet
diff --git a/libraries-http-2/pom.xml b/libraries-http-2/pom.xml
index 934e0d2900..fa6b65f79f 100644
--- a/libraries-http-2/pom.xml
+++ b/libraries-http-2/pom.xml
@@ -85,7 +85,7 @@
org.mockito
mockito-inline
- ${mockito.version}
+ ${mockito-inline.version}
test
@@ -120,6 +120,7 @@
1.0.3
3.6.0
1.49
+ 5.2.0
\ No newline at end of file
diff --git a/maven-modules/maven-plugins/jaxws/pom.xml b/maven-modules/maven-plugins/jaxws/pom.xml
index f17d70c182..a30fca8c87 100644
--- a/maven-modules/maven-plugins/jaxws/pom.xml
+++ b/maven-modules/maven-plugins/jaxws/pom.xml
@@ -36,7 +36,7 @@
com.sun.xml.ws
jaxws-ri
- 2.3.0
+ ${jaxws.version}
pom
@@ -46,7 +46,7 @@
com.sun.xml.ws
jaxws-maven-plugin
- 4.0.1
+ ${jaxws.version}
@@ -73,4 +73,8 @@
+
+ 4.0.2
+
+
\ No newline at end of file
diff --git a/messaging-modules/spring-jms/pom.xml b/messaging-modules/spring-jms/pom.xml
index aad416433d..0df1e9fff2 100644
--- a/messaging-modules/spring-jms/pom.xml
+++ b/messaging-modules/spring-jms/pom.xml
@@ -44,7 +44,7 @@
org.mockito
mockito-core
- ${mockito-core.version}
+ ${mockito.version}
test
@@ -83,7 +83,6 @@
5.14.1
1.5.10.RELEASE
3.3.2
- 4.6.1
5.16.5
1.17.3
5.10.1
diff --git a/microservices-modules/msf4j/pom.xml b/microservices-modules/msf4j/pom.xml
index 642795e5fe..6d6315903b 100644
--- a/microservices-modules/msf4j/pom.xml
+++ b/microservices-modules/msf4j/pom.xml
@@ -14,6 +14,13 @@
1.0.0-SNAPSHOT
+
+
+ wso2-https
+ https://maven.wso2.org/nexus/content/groups/wso2-public/
+
+
+
@@ -40,7 +47,7 @@
com.baeldung.msf4j.msf4jintro.Application
- 2.6.3
+ 2.8.11
\ No newline at end of file
diff --git a/patterns-modules/design-patterns-creational-2/pom.xml b/patterns-modules/design-patterns-creational-2/pom.xml
index 27c83c9eb7..30e052e6db 100644
--- a/patterns-modules/design-patterns-creational-2/pom.xml
+++ b/patterns-modules/design-patterns-creational-2/pom.xml
@@ -16,9 +16,13 @@
org.mockito
mockito-inline
- ${mockito.version}
+ ${mockito-inline.version}
test
+
+ 5.2.0
+
+
\ No newline at end of file
diff --git a/persistence-modules/hibernate-annotations-2/README.md b/persistence-modules/hibernate-annotations-2/README.md
new file mode 100644
index 0000000000..9da9b37245
--- /dev/null
+++ b/persistence-modules/hibernate-annotations-2/README.md
@@ -0,0 +1,6 @@
+## Hibernate Annotations
+
+This module contains articles about Annotations used in Hibernate.
+
+### Relevant Articles:
+- [@Subselect Annotation in Hibernate](https://www.baeldung.com/hibernate-subselect)
diff --git a/persistence-modules/hibernate-annotations-2/pom.xml b/persistence-modules/hibernate-annotations-2/pom.xml
new file mode 100644
index 0000000000..046fbae619
--- /dev/null
+++ b/persistence-modules/hibernate-annotations-2/pom.xml
@@ -0,0 +1,109 @@
+
+
+ 4.0.0
+
+ hibernate-annotations-2
+ 0.1-SNAPSHOT
+ hibernate-annotations-2
+ jar
+ Hibernate annotations module, part 2
+
+
+ com.baeldung
+ persistence-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+
+ org.springframework
+ spring-context
+ ${org.springframework.version}
+
+
+ org.springframework.data
+ spring-data-jpa
+ ${org.springframework.data.version}
+
+
+ org.hibernate.orm
+ hibernate-core
+ ${hibernate-core.version}
+
+
+ org.hsqldb
+ hsqldb
+ ${hsqldb.version}
+
+
+ com.h2database
+ h2
+ ${h2.version}
+
+
+ org.apache.commons
+ commons-lang3
+ ${commons-lang3.version}
+
+
+ org.hibernate.orm
+ hibernate-testing
+ ${hibernate-core.version}
+
+
+ org.hibernate.orm
+ hibernate-spatial
+ ${hibernate-core.version}
+
+
+ org.apache.tomcat
+ tomcat-dbcp
+ ${tomcat-dbcp.version}
+
+
+
+
+ com.google.guava
+ guava
+ ${guava.version}
+
+
+
+ org.springframework
+ spring-test
+ ${org.springframework.version}
+ test
+
+
+ io.hypersistence
+ hypersistence-utils-hibernate-60
+ ${hypersistance-utils-hibernate-60.version}
+
+
+ org.liquibase
+ liquibase-core
+ ${liquibase-core.version}
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+
+
+
+ 6.0.6
+ 3.0.3
+ 6.4.2.Final
+ true
+ 9.0.0.M26
+ 3.3.1
+ 1.18.30
+ 4.24.0
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/HibernateAnnotationUtil.java b/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/HibernateAnnotationUtil.java
new file mode 100644
index 0000000000..74046854e7
--- /dev/null
+++ b/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/HibernateAnnotationUtil.java
@@ -0,0 +1,50 @@
+package com.baeldung.hibernate;
+
+import com.baeldung.hibernate.subselect.RuntimeConfiguration;
+import java.util.HashMap;
+import java.util.Map;
+import org.hibernate.SessionFactory;
+import org.hibernate.boot.Metadata;
+import org.hibernate.boot.MetadataSources;
+import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
+import org.hibernate.cfg.Environment;
+import org.hibernate.service.ServiceRegistry;
+
+public class HibernateAnnotationUtil {
+
+ private static final SessionFactory SESSION_FACTORY = buildSessionFactory();
+
+ /**
+ * Utility class
+ */
+ private HibernateAnnotationUtil() {
+ }
+
+ public static SessionFactory getSessionFactory() {
+ return SESSION_FACTORY;
+ }
+
+ private static SessionFactory buildSessionFactory() {
+ ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
+ .applySettings(dbSettings())
+ .build();
+
+ Metadata metadata = new MetadataSources(serviceRegistry)
+ .addAnnotatedClass(RuntimeConfiguration.class)
+ .buildMetadata();
+
+ return metadata.buildSessionFactory();
+ }
+
+ private static Map dbSettings() {
+ Map dbSettings = new HashMap<>();
+ dbSettings.put(Environment.URL, "jdbc:h2:mem:spring_hibernate_one_to_many");
+ dbSettings.put(Environment.USER, "sa");
+ dbSettings.put(Environment.PASS, "");
+ dbSettings.put(Environment.DRIVER, "org.h2.Driver");
+ dbSettings.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread");
+ dbSettings.put(Environment.SHOW_SQL, "true");
+ dbSettings.put(Environment.HBM2DDL_AUTO, "create");
+ return dbSettings;
+ }
+}
diff --git a/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/PersistenceConfig.java b/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/PersistenceConfig.java
new file mode 100644
index 0000000000..c34b77282c
--- /dev/null
+++ b/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/PersistenceConfig.java
@@ -0,0 +1,67 @@
+package com.baeldung.hibernate;
+
+import com.google.common.base.Preconditions;
+import java.util.Properties;
+import javax.sql.DataSource;
+import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
+import org.springframework.orm.hibernate5.HibernateTransactionManager;
+import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+@Configuration
+@EnableTransactionManagement
+@PropertySource({ "classpath:persistence-h2.properties" })
+public class PersistenceConfig {
+
+ @Autowired
+ private Environment env;
+
+ @Bean
+ public LocalSessionFactoryBean sessionFactory() {
+ final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
+ sessionFactory.setDataSource(dataSource());
+ sessionFactory.setPackagesToScan(new String[] { "com.baeldung.hibernate" });
+ sessionFactory.setHibernateProperties(hibernateProperties());
+ return sessionFactory;
+ }
+
+ @Bean
+ public DataSource dataSource() {
+ final BasicDataSource dataSource = new BasicDataSource();
+ dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
+ dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
+ dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
+ dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));
+
+ return dataSource;
+ }
+
+ @Bean
+ public PlatformTransactionManager hibernateTransactionManager() {
+ final HibernateTransactionManager transactionManager = new HibernateTransactionManager();
+ transactionManager.setSessionFactory(sessionFactory().getObject());
+ return transactionManager;
+ }
+
+ @Bean
+ public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
+ return new PersistenceExceptionTranslationPostProcessor();
+ }
+
+ private final Properties hibernateProperties() {
+ final Properties hibernateProperties = new Properties();
+ hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
+ hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
+ hibernateProperties.setProperty("hibernate.show_sql", "false");
+ return hibernateProperties;
+ }
+
+}
\ No newline at end of file
diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/subselect/RuntimeConfiguration.java b/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/subselect/RuntimeConfiguration.java
similarity index 100%
rename from persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/subselect/RuntimeConfiguration.java
rename to persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/subselect/RuntimeConfiguration.java
diff --git a/persistence-modules/hibernate-annotations/src/main/resources/migrations/V1__init.xml b/persistence-modules/hibernate-annotations-2/src/main/resources/migrations/V1__init.xml
similarity index 100%
rename from persistence-modules/hibernate-annotations/src/main/resources/migrations/V1__init.xml
rename to persistence-modules/hibernate-annotations-2/src/main/resources/migrations/V1__init.xml
diff --git a/persistence-modules/hibernate-annotations/src/main/resources/migrations/master.xml b/persistence-modules/hibernate-annotations-2/src/main/resources/migrations/master.xml
similarity index 100%
rename from persistence-modules/hibernate-annotations/src/main/resources/migrations/master.xml
rename to persistence-modules/hibernate-annotations-2/src/main/resources/migrations/master.xml
diff --git a/persistence-modules/hibernate-annotations-2/src/main/resources/persistence-h2.properties b/persistence-modules/hibernate-annotations-2/src/main/resources/persistence-h2.properties
new file mode 100644
index 0000000000..4bc5e98f56
--- /dev/null
+++ b/persistence-modules/hibernate-annotations-2/src/main/resources/persistence-h2.properties
@@ -0,0 +1,15 @@
+# jdbc.X
+jdbc.driverClassName=org.h2.Driver
+jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
+jdbc.eventGeneratedId=sa
+jdbc.user=sa
+jdbc.pass=
+
+# hibernate.X
+hibernate.dialect=org.hibernate.dialect.H2Dialect
+hibernate.show_sql=false
+hibernate.hbm2ddl.auto=create-drop
+hibernate.cache.use_second_level_cache=true
+hibernate.cache.use_query_cache=true
+hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
+
diff --git a/persistence-modules/hibernate-annotations-2/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/hibernate-annotations-2/src/test/java/com/baeldung/SpringContextTest.java
new file mode 100644
index 0000000000..2db3ec53d5
--- /dev/null
+++ b/persistence-modules/hibernate-annotations-2/src/test/java/com/baeldung/SpringContextTest.java
@@ -0,0 +1,18 @@
+package com.baeldung;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+import com.baeldung.hibernate.PersistenceConfig;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class)
+public class SpringContextTest {
+
+ @Test
+ public void whenSpringContextIsBootstrapped_thenNoExceptions() {
+ }
+}
diff --git a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/subselect/SubselectIntegrationTest.java b/persistence-modules/hibernate-annotations-2/src/test/java/com/baeldung/hibernate/subselect/SubselectIntegrationTest.java
similarity index 96%
rename from persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/subselect/SubselectIntegrationTest.java
rename to persistence-modules/hibernate-annotations-2/src/test/java/com/baeldung/hibernate/subselect/SubselectIntegrationTest.java
index 074468ca37..fee67240e4 100644
--- a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/subselect/SubselectIntegrationTest.java
+++ b/persistence-modules/hibernate-annotations-2/src/test/java/com/baeldung/hibernate/subselect/SubselectIntegrationTest.java
@@ -1,6 +1,6 @@
package com.baeldung.hibernate.subselect;
-import com.baeldung.hibernate.oneToMany.config.HibernateAnnotationUtil;
+import com.baeldung.hibernate.HibernateAnnotationUtil;
import jakarta.persistence.criteria.Root;
import liquibase.Contexts;
import liquibase.LabelExpression;
diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java
index 0bf03e3fee..99410e1f76 100644
--- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java
+++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java
@@ -4,7 +4,6 @@ import com.baeldung.hibernate.oneToMany.model.Cart;
import com.baeldung.hibernate.oneToMany.model.CartOIO;
import com.baeldung.hibernate.oneToMany.model.Item;
import com.baeldung.hibernate.oneToMany.model.ItemOIO;
-import com.baeldung.hibernate.subselect.RuntimeConfiguration;
import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
@@ -39,7 +38,6 @@ public class HibernateAnnotationUtil {
.addAnnotatedClass(CartOIO.class)
.addAnnotatedClass(Item.class)
.addAnnotatedClass(ItemOIO.class)
- .addAnnotatedClass(RuntimeConfiguration.class)
.buildMetadata();
return metadata.buildSessionFactory();
diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/DefaultCatalog.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/DefaultCatalog.java
new file mode 100644
index 0000000000..a730e9bfc6
--- /dev/null
+++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/DefaultCatalog.java
@@ -0,0 +1,56 @@
+/*
+ * This file is generated by jOOQ.
+ */
+package com.baeldung.jooq.jointables;
+
+
+import com.baeldung.jooq.jointables.public_.Public;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.jooq.Constants;
+import org.jooq.Schema;
+import org.jooq.impl.CatalogImpl;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" })
+public class DefaultCatalog extends CatalogImpl {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The reference instance of DEFAULT_CATALOG
+ */
+ public static final DefaultCatalog DEFAULT_CATALOG = new DefaultCatalog();
+
+ /**
+ * The schema public.
+ */
+ public final Public PUBLIC = Public.PUBLIC;
+
+ /**
+ * No further instances allowed
+ */
+ private DefaultCatalog() {
+ super("");
+ }
+
+ @Override
+ public final List getSchemas() {
+ return Arrays.asList(
+ Public.PUBLIC
+ );
+ }
+
+ /**
+ * A reference to the 3.19 minor release of the code generator. If this
+ * doesn't compile, it's because the runtime library uses an older minor
+ * release, namely: 3.19. You can turn off the generation of this reference
+ * by specifying /configuration/generator/generate/jooqVersionReference
+ */
+ private static final String REQUIRE_RUNTIME_JOOQ_VERSION = Constants.VERSION_3_19;
+}
diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/JoinTables.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/JoinTables.java
new file mode 100644
index 0000000000..2c67ef2ad3
--- /dev/null
+++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/JoinTables.java
@@ -0,0 +1,75 @@
+package com.baeldung.jooq.jointables;
+
+import static org.jooq.impl.DSL.field;
+
+import org.jooq.DSLContext;
+import org.jooq.Record;
+import org.jooq.Result;
+import org.jooq.SelectJoinStep;
+
+import com.baeldung.jooq.jointables.public_.Tables;
+
+public class JoinTables {
+
+ public static Result usingJoinMethod(DSLContext context) {
+ SelectJoinStep query = context.select()
+ .from(Tables.BOOK)
+ .join(Tables.BOOKAUTHOR)
+ .on(field(Tables.BOOK.AUTHOR_ID).eq(field(Tables.BOOKAUTHOR.ID)));
+ return query.fetch();
+ }
+
+ public static Result usingMultipleJoinMethod(DSLContext context) {
+ SelectJoinStep query = context.select()
+ .from(Tables.BOOK)
+ .join(Tables.BOOKAUTHOR)
+ .on(field(Tables.BOOK.AUTHOR_ID).eq(field(Tables.BOOKAUTHOR.ID)))
+ .join(Tables.STORE)
+ .on(field(Tables.BOOK.STORE_ID).eq(field(Tables.STORE.ID)));
+ return query.fetch();
+ }
+
+ public static Result usingLeftOuterJoinMethod(DSLContext context) {
+ SelectJoinStep query = context.select()
+ .from(Tables.BOOK)
+ .leftOuterJoin(Tables.BOOKAUTHOR)
+ .on(field(Tables.BOOK.AUTHOR_ID).eq(field(Tables.BOOKAUTHOR.ID)));
+ return query.fetch();
+ }
+
+ public static Result usingRightOuterJoinMethod(DSLContext context) {
+ SelectJoinStep query = context.select()
+ .from(Tables.BOOK)
+ .rightOuterJoin(Tables.BOOKAUTHOR)
+ .on(field(Tables.BOOK.AUTHOR_ID).eq(field(Tables.BOOKAUTHOR.ID)));
+ return query.fetch();
+ }
+
+ public static Result usingFullOuterJoinMethod(DSLContext context) {
+ SelectJoinStep query = context.select()
+ .from(Tables.BOOK)
+ .fullOuterJoin(Tables.BOOKAUTHOR)
+ .on(field(Tables.BOOK.AUTHOR_ID).eq(field(Tables.BOOKAUTHOR.ID)));
+ return query.fetch();
+ }
+
+ public static Result usingNaturalJoinMethod(DSLContext context) {
+ SelectJoinStep query = context.select()
+ .from(Tables.BOOK)
+ .naturalJoin(Tables.BOOKAUTHOR);
+ return query.fetch();
+ }
+
+ public static Result usingCrossJoinMethod(DSLContext context) {
+ SelectJoinStep query = context.select()
+ .from(Tables.STORE)
+ .crossJoin(Tables.BOOK);
+ return query.fetch();
+ }
+
+ public static void printResult(Result result) {
+ for (Record record : result) {
+ System.out.println(record);
+ }
+ }
+}
diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Keys.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Keys.java
new file mode 100644
index 0000000000..86c1939891
--- /dev/null
+++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Keys.java
@@ -0,0 +1,34 @@
+/*
+ * This file is generated by jOOQ.
+ */
+package com.baeldung.jooq.jointables.public_;
+
+
+import com.baeldung.jooq.jointables.public_.tables.Book;
+import com.baeldung.jooq.jointables.public_.tables.Bookauthor;
+import com.baeldung.jooq.jointables.public_.tables.Store;
+import com.baeldung.jooq.jointables.public_.tables.records.BookRecord;
+import com.baeldung.jooq.jointables.public_.tables.records.BookauthorRecord;
+import com.baeldung.jooq.jointables.public_.tables.records.StoreRecord;
+
+import org.jooq.TableField;
+import org.jooq.UniqueKey;
+import org.jooq.impl.DSL;
+import org.jooq.impl.Internal;
+
+
+/**
+ * A class modelling foreign key relationships and constraints of tables in
+ * public.
+ */
+@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" })
+public class Keys {
+
+ // -------------------------------------------------------------------------
+ // UNIQUE and PRIMARY KEY definitions
+ // -------------------------------------------------------------------------
+
+ public static final UniqueKey BOOK_PKEY = Internal.createUniqueKey(Book.BOOK, DSL.name("Book_pkey"), new TableField[] { Book.BOOK.ID }, true);
+ public static final UniqueKey AUTHOR_PKEY = Internal.createUniqueKey(Bookauthor.BOOKAUTHOR, DSL.name("Author_pkey"), new TableField[] { Bookauthor.BOOKAUTHOR.ID }, true);
+ public static final UniqueKey STORE_PKEY = Internal.createUniqueKey(Store.STORE, DSL.name("Store_pkey"), new TableField[] { Store.STORE.ID }, true);
+}
diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Public.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Public.java
new file mode 100644
index 0000000000..1b2e8dda87
--- /dev/null
+++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Public.java
@@ -0,0 +1,69 @@
+/*
+ * This file is generated by jOOQ.
+ */
+package com.baeldung.jooq.jointables.public_;
+
+
+import com.baeldung.jooq.jointables.DefaultCatalog;
+import com.baeldung.jooq.jointables.public_.tables.Book;
+import com.baeldung.jooq.jointables.public_.tables.Bookauthor;
+import com.baeldung.jooq.jointables.public_.tables.Store;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.jooq.Catalog;
+import org.jooq.Table;
+import org.jooq.impl.SchemaImpl;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" })
+public class Public extends SchemaImpl {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The reference instance of public
+ */
+ public static final Public PUBLIC = new Public();
+
+ /**
+ * The table public.Book.
+ */
+ public final Book BOOK = Book.BOOK;
+
+ /**
+ * The table public.BookAuthor.
+ */
+ public final Bookauthor BOOKAUTHOR = Bookauthor.BOOKAUTHOR;
+
+ /**
+ * The table public.Store.
+ */
+ public final Store STORE = Store.STORE;
+
+ /**
+ * No further instances allowed
+ */
+ private Public() {
+ super("public", null);
+ }
+
+
+ @Override
+ public Catalog getCatalog() {
+ return DefaultCatalog.DEFAULT_CATALOG;
+ }
+
+ @Override
+ public final List> getTables() {
+ return Arrays.asList(
+ Book.BOOK,
+ Bookauthor.BOOKAUTHOR,
+ Store.STORE
+ );
+ }
+}
diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Tables.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Tables.java
new file mode 100644
index 0000000000..789c131a25
--- /dev/null
+++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Tables.java
@@ -0,0 +1,32 @@
+/*
+ * This file is generated by jOOQ.
+ */
+package com.baeldung.jooq.jointables.public_;
+
+
+import com.baeldung.jooq.jointables.public_.tables.Book;
+import com.baeldung.jooq.jointables.public_.tables.Bookauthor;
+import com.baeldung.jooq.jointables.public_.tables.Store;
+
+
+/**
+ * Convenience access to all tables in public.
+ */
+@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" })
+public class Tables {
+
+ /**
+ * The table public.Book.
+ */
+ public static final Book BOOK = Book.BOOK;
+
+ /**
+ * The table public.BookAuthor.
+ */
+ public static final Bookauthor BOOKAUTHOR = Bookauthor.BOOKAUTHOR;
+
+ /**
+ * The table public.Store.
+ */
+ public static final Store STORE = Store.STORE;
+}
diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Book.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Book.java
new file mode 100644
index 0000000000..4e21648cbd
--- /dev/null
+++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Book.java
@@ -0,0 +1,238 @@
+/*
+ * This file is generated by jOOQ.
+ */
+package com.baeldung.jooq.jointables.public_.tables;
+
+
+import com.baeldung.jooq.jointables.public_.Keys;
+import com.baeldung.jooq.jointables.public_.Public;
+import com.baeldung.jooq.jointables.public_.tables.records.BookRecord;
+
+import java.util.Collection;
+
+import org.jooq.Condition;
+import org.jooq.Field;
+import org.jooq.Name;
+import org.jooq.PlainSQL;
+import org.jooq.QueryPart;
+import org.jooq.SQL;
+import org.jooq.Schema;
+import org.jooq.Select;
+import org.jooq.Stringly;
+import org.jooq.Table;
+import org.jooq.TableField;
+import org.jooq.TableOptions;
+import org.jooq.UniqueKey;
+import org.jooq.impl.DSL;
+import org.jooq.impl.SQLDataType;
+import org.jooq.impl.TableImpl;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" })
+public class Book extends TableImpl {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The reference instance of public.Book
+ */
+ public static final Book BOOK = new Book();
+
+ /**
+ * The class holding records for this type
+ */
+ @Override
+ public Class getRecordType() {
+ return BookRecord.class;
+ }
+
+ /**
+ * The column public.Book.id.
+ */
+ public final TableField ID = createField(DSL.name("id"), SQLDataType.INTEGER.nullable(false), this, "");
+
+ /**
+ * The column public.Book.author_id.
+ */
+ public final TableField AUTHOR_ID = createField(DSL.name("author_id"), SQLDataType.INTEGER, this, "");
+
+ /**
+ * The column public.Book.title.
+ */
+ public final TableField TITLE = createField(DSL.name("title"), SQLDataType.VARCHAR, this, "");
+
+ /**
+ * The column public.Book.description.
+ */
+ public final TableField DESCRIPTION = createField(DSL.name("description"), SQLDataType.VARCHAR, this, "");
+
+ /**
+ * The column public.Book.store_id.
+ */
+ public final TableField STORE_ID = createField(DSL.name("store_id"), SQLDataType.INTEGER, this, "");
+
+ private Book(Name alias, Table aliased) {
+ this(alias, aliased, (Field>[]) null, null);
+ }
+
+ private Book(Name alias, Table aliased, Field>[] parameters, Condition where) {
+ super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table(), where);
+ }
+
+ /**
+ * Create an aliased public.Book table reference
+ */
+ public Book(String alias) {
+ this(DSL.name(alias), BOOK);
+ }
+
+ /**
+ * Create an aliased public.Book table reference
+ */
+ public Book(Name alias) {
+ this(alias, BOOK);
+ }
+
+ /**
+ * Create a public.Book table reference
+ */
+ public Book() {
+ this(DSL.name("Book"), null);
+ }
+
+ @Override
+ public Schema getSchema() {
+ return aliased() ? null : Public.PUBLIC;
+ }
+
+ @Override
+ public UniqueKey getPrimaryKey() {
+ return Keys.BOOK_PKEY;
+ }
+
+ @Override
+ public Book as(String alias) {
+ return new Book(DSL.name(alias), this);
+ }
+
+ @Override
+ public Book as(Name alias) {
+ return new Book(alias, this);
+ }
+
+ @Override
+ public Book as(Table> alias) {
+ return new Book(alias.getQualifiedName(), this);
+ }
+
+ /**
+ * Rename this table
+ */
+ @Override
+ public Book rename(String name) {
+ return new Book(DSL.name(name), null);
+ }
+
+ /**
+ * Rename this table
+ */
+ @Override
+ public Book rename(Name name) {
+ return new Book(name, null);
+ }
+
+ /**
+ * Rename this table
+ */
+ @Override
+ public Book rename(Table> name) {
+ return new Book(name.getQualifiedName(), null);
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ public Book where(Condition condition) {
+ return new Book(getQualifiedName(), aliased() ? this : null, null, condition);
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ public Book where(Collection extends Condition> conditions) {
+ return where(DSL.and(conditions));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ public Book where(Condition... conditions) {
+ return where(DSL.and(conditions));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ public Book where(Field condition) {
+ return where(DSL.condition(condition));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ @PlainSQL
+ public Book where(SQL condition) {
+ return where(DSL.condition(condition));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ @PlainSQL
+ public Book where(@Stringly.SQL String condition) {
+ return where(DSL.condition(condition));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ @PlainSQL
+ public Book where(@Stringly.SQL String condition, Object... binds) {
+ return where(DSL.condition(condition, binds));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ @PlainSQL
+ public Book where(@Stringly.SQL String condition, QueryPart... parts) {
+ return where(DSL.condition(condition, parts));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ public Book whereExists(Select> select) {
+ return where(DSL.exists(select));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ public Book whereNotExists(Select> select) {
+ return where(DSL.notExists(select));
+ }
+}
diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Bookauthor.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Bookauthor.java
new file mode 100644
index 0000000000..9d828e9add
--- /dev/null
+++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Bookauthor.java
@@ -0,0 +1,228 @@
+/*
+ * This file is generated by jOOQ.
+ */
+package com.baeldung.jooq.jointables.public_.tables;
+
+
+import com.baeldung.jooq.jointables.public_.Keys;
+import com.baeldung.jooq.jointables.public_.Public;
+import com.baeldung.jooq.jointables.public_.tables.records.BookauthorRecord;
+
+import java.util.Collection;
+
+import org.jooq.Condition;
+import org.jooq.Field;
+import org.jooq.Name;
+import org.jooq.PlainSQL;
+import org.jooq.QueryPart;
+import org.jooq.SQL;
+import org.jooq.Schema;
+import org.jooq.Select;
+import org.jooq.Stringly;
+import org.jooq.Table;
+import org.jooq.TableField;
+import org.jooq.TableOptions;
+import org.jooq.UniqueKey;
+import org.jooq.impl.DSL;
+import org.jooq.impl.SQLDataType;
+import org.jooq.impl.TableImpl;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" })
+public class Bookauthor extends TableImpl {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The reference instance of public.BookAuthor
+ */
+ public static final Bookauthor BOOKAUTHOR = new Bookauthor();
+
+ /**
+ * The class holding records for this type
+ */
+ @Override
+ public Class getRecordType() {
+ return BookauthorRecord.class;
+ }
+
+ /**
+ * The column public.BookAuthor.id.
+ */
+ public final TableField ID = createField(DSL.name("id"), SQLDataType.INTEGER.nullable(false), this, "");
+
+ /**
+ * The column public.BookAuthor.name.
+ */
+ public final TableField NAME = createField(DSL.name("name"), SQLDataType.VARCHAR.nullable(false), this, "");
+
+ /**
+ * The column public.BookAuthor.country.
+ */
+ public final TableField COUNTRY = createField(DSL.name("country"), SQLDataType.VARCHAR, this, "");
+
+ private Bookauthor(Name alias, Table aliased) {
+ this(alias, aliased, (Field>[]) null, null);
+ }
+
+ private Bookauthor(Name alias, Table aliased, Field>[] parameters, Condition where) {
+ super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table(), where);
+ }
+
+ /**
+ * Create an aliased public.BookAuthor table reference
+ */
+ public Bookauthor(String alias) {
+ this(DSL.name(alias), BOOKAUTHOR);
+ }
+
+ /**
+ * Create an aliased public.BookAuthor table reference
+ */
+ public Bookauthor(Name alias) {
+ this(alias, BOOKAUTHOR);
+ }
+
+ /**
+ * Create a public.BookAuthor table reference
+ */
+ public Bookauthor() {
+ this(DSL.name("BookAuthor"), null);
+ }
+
+ @Override
+ public Schema getSchema() {
+ return aliased() ? null : Public.PUBLIC;
+ }
+
+ @Override
+ public UniqueKey getPrimaryKey() {
+ return Keys.AUTHOR_PKEY;
+ }
+
+ @Override
+ public Bookauthor as(String alias) {
+ return new Bookauthor(DSL.name(alias), this);
+ }
+
+ @Override
+ public Bookauthor as(Name alias) {
+ return new Bookauthor(alias, this);
+ }
+
+ @Override
+ public Bookauthor as(Table> alias) {
+ return new Bookauthor(alias.getQualifiedName(), this);
+ }
+
+ /**
+ * Rename this table
+ */
+ @Override
+ public Bookauthor rename(String name) {
+ return new Bookauthor(DSL.name(name), null);
+ }
+
+ /**
+ * Rename this table
+ */
+ @Override
+ public Bookauthor rename(Name name) {
+ return new Bookauthor(name, null);
+ }
+
+ /**
+ * Rename this table
+ */
+ @Override
+ public Bookauthor rename(Table> name) {
+ return new Bookauthor(name.getQualifiedName(), null);
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ public Bookauthor where(Condition condition) {
+ return new Bookauthor(getQualifiedName(), aliased() ? this : null, null, condition);
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ public Bookauthor where(Collection extends Condition> conditions) {
+ return where(DSL.and(conditions));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ public Bookauthor where(Condition... conditions) {
+ return where(DSL.and(conditions));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ public Bookauthor where(Field condition) {
+ return where(DSL.condition(condition));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ @PlainSQL
+ public Bookauthor where(SQL condition) {
+ return where(DSL.condition(condition));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ @PlainSQL
+ public Bookauthor where(@Stringly.SQL String condition) {
+ return where(DSL.condition(condition));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ @PlainSQL
+ public Bookauthor where(@Stringly.SQL String condition, Object... binds) {
+ return where(DSL.condition(condition, binds));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ @PlainSQL
+ public Bookauthor where(@Stringly.SQL String condition, QueryPart... parts) {
+ return where(DSL.condition(condition, parts));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ public Bookauthor whereExists(Select> select) {
+ return where(DSL.exists(select));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ public Bookauthor whereNotExists(Select> select) {
+ return where(DSL.notExists(select));
+ }
+}
diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Store.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Store.java
new file mode 100644
index 0000000000..d97f3da21b
--- /dev/null
+++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Store.java
@@ -0,0 +1,223 @@
+/*
+ * This file is generated by jOOQ.
+ */
+package com.baeldung.jooq.jointables.public_.tables;
+
+
+import com.baeldung.jooq.jointables.public_.Keys;
+import com.baeldung.jooq.jointables.public_.Public;
+import com.baeldung.jooq.jointables.public_.tables.records.StoreRecord;
+
+import java.util.Collection;
+
+import org.jooq.Condition;
+import org.jooq.Field;
+import org.jooq.Name;
+import org.jooq.PlainSQL;
+import org.jooq.QueryPart;
+import org.jooq.SQL;
+import org.jooq.Schema;
+import org.jooq.Select;
+import org.jooq.Stringly;
+import org.jooq.Table;
+import org.jooq.TableField;
+import org.jooq.TableOptions;
+import org.jooq.UniqueKey;
+import org.jooq.impl.DSL;
+import org.jooq.impl.SQLDataType;
+import org.jooq.impl.TableImpl;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" })
+public class Store extends TableImpl {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The reference instance of public.Store
+ */
+ public static final Store STORE = new Store();
+
+ /**
+ * The class holding records for this type
+ */
+ @Override
+ public Class getRecordType() {
+ return StoreRecord.class;
+ }
+
+ /**
+ * The column public.Store.id.
+ */
+ public final TableField ID = createField(DSL.name("id"), SQLDataType.INTEGER.nullable(false), this, "");
+
+ /**
+ * The column public.Store.name.
+ */
+ public final TableField NAME = createField(DSL.name("name"), SQLDataType.VARCHAR.nullable(false), this, "");
+
+ private Store(Name alias, Table aliased) {
+ this(alias, aliased, (Field>[]) null, null);
+ }
+
+ private Store(Name alias, Table aliased, Field>[] parameters, Condition where) {
+ super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table(), where);
+ }
+
+ /**
+ * Create an aliased public.Store table reference
+ */
+ public Store(String alias) {
+ this(DSL.name(alias), STORE);
+ }
+
+ /**
+ * Create an aliased public.Store table reference
+ */
+ public Store(Name alias) {
+ this(alias, STORE);
+ }
+
+ /**
+ * Create a public.Store table reference
+ */
+ public Store() {
+ this(DSL.name("Store"), null);
+ }
+
+ @Override
+ public Schema getSchema() {
+ return aliased() ? null : Public.PUBLIC;
+ }
+
+ @Override
+ public UniqueKey getPrimaryKey() {
+ return Keys.STORE_PKEY;
+ }
+
+ @Override
+ public Store as(String alias) {
+ return new Store(DSL.name(alias), this);
+ }
+
+ @Override
+ public Store as(Name alias) {
+ return new Store(alias, this);
+ }
+
+ @Override
+ public Store as(Table> alias) {
+ return new Store(alias.getQualifiedName(), this);
+ }
+
+ /**
+ * Rename this table
+ */
+ @Override
+ public Store rename(String name) {
+ return new Store(DSL.name(name), null);
+ }
+
+ /**
+ * Rename this table
+ */
+ @Override
+ public Store rename(Name name) {
+ return new Store(name, null);
+ }
+
+ /**
+ * Rename this table
+ */
+ @Override
+ public Store rename(Table> name) {
+ return new Store(name.getQualifiedName(), null);
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ public Store where(Condition condition) {
+ return new Store(getQualifiedName(), aliased() ? this : null, null, condition);
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ public Store where(Collection extends Condition> conditions) {
+ return where(DSL.and(conditions));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ public Store where(Condition... conditions) {
+ return where(DSL.and(conditions));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ public Store where(Field condition) {
+ return where(DSL.condition(condition));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ @PlainSQL
+ public Store where(SQL condition) {
+ return where(DSL.condition(condition));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ @PlainSQL
+ public Store where(@Stringly.SQL String condition) {
+ return where(DSL.condition(condition));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ @PlainSQL
+ public Store where(@Stringly.SQL String condition, Object... binds) {
+ return where(DSL.condition(condition, binds));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ @PlainSQL
+ public Store where(@Stringly.SQL String condition, QueryPart... parts) {
+ return where(DSL.condition(condition, parts));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ public Store whereExists(Select> select) {
+ return where(DSL.exists(select));
+ }
+
+ /**
+ * Create an inline derived table from this table
+ */
+ @Override
+ public Store whereNotExists(Select> select) {
+ return where(DSL.notExists(select));
+ }
+}
diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/BookRecord.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/BookRecord.java
new file mode 100644
index 0000000000..0636ff2fdf
--- /dev/null
+++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/BookRecord.java
@@ -0,0 +1,124 @@
+/*
+ * This file is generated by jOOQ.
+ */
+package com.baeldung.jooq.jointables.public_.tables.records;
+
+
+import com.baeldung.jooq.jointables.public_.tables.Book;
+
+import org.jooq.Record1;
+import org.jooq.impl.UpdatableRecordImpl;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" })
+public class BookRecord extends UpdatableRecordImpl {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Setter for public.Book.id.
+ */
+ public void setId(Integer value) {
+ set(0, value);
+ }
+
+ /**
+ * Getter for public.Book.id.
+ */
+ public Integer getId() {
+ return (Integer) get(0);
+ }
+
+ /**
+ * Setter for public.Book.author_id.
+ */
+ public void setAuthorId(Integer value) {
+ set(1, value);
+ }
+
+ /**
+ * Getter for public.Book.author_id.
+ */
+ public Integer getAuthorId() {
+ return (Integer) get(1);
+ }
+
+ /**
+ * Setter for public.Book.title.
+ */
+ public void setTitle(String value) {
+ set(2, value);
+ }
+
+ /**
+ * Getter for public.Book.title.
+ */
+ public String getTitle() {
+ return (String) get(2);
+ }
+
+ /**
+ * Setter for public.Book.description.
+ */
+ public void setDescription(String value) {
+ set(3, value);
+ }
+
+ /**
+ * Getter for public.Book.description.
+ */
+ public String getDescription() {
+ return (String) get(3);
+ }
+
+ /**
+ * Setter for public.Book.store_id.
+ */
+ public void setStoreId(Integer value) {
+ set(4, value);
+ }
+
+ /**
+ * Getter for public.Book.store_id.
+ */
+ public Integer getStoreId() {
+ return (Integer) get(4);
+ }
+
+ // -------------------------------------------------------------------------
+ // Primary key information
+ // -------------------------------------------------------------------------
+
+ @Override
+ public Record1 key() {
+ return (Record1) super.key();
+ }
+
+ // -------------------------------------------------------------------------
+ // Constructors
+ // -------------------------------------------------------------------------
+
+ /**
+ * Create a detached BookRecord
+ */
+ public BookRecord() {
+ super(Book.BOOK);
+ }
+
+ /**
+ * Create a detached, initialised BookRecord
+ */
+ public BookRecord(Integer id, Integer authorId, String title, String description, Integer storeId) {
+ super(Book.BOOK);
+
+ setId(id);
+ setAuthorId(authorId);
+ setTitle(title);
+ setDescription(description);
+ setStoreId(storeId);
+ resetChangedOnNotNull();
+ }
+}
diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/BookauthorRecord.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/BookauthorRecord.java
new file mode 100644
index 0000000000..0e99b2d93b
--- /dev/null
+++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/BookauthorRecord.java
@@ -0,0 +1,94 @@
+/*
+ * This file is generated by jOOQ.
+ */
+package com.baeldung.jooq.jointables.public_.tables.records;
+
+
+import com.baeldung.jooq.jointables.public_.tables.Bookauthor;
+
+import org.jooq.Record1;
+import org.jooq.impl.UpdatableRecordImpl;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" })
+public class BookauthorRecord extends UpdatableRecordImpl {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Setter for public.BookAuthor.id.
+ */
+ public void setId(Integer value) {
+ set(0, value);
+ }
+
+ /**
+ * Getter for public.BookAuthor.id.
+ */
+ public Integer getId() {
+ return (Integer) get(0);
+ }
+
+ /**
+ * Setter for public.BookAuthor.name.
+ */
+ public void setName(String value) {
+ set(1, value);
+ }
+
+ /**
+ * Getter for public.BookAuthor.name.
+ */
+ public String getName() {
+ return (String) get(1);
+ }
+
+ /**
+ * Setter for public.BookAuthor.country.
+ */
+ public void setCountry(String value) {
+ set(2, value);
+ }
+
+ /**
+ * Getter for public.BookAuthor.country.
+ */
+ public String getCountry() {
+ return (String) get(2);
+ }
+
+ // -------------------------------------------------------------------------
+ // Primary key information
+ // -------------------------------------------------------------------------
+
+ @Override
+ public Record1 key() {
+ return (Record1) super.key();
+ }
+
+ // -------------------------------------------------------------------------
+ // Constructors
+ // -------------------------------------------------------------------------
+
+ /**
+ * Create a detached BookauthorRecord
+ */
+ public BookauthorRecord() {
+ super(Bookauthor.BOOKAUTHOR);
+ }
+
+ /**
+ * Create a detached, initialised BookauthorRecord
+ */
+ public BookauthorRecord(Integer id, String name, String country) {
+ super(Bookauthor.BOOKAUTHOR);
+
+ setId(id);
+ setName(name);
+ setCountry(country);
+ resetChangedOnNotNull();
+ }
+}
diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/StoreRecord.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/StoreRecord.java
new file mode 100644
index 0000000000..f8628818e3
--- /dev/null
+++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/StoreRecord.java
@@ -0,0 +1,79 @@
+/*
+ * This file is generated by jOOQ.
+ */
+package com.baeldung.jooq.jointables.public_.tables.records;
+
+
+import com.baeldung.jooq.jointables.public_.tables.Store;
+
+import org.jooq.Record1;
+import org.jooq.impl.UpdatableRecordImpl;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" })
+public class StoreRecord extends UpdatableRecordImpl {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Setter for public.Store.id.
+ */
+ public void setId(Integer value) {
+ set(0, value);
+ }
+
+ /**
+ * Getter for public.Store.id.
+ */
+ public Integer getId() {
+ return (Integer) get(0);
+ }
+
+ /**
+ * Setter for public.Store.name.
+ */
+ public void setName(String value) {
+ set(1, value);
+ }
+
+ /**
+ * Getter for public.Store.name.
+ */
+ public String getName() {
+ return (String) get(1);
+ }
+
+ // -------------------------------------------------------------------------
+ // Primary key information
+ // -------------------------------------------------------------------------
+
+ @Override
+ public Record1 key() {
+ return (Record1) super.key();
+ }
+
+ // -------------------------------------------------------------------------
+ // Constructors
+ // -------------------------------------------------------------------------
+
+ /**
+ * Create a detached StoreRecord
+ */
+ public StoreRecord() {
+ super(Store.STORE);
+ }
+
+ /**
+ * Create a detached, initialised StoreRecord
+ */
+ public StoreRecord(Integer id, String name) {
+ super(Store.STORE);
+
+ setId(id);
+ setName(name);
+ resetChangedOnNotNull();
+ }
+}
diff --git a/persistence-modules/jooq/src/test/java/com/baeldung/jooq/jointables/JoinTablesLiveTest.java b/persistence-modules/jooq/src/test/java/com/baeldung/jooq/jointables/JoinTablesLiveTest.java
new file mode 100644
index 0000000000..a5daf53542
--- /dev/null
+++ b/persistence-modules/jooq/src/test/java/com/baeldung/jooq/jointables/JoinTablesLiveTest.java
@@ -0,0 +1,111 @@
+package com.baeldung.jooq.jointables;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+
+import org.jooq.DSLContext;
+import org.jooq.Record;
+import org.jooq.Result;
+import org.jooq.SQLDialect;
+import org.jooq.impl.DSL;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.baeldung.jooq.jointables.public_.Tables;
+import com.baeldung.jooq.jointables.public_.tables.Book;
+import com.baeldung.jooq.jointables.public_.tables.Bookauthor;
+import com.baeldung.jooq.jointables.public_.tables.Store;
+
+public class JoinTablesLiveTest {
+
+ static DSLContext context;
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ // URL jooqConfigURL = getClass().getClassLoader().getResource("jooq-config-2.xml");
+ // File file = new File(jooqConfigURL.getFile());
+ // GenerationTool.generate(Files.readString(file.toPath()));
+
+ String url = "jdbc:postgresql://localhost:5432/postgres";
+ String username = "postgres";
+ String password = "";
+
+ Connection conn = DriverManager.getConnection(url, username, password);
+ context = DSL.using(conn, SQLDialect.POSTGRES);
+
+ context.insertInto(Tables.STORE, Store.STORE.ID, Store.STORE.NAME)
+ .values(1, "ABC Branch I ")
+ .values(2, "ABC Branch II")
+ .execute();
+
+ context.insertInto(Tables.BOOK, Book.BOOK.ID, Book.BOOK.TITLE, Book.BOOK.DESCRIPTION, Book.BOOK.AUTHOR_ID, Book.BOOK.STORE_ID)
+ .values(1, "Book 1", "This is book 1", 1, 1)
+ .values(2, "Book 2", "This is book 2", 2, 2)
+ .values(3, "Book 3", "This is book 3", 1, 2)
+ .values(4, "Book 4", "This is book 4", 5, 1)
+ .execute();
+
+ context.insertInto(Tables.BOOKAUTHOR, Bookauthor.BOOKAUTHOR.ID, Bookauthor.BOOKAUTHOR.NAME, Bookauthor.BOOKAUTHOR.COUNTRY)
+ .values(1, "John Smith", "Japan")
+ .values(2, "William Walce", "Japan")
+ .values(3, "Marry Sity", "South Korea")
+ .values(4, "Morry Toh", "England")
+ .execute();
+ }
+
+ @AfterClass
+ public static void cleanup() throws Exception {
+ context.truncateTable(Store.STORE)
+ .execute();
+ context.truncateTable(Book.BOOK)
+ .execute();
+ context.truncateTable(Bookauthor.BOOKAUTHOR)
+ .execute();
+ }
+
+ @Test
+ public void _whenUsingJoinMethod_thenQueryExecuted() {
+ Result result = JoinTables.usingJoinMethod(context);
+ assertEquals(3, result.size());
+ }
+
+ @Test
+ public void _whenUsingMultipleJoinMethod_thenQueryExecuted() {
+ Result result = JoinTables.usingMultipleJoinMethod(context);
+ assertEquals(3, result.size());
+ }
+
+ @Test
+ public void givenContext_whenUsingLeftOuterJoinMethod_thenQueryExecuted() {
+ Result result = JoinTables.usingLeftOuterJoinMethod(context);
+ assertEquals(4, result.size());
+ }
+
+ @Test
+ public void whenUsingRightOuterJoinMethod_thenQueryExecuted() {
+ Result result = JoinTables.usingRightOuterJoinMethod(context);
+ assertEquals(5, result.size());
+ }
+
+ @Test
+ public void whenUsingFullOuterJoinMethod_thenQueryExecuted() {
+ Result result = JoinTables.usingFullOuterJoinMethod(context);
+ assertEquals(6, result.size());
+ }
+
+ @Test
+ public void whenUsingNaturalJoinMethod_thenQueryExecuted() {
+ Result result = JoinTables.usingNaturalJoinMethod(context);
+ assertEquals(4, result.size());
+ }
+
+ @Test
+ public void whenUsingCrossJoinMethod_thenQueryExecuted() {
+ Result result = JoinTables.usingCrossJoinMethod(context);
+ assertEquals(8, result.size());
+ }
+}
diff --git a/persistence-modules/jooq/src/test/resources/jooq-config-2.xml b/persistence-modules/jooq/src/test/resources/jooq-config-2.xml
new file mode 100644
index 0000000000..a644e3fef5
--- /dev/null
+++ b/persistence-modules/jooq/src/test/resources/jooq-config-2.xml
@@ -0,0 +1,19 @@
+
+
+ org.postgresql.Driver
+ jdbc:postgresql://localhost:5432/postgres
+ postgres
+
+
+
+
+ org.jooq.meta.postgres.PostgresDatabase
+ Store|Book|BookAuthor
+
+
+
+ com.baeldung.jooq.jointables
+ src/main/java
+
+
+
diff --git a/persistence-modules/spring-boot-persistence-4/pom.xml b/persistence-modules/spring-boot-persistence-4/pom.xml
index 75b444f7cc..d4bf8ba5cb 100644
--- a/persistence-modules/spring-boot-persistence-4/pom.xml
+++ b/persistence-modules/spring-boot-persistence-4/pom.xml
@@ -60,6 +60,11 @@
${lombok.version}
provided
+
+ org.springframework
+ spring-tx
+ ${spring.tx.version}
+
@@ -84,6 +89,7 @@
3.2.0
1.16.1
1.18.30
+ 6.1.4
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/Account.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/Account.java
new file mode 100644
index 0000000000..6bb070cad2
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/Account.java
@@ -0,0 +1,23 @@
+package com.baeldung.transactionalandasync;
+
+import jakarta.persistence.*;
+import lombok.*;
+
+import java.math.BigDecimal;
+
+@Entity
+@AllArgsConstructor
+@NoArgsConstructor
+@EqualsAndHashCode(of = {"id"})
+@Table(name = "account")
+@Data
+public class Account {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+
+ @Column(name = "balance")
+ private BigDecimal balance;
+}
diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/AccountRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/AccountRepository.java
new file mode 100644
index 0000000000..a3c15e25eb
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/AccountRepository.java
@@ -0,0 +1,6 @@
+package com.baeldung.transactionalandasync;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface AccountRepository extends JpaRepository {
+}
diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/AccountService.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/AccountService.java
new file mode 100644
index 0000000000..d54f90e2e5
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/AccountService.java
@@ -0,0 +1,41 @@
+package com.baeldung.transactionalandasync;
+
+import jakarta.transaction.Transactional;
+import lombok.AllArgsConstructor;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+
+@Service
+@AllArgsConstructor
+@Transactional
+public class AccountService {
+
+ private final AccountRepository accountRepository;
+
+ @Async
+ public void transferAsync(Long depositorId, Long favoredId, BigDecimal amount) {
+ transfer(depositorId, favoredId, amount);
+
+ printReceipt();
+ }
+
+ @Transactional
+ public void transfer(Long depositorId, Long favoredId, BigDecimal amount) {
+ Account depositorAccount = accountRepository.findById(depositorId)
+ .orElseThrow(IllegalArgumentException::new);
+ Account favoredAccount = accountRepository.findById(favoredId)
+ .orElseThrow(IllegalArgumentException::new);
+
+ depositorAccount.setBalance(depositorAccount.getBalance().subtract(amount));
+ favoredAccount.setBalance(favoredAccount.getBalance().add(amount));
+
+ accountRepository.save(depositorAccount);
+ accountRepository.save(favoredAccount);
+ }
+
+ public void printReceipt() {
+ // logic to print the receipt
+ }
+}
diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/BankAccountApplication.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/BankAccountApplication.java
new file mode 100644
index 0000000000..403a098df8
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/BankAccountApplication.java
@@ -0,0 +1,12 @@
+package com.baeldung.transactionalandasync;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class BankAccountApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(BankAccountApplication.class, args);
+ }
+
+}
diff --git a/persistence-modules/spring-boot-persistence/pom.xml b/persistence-modules/spring-boot-persistence/pom.xml
index 39edc01170..a816732e52 100644
--- a/persistence-modules/spring-boot-persistence/pom.xml
+++ b/persistence-modules/spring-boot-persistence/pom.xml
@@ -70,7 +70,6 @@
- 2.23.0
2.0.1.Final
8.2.0
com.baeldung.boot.Application
diff --git a/persistence-modules/spring-data-dynamodb/pom.xml b/persistence-modules/spring-data-dynamodb/pom.xml
index 5252aa5481..5d31f13518 100644
--- a/persistence-modules/spring-data-dynamodb/pom.xml
+++ b/persistence-modules/spring-data-dynamodb/pom.xml
@@ -136,6 +136,12 @@
so
test
+
+ net.bytebuddy
+ byte-buddy
+ 1.14.13
+ test
+
diff --git a/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/SpringContextTest.java
index 3ad54e2267..13c1c162f1 100644
--- a/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/SpringContextTest.java
+++ b/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/SpringContextTest.java
@@ -5,8 +5,6 @@ import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
-import com.baeldung.Application;
-
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class SpringContextTest {
diff --git a/persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/queryjsonb/ProductRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/queryjsonb/ProductRepositoryLiveTest.java
similarity index 98%
rename from persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/queryjsonb/ProductRepositoryIntegrationTest.java
rename to persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/queryjsonb/ProductRepositoryLiveTest.java
index 2385590d7f..ac68d55139 100644
--- a/persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/queryjsonb/ProductRepositoryIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/queryjsonb/ProductRepositoryLiveTest.java
@@ -25,7 +25,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
@SpringBootTest
@ActiveProfiles("test")
@Sql(scripts = "/testdata.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
-public class ProductRepositoryIntegrationTest {
+public class ProductRepositoryLiveTest {
@Autowired
private ProductRepository productRepository;
diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/AppConfig.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/AppConfig.java
new file mode 100644
index 0000000000..840d26edf7
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/AppConfig.java
@@ -0,0 +1,52 @@
+package com.baeldung.spring.data.jpa.joinquery;
+
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
+
+import javax.sql.DataSource;
+import java.util.Properties;
+
+@Configuration
+@EnableAutoConfiguration
+public class AppConfig {
+
+ @Bean
+ public DataSource dataSource() {
+ return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2)
+ .build();
+ }
+
+ @Bean
+ public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
+ LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
+ emf.setDataSource(dataSource);
+ emf.setPackagesToScan("com.baeldung.spring.data.jpa.joinquery.entities"
+ , "com.baeldung.spring.data.jpa.joinquery.DTO"
+ , "com.baeldung.spring.data.jpa.joinquery.repositories");
+ emf.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
+ emf.setJpaProperties(getHibernateProperties());
+ return emf;
+ }
+
+ @Bean
+ public JpaTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactory) {
+ return new JpaTransactionManager(entityManagerFactory.getObject());
+ }
+
+ private Properties getHibernateProperties() {
+ Properties properties = new Properties();
+ properties.setProperty("hibernate.hbm2ddl.auto", "create");
+ properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
+ return properties;
+ }
+}
+
+
+
+
diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/DTO/ResultDTO.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/DTO/ResultDTO.java
new file mode 100644
index 0000000000..9464c25ce8
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/DTO/ResultDTO.java
@@ -0,0 +1,119 @@
+package com.baeldung.spring.data.jpa.joinquery.DTO;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import jakarta.persistence.IdClass;
+import org.springframework.context.annotation.Bean;
+
+import java.time.LocalDate;
+
+class DTO {
+ private Long customer_id;
+ private Long order_id;
+ private Long product_id;
+
+ public DTO(Long customer_id, Long order_id, Long product_id) {
+ this.customer_id = customer_id;
+ this.order_id = order_id;
+ this.product_id = product_id;
+ }
+}
+
+@Entity
+@IdClass(DTO.class)
+public class ResultDTO {
+ @Id
+ private Long customer_id;
+
+ @Id
+ private Long order_id;
+
+ @Id
+ private Long product_id;
+
+ public void setCustomer_id(Long customer_id) {
+ this.customer_id = customer_id;
+ }
+
+ public Long getProduct_id() {
+ return product_id;
+ }
+
+ public void setProduct_id(Long product_id) {
+ this.product_id = product_id;
+ }
+
+ public ResultDTO(Long customer_id, Long order_id, Long product_id, String customerName, String customerEmail, LocalDate orderDate, String productName, Double productPrice) {
+ this.customer_id = customer_id;
+ this.order_id = order_id;
+ this.product_id = product_id;
+ this.customerName = customerName;
+ this.customerEmail = customerEmail;
+ this.orderDate = orderDate;
+ this.productName = productName;
+ this.productPrice = productPrice;
+ }
+
+ private String customerName;
+ private String customerEmail;
+ private LocalDate orderDate;
+ private String productName;
+ private Double productPrice;
+
+ public Long getCustomer_id() {
+ return customer_id;
+ }
+
+ public void setCustoemr_id(Long custoemr_id) {
+ this.customer_id = custoemr_id;
+ }
+
+ public String getCustomerName() {
+ return customerName;
+ }
+
+ public void setCustomerName(String customerName) {
+ this.customerName = customerName;
+ }
+
+ public String getCustomerEmail() {
+ return customerEmail;
+ }
+
+ public void setCustomerEmail(String customerEmail) {
+ this.customerEmail = customerEmail;
+ }
+
+ public Long getOrder_id() {
+ return order_id;
+ }
+
+ public void setOrder_id(Long order_id) {
+ this.order_id = order_id;
+ }
+
+ public LocalDate getOrderDate() {
+ return orderDate;
+ }
+
+ public void setOrderDate(LocalDate orderDate) {
+ this.orderDate = orderDate;
+ }
+
+ public String getProductName() {
+ return productName;
+ }
+
+ public void setProductName(String productName) {
+ this.productName = productName;
+ }
+
+ public Double getProductPrice() {
+ return productPrice;
+ }
+
+ public void setProductPrice(Double productPrice) {
+ this.productPrice = productPrice;
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/DTO/ResultDTO_wo_Ids.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/DTO/ResultDTO_wo_Ids.java
new file mode 100644
index 0000000000..540ad9fc91
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/DTO/ResultDTO_wo_Ids.java
@@ -0,0 +1,66 @@
+package com.baeldung.spring.data.jpa.joinquery.DTO;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import jakarta.persistence.IdClass;
+
+import java.time.LocalDate;
+
+//@Entity
+//@IdClass(DTO.class)
+public class ResultDTO_wo_Ids {
+ public ResultDTO_wo_Ids(String customerName, String customerEmail, LocalDate orderDate, String productName, Double productPrice) {
+ this.customerName = customerName;
+ this.customerEmail = customerEmail;
+ this.orderDate = orderDate;
+ this.productName = productName;
+ this.productPrice = productPrice;
+ }
+
+ private String customerName;
+ private String customerEmail;
+ private LocalDate orderDate;
+ private String productName;
+ private Double productPrice;
+
+ public String getCustomerName() {
+ return customerName;
+ }
+
+ public void setCustomerName(String customerName) {
+ this.customerName = customerName;
+ }
+
+ public String getCustomerEmail() {
+ return customerEmail;
+ }
+
+ public void setCustomerEmail(String customerEmail) {
+ this.customerEmail = customerEmail;
+ }
+
+ public LocalDate getOrderDate() {
+ return orderDate;
+ }
+
+ public void setOrderDate(LocalDate orderDate) {
+ this.orderDate = orderDate;
+ }
+
+ public String getProductName() {
+ return productName;
+ }
+
+ public void setProductName(String productName) {
+ this.productName = productName;
+ }
+
+ public Double getProductPrice() {
+ return productPrice;
+ }
+
+ public void setProductPrice(Double productPrice) {
+ this.productPrice = productPrice;
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/Customer.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/Customer.java
new file mode 100644
index 0000000000..8da7aa21a2
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/Customer.java
@@ -0,0 +1,104 @@
+package com.baeldung.spring.data.jpa.joinquery.entities;
+
+import jakarta.persistence.*;
+
+import java.time.LocalDate;
+import java.util.Objects;
+import java.util.Set;
+
+@Entity
+public class Customer {
+ public Customer(){}
+ @Id
+ //@GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @OneToMany(mappedBy = "customer"
+ , cascade = CascadeType.ALL)
+ private Set customerOrders;
+
+ public Customer(Long id, Set customerOrders, String email, LocalDate dob, String name) {
+ this.id = id;
+ this.customerOrders = customerOrders;
+ this.email = email;
+ this.dob = dob;
+ this.name = name;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public void setCustomerOrders(Set customerOrders) {
+ this.customerOrders = customerOrders;
+ }
+
+ @Override
+ public String toString() {
+ return "Patient{" +
+ "id=" + id +
+ ", orders=" + customerOrders +
+ ", email='" + email + '\'' +
+ ", dob=" + dob +
+ ", name='" + name + '\'' +
+ '}';
+ }
+
+ public Set getOrders() {
+ return customerOrders;
+ }
+
+ public void setOrders(Set orders) {
+ this.customerOrders = orders;
+ }
+
+ @Column
+ private String email;
+
+ @Column(name = "dob", columnDefinition = "DATE")
+ private LocalDate dob;
+
+ @Column
+ private String name;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Customer patient = (Customer) o;
+ return Objects.equals(id, patient.id);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id);
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public LocalDate getDob() {
+ return dob;
+ }
+
+ public void setDob(LocalDate dob) {
+ this.dob = dob;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/CustomerOrder.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/CustomerOrder.java
new file mode 100644
index 0000000000..d147543e2f
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/CustomerOrder.java
@@ -0,0 +1,88 @@
+package com.baeldung.spring.data.jpa.joinquery.entities;
+
+import jakarta.persistence.*;
+
+import java.time.LocalDate;
+import java.util.Objects;
+import java.util.Set;
+
+@Entity
+public class CustomerOrder {
+ public CustomerOrder(){}
+ @Id
+ //@GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Set getProducts() {
+ return products;
+ }
+
+ public void setProducts(Set products) {
+ this.products = products;
+ }
+
+ @OneToMany(mappedBy = "customerOrder"
+ , cascade = CascadeType.ALL)
+ private Set products;
+
+ @Column
+ private LocalDate orderDate;
+
+ public CustomerOrder(Long id, Set products, LocalDate orderDate, Customer customer) {
+ this.id = id;
+ this.products = products;
+ this.orderDate = orderDate;
+ this.customer = customer;
+ }
+
+ @Override
+ public String toString() {
+ return "Consult{" +
+ "id=" + id +
+ ", products=" + products +
+ ", orderDate=" + orderDate +
+ ", customer=" + customer +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ CustomerOrder co = (CustomerOrder) o;
+ return Objects.equals(id, co.id);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id);
+ }
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name="customer_id", nullable = false)
+ private Customer customer;
+
+ public Long getId() {
+ return id;
+ }
+
+ public LocalDate getOrderDate() {
+ return orderDate;
+ }
+
+ public void setOrderDate(LocalDate orderDate) {
+ this.orderDate = orderDate;
+ }
+
+ public Customer getCustomer() {
+ return customer;
+ }
+
+ public void setCustomer(Customer customer) {
+ this.customer = customer;
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/Product.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/Product.java
new file mode 100644
index 0000000000..ea18e6225e
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/Product.java
@@ -0,0 +1,84 @@
+package com.baeldung.spring.data.jpa.joinquery.entities;
+
+import jakarta.persistence.*;
+
+import java.util.Objects;
+
+@Entity
+public class Product {
+ public Product(){}
+ @Id
+ //@GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ public Product(Long id, String productName, Double price, CustomerOrder customerOrder) {
+ this.id = id;
+ this.productName = productName;
+ this.price = price;
+ this.customerOrder = customerOrder;
+ }
+
+ @Column
+ private String productName;
+
+ @Column
+ private Double price;
+
+ @Override
+ public String toString() {
+ return "Dispense{" +
+ "id=" + id +
+ ", productName='" + productName + '\'' +
+ ", price=" + price +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Product dispense = (Product) o;
+ return Objects.equals(id, dispense.id);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id);
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getProductName() {
+ return productName;
+ }
+
+ public void setProductName(String productName) {
+ this.productName = productName;
+ }
+
+ public Double getPrice() {
+ return price;
+ }
+
+ public void setPrice(Double price) {
+ this.price = price;
+ }
+
+ public CustomerOrder getCustomerOrder() {
+ return customerOrder;
+ }
+
+ public void setCustomerOrder(CustomerOrder co) {
+ this.customerOrder = co;
+ }
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name="customerorder_id", nullable = false)
+ private CustomerOrder customerOrder;
+}
diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/CustomerRepository.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/CustomerRepository.java
new file mode 100644
index 0000000000..ba7ece74b8
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/CustomerRepository.java
@@ -0,0 +1,9 @@
+package com.baeldung.spring.data.jpa.joinquery.repositories;
+
+import com.baeldung.spring.data.jpa.joinquery.entities.Customer;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface CustomerRepository extends CrudRepository {
+}
diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/JoinRepository.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/JoinRepository.java
new file mode 100644
index 0000000000..056c91f973
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/JoinRepository.java
@@ -0,0 +1,34 @@
+package com.baeldung.spring.data.jpa.joinquery.repositories;
+
+import com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO;
+import com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO_wo_Ids;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
+import java.util.List;
+import java.util.Map;
+
+@Repository
+public interface JoinRepository extends CrudRepository {
+ @Query(value = "SELECT new com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO(c.id, o.id, p.id, c.name, c.email, o.orderDate, p.productName, p.price) "
+ + " from Customer c, CustomerOrder o ,Product p "
+ + " where c.id=o.customer.id "
+ + " and o.id=p.customerOrder.id "
+ + " and c.id=?1 ")
+ List findResultDTOByCustomer(Long id);
+
+ @Query(value = "SELECT new com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO_wo_Ids(c.name, c.email, o.orderDate, p.productName, p.price) "
+ + " from Customer c, CustomerOrder o ,Product p "
+ + " where c.id=o.customer.id "
+ + " and o.id=p.customerOrder.id "
+ + " and c.id=?1 ")
+ List findResultDTOByCustomerWithoutIds(Long id);
+
+ @Query(value = "SELECT c.*, o.*, p.* "
+ + " from Customer c, CustomerOrder o ,Product p "
+ + " where c.id=o.customer_id "
+ + " and o.id=p.customerOrder_id "
+ + " and c.id=?1 "
+ , nativeQuery = true)
+ List
@@ -92,7 +91,7 @@
org.mockito
mockito-core
- ${mockito-core.version}
+ ${mockito.version}
test
diff --git a/quarkus-modules/quarkus/pom.xml b/quarkus-modules/quarkus/pom.xml
index fc3d294beb..5ddd9826e9 100644
--- a/quarkus-modules/quarkus/pom.xml
+++ b/quarkus-modules/quarkus/pom.xml
@@ -180,7 +180,7 @@
2.16.3.Final
- 3.3.0
+ 4.4.0
\ No newline at end of file
diff --git a/spring-5-rest-docs/.gitignore b/spring-5-rest-docs/.gitignore
new file mode 100644
index 0000000000..dec013dfa4
--- /dev/null
+++ b/spring-5-rest-docs/.gitignore
@@ -0,0 +1,12 @@
+#folders#
+.idea
+/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-5-rest-docs/README.md b/spring-5-rest-docs/README.md
new file mode 100644
index 0000000000..02c018a07c
--- /dev/null
+++ b/spring-5-rest-docs/README.md
@@ -0,0 +1,8 @@
+## Spring 5 REST Docs
+
+This module contains articles about Spring 5
+
+### Relevant Articles
+
+- [Introduction to Spring REST Docs](https://www.baeldung.com/spring-rest-docs)
+- [Document Query Parameters with Spring REST Docs](https://www.baeldung.com/spring-rest-document-query-parameters)
diff --git a/spring-5-rest-docs/pom.xml b/spring-5-rest-docs/pom.xml
new file mode 100644
index 0000000000..c1f5dc0681
--- /dev/null
+++ b/spring-5-rest-docs/pom.xml
@@ -0,0 +1,118 @@
+
+
+ 4.0.0
+ spring-5
+ 0.0.1-SNAPSHOT
+ spring-5
+ jar
+ spring 5 sample project about new features
+
+
+ com.baeldung
+ parent-boot-3
+ 0.0.1-SNAPSHOT
+ ../parent-boot-3
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-hateoas
+
+
+ com.h2database
+ h2
+ runtime
+
+
+ org.springframework
+ spring-test
+
+
+ org.springframework.security
+ spring-security-test
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+
+
+
+ org.springframework.restdocs
+ spring-restdocs-mockmvc
+ test
+
+
+ org.springframework.restdocs
+ spring-restdocs-restassured
+ test
+
+
+ org.springframework.restdocs
+ spring-restdocs-webtestclient
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ com.baeldung.Spring5Application
+ JAR
+
+
+
+ org.asciidoctor
+ asciidoctor-maven-plugin
+ ${asciidoctor-plugin.version}
+
+
+ generate-docs
+ package
+
+ process-asciidoc
+
+
+ html
+ book
+
+ ${snippetsDirectory}
+
+ src/docs/asciidocs
+ target/generated-docs
+
+
+
+
+
+
+
+
+ 2.2.6
+ ${project.build.directory}/generated-snippets
+ true
+
+
+
\ No newline at end of file
diff --git a/spring-5/src/docs/asciidocs/api-guide.adoc b/spring-5-rest-docs/src/docs/asciidocs/api-guide.adoc
similarity index 100%
rename from spring-5/src/docs/asciidocs/api-guide.adoc
rename to spring-5-rest-docs/src/docs/asciidocs/api-guide.adoc
diff --git a/spring-5/src/main/java/com/baeldung/queryparamdoc/Application.java b/spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/Application.java
similarity index 100%
rename from spring-5/src/main/java/com/baeldung/queryparamdoc/Application.java
rename to spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/Application.java
diff --git a/spring-5/src/main/java/com/baeldung/queryparamdoc/Book.java b/spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/Book.java
similarity index 100%
rename from spring-5/src/main/java/com/baeldung/queryparamdoc/Book.java
rename to spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/Book.java
diff --git a/spring-5/src/main/java/com/baeldung/queryparamdoc/BookController.java b/spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/BookController.java
similarity index 100%
rename from spring-5/src/main/java/com/baeldung/queryparamdoc/BookController.java
rename to spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/BookController.java
diff --git a/spring-5/src/main/java/com/baeldung/queryparamdoc/BookService.java b/spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/BookService.java
similarity index 100%
rename from spring-5/src/main/java/com/baeldung/queryparamdoc/BookService.java
rename to spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/BookService.java
diff --git a/spring-5/src/main/java/com/baeldung/restdocs/CRUDController.java b/spring-5-rest-docs/src/main/java/com/baeldung/restdocs/CRUDController.java
similarity index 100%
rename from spring-5/src/main/java/com/baeldung/restdocs/CRUDController.java
rename to spring-5-rest-docs/src/main/java/com/baeldung/restdocs/CRUDController.java
diff --git a/spring-5/src/main/java/com/baeldung/restdocs/CrudInput.java b/spring-5-rest-docs/src/main/java/com/baeldung/restdocs/CrudInput.java
similarity index 100%
rename from spring-5/src/main/java/com/baeldung/restdocs/CrudInput.java
rename to spring-5-rest-docs/src/main/java/com/baeldung/restdocs/CrudInput.java
diff --git a/spring-5/src/main/java/com/baeldung/restdocs/IndexController.java b/spring-5-rest-docs/src/main/java/com/baeldung/restdocs/IndexController.java
similarity index 100%
rename from spring-5/src/main/java/com/baeldung/restdocs/IndexController.java
rename to spring-5-rest-docs/src/main/java/com/baeldung/restdocs/IndexController.java
diff --git a/spring-5/src/main/java/com/baeldung/restdocs/SpringRestDocsApplication.java b/spring-5-rest-docs/src/main/java/com/baeldung/restdocs/SpringRestDocsApplication.java
similarity index 100%
rename from spring-5/src/main/java/com/baeldung/restdocs/SpringRestDocsApplication.java
rename to spring-5-rest-docs/src/main/java/com/baeldung/restdocs/SpringRestDocsApplication.java
diff --git a/spring-5/src/test/java/com/baeldung/queryparamdoc/BookControllerMvcIntegrationTest.java b/spring-5-rest-docs/src/test/java/com/baeldung/queryparamdoc/BookControllerMvcIntegrationTest.java
similarity index 100%
rename from spring-5/src/test/java/com/baeldung/queryparamdoc/BookControllerMvcIntegrationTest.java
rename to spring-5-rest-docs/src/test/java/com/baeldung/queryparamdoc/BookControllerMvcIntegrationTest.java
diff --git a/spring-5/src/test/java/com/baeldung/queryparamdoc/BookControllerReactiveIntegrationTest.java b/spring-5-rest-docs/src/test/java/com/baeldung/queryparamdoc/BookControllerReactiveIntegrationTest.java
similarity index 100%
rename from spring-5/src/test/java/com/baeldung/queryparamdoc/BookControllerReactiveIntegrationTest.java
rename to spring-5-rest-docs/src/test/java/com/baeldung/queryparamdoc/BookControllerReactiveIntegrationTest.java
diff --git a/spring-5/src/test/java/com/baeldung/queryparamdoc/BookControllerRestAssuredIntegrationTest.java b/spring-5-rest-docs/src/test/java/com/baeldung/queryparamdoc/BookControllerRestAssuredIntegrationTest.java
similarity index 100%
rename from spring-5/src/test/java/com/baeldung/queryparamdoc/BookControllerRestAssuredIntegrationTest.java
rename to spring-5-rest-docs/src/test/java/com/baeldung/queryparamdoc/BookControllerRestAssuredIntegrationTest.java
diff --git a/spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit4IntegrationTest.java b/spring-5-rest-docs/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit4IntegrationTest.java
similarity index 100%
rename from spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit4IntegrationTest.java
rename to spring-5-rest-docs/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit4IntegrationTest.java
diff --git a/spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit5IntegrationTest.java b/spring-5-rest-docs/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit5IntegrationTest.java
similarity index 100%
rename from spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit5IntegrationTest.java
rename to spring-5-rest-docs/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit5IntegrationTest.java
diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java
new file mode 100644
index 0000000000..5401a4d133
--- /dev/null
+++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java
@@ -0,0 +1,12 @@
+package com.baeldung.webflux.exceptionhandeling.ex;
+
+public class NotFoundException extends RuntimeException {
+
+ public NotFoundException(String message) {
+ super(message);
+ }
+
+ public NotFoundException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java
new file mode 100644
index 0000000000..6bc39da062
--- /dev/null
+++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java
@@ -0,0 +1,29 @@
+package com.baeldung.webflux.exceptionhandeling.model;
+
+public class User {
+ private String id;
+ private String username;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public User(String userId, String userName) {
+ this.id = userId;
+ this.username = userName;
+
+ }
+}
+
diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java
new file mode 100644
index 0000000000..8c153aa2e6
--- /dev/null
+++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java
@@ -0,0 +1,22 @@
+package com.baeldung.webflux.exceptionhandeling.repository;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.springframework.stereotype.Repository;
+
+import com.baeldung.webflux.exceptionhandeling.model.User;
+
+@Repository
+public class UserRepository {
+ private final Map userDatabase = new ConcurrentHashMap<>();
+
+ public UserRepository() {
+ userDatabase.put("1", new User("1", "John Doe"));
+ userDatabase.put("2", new User("2", "Jane Smith"));
+ }
+
+ public User findById(String id) {
+ return userDatabase.get(id);
+ }
+}
diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/service/UserService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/service/UserService.java
new file mode 100644
index 0000000000..da5a672183
--- /dev/null
+++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/service/UserService.java
@@ -0,0 +1,34 @@
+package com.baeldung.webflux.exceptionhandeling.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+
+import com.baeldung.webflux.exceptionhandeling.ex.NotFoundException;
+import com.baeldung.webflux.exceptionhandeling.model.User;
+import com.baeldung.webflux.exceptionhandeling.repository.UserRepository;
+
+import reactor.core.publisher.Mono;
+
+public class UserService {
+
+ private final UserRepository userRepository;
+
+ @Autowired
+ public UserService(UserRepository userRepository) {
+ this.userRepository = userRepository;
+ }
+
+ public Mono getUserByIdThrowingException(String id) {
+ User user = userRepository.findById(id);
+ if (user == null)
+ throw new NotFoundException("User Not Found");
+ return Mono.justOrEmpty(user);
+ }
+
+ public Mono getUserByIdUsingMonoError(String id) {
+ User user = userRepository.findById(id);
+ return (user != null) ? Mono.justOrEmpty(user) : Mono.error(new NotFoundException("User Not Found"));
+
+ }
+}
diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java
new file mode 100644
index 0000000000..e968cfeea3
--- /dev/null
+++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java
@@ -0,0 +1,36 @@
+package com.baeldung.webflux.exceptionhandeling;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.Test;
+
+import reactor.core.publisher.Mono;
+import reactor.test.StepVerifier;
+
+import com.baeldung.webflux.exceptionhandeling.ex.NotFoundException;
+import com.baeldung.webflux.exceptionhandeling.model.User;
+import com.baeldung.webflux.exceptionhandeling.service.UserService;
+import com.baeldung.webflux.exceptionhandeling.repository.UserRepository;
+
+public class UserControllerUnitTest {
+ UserRepository repositoryMock = mock(UserRepository.class);
+ private final UserService userService = new UserService(repositoryMock);
+
+ @Test
+ public void givenNonExistUser_whenFailureCall_then_Throws_exception() {
+ assertThrows(NotFoundException.class, () -> userService.getUserByIdThrowingException("3"));
+
+ }
+
+ @Test
+ public void givenNonExistUser_whenFailureCall_then_returnMonoError() {
+ Mono result = userService.getUserByIdUsingMonoError("3");
+ StepVerifier.create(result)
+ .expectError(NotFoundException.class)
+ .verify();
+
+ }
+
+}
diff --git a/spring-5/README.md b/spring-5/README.md
index d1487913ac..9af8bdfaf2 100644
--- a/spring-5/README.md
+++ b/spring-5/README.md
@@ -6,9 +6,7 @@ This module contains articles about Spring 5
- [Spring 5 Functional Bean Registration](https://www.baeldung.com/spring-5-functional-beans)
- [The SpringJUnitConfig and SpringJUnitWebConfig Annotations in Spring 5](https://www.baeldung.com/spring-5-junit-config)
-- [Introduction to Spring REST Docs](https://www.baeldung.com/spring-rest-docs)
- [Spring ResponseStatusException](https://www.baeldung.com/spring-response-status-exception)
- [Spring Assert Statements](https://www.baeldung.com/spring-assert)
- [Difference between context:annotation-config vs context:component-scan](https://www.baeldung.com/spring-contextannotation-contextcomponentscan)
- [Configuring a Hikari Connection Pool with Spring Boot](https://www.baeldung.com/spring-boot-hikari)
-- [Document Query Parameters with Spring REST Docs](https://www.baeldung.com/spring-rest-document-query-parameters)
diff --git a/spring-5/pom.xml b/spring-5/pom.xml
index d66f0fa01f..46c13cd28c 100644
--- a/spring-5/pom.xml
+++ b/spring-5/pom.xml
@@ -131,36 +131,11 @@
JAR
-
- org.asciidoctor
- asciidoctor-maven-plugin
- ${asciidoctor-plugin.version}
-
-
- generate-docs
- package
-
- process-asciidoc
-
-
- html
- book
-
- ${snippetsDirectory}
-
- src/docs/asciidocs
- target/generated-docs
-
-
-
-
1.0
- 2.2.6
- ${project.build.directory}/generated-snippets
5.1.0
true
2.0.1
diff --git a/spring-aop-2/pom.xml b/spring-aop-2/pom.xml
index 3a60739315..7aea3b64de 100644
--- a/spring-aop-2/pom.xml
+++ b/spring-aop-2/pom.xml
@@ -45,6 +45,7 @@
org.mockito
mockito-core
+ ${mockito.version}
test
diff --git a/spring-boot-modules/spring-boot-3-2/pom.xml b/spring-boot-modules/spring-boot-3-2/pom.xml
index 29d9332ca5..d427aff835 100644
--- a/spring-boot-modules/spring-boot-3-2/pom.xml
+++ b/spring-boot-modules/spring-boot-3-2/pom.xml
@@ -9,10 +9,9 @@
Demo project for Spring Boot
- com.baeldung
- parent-boot-3
- 0.0.1-SNAPSHOT
- ../../parent-boot-3
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
diff --git a/spring-boot-modules/spring-boot-3/pom.xml b/spring-boot-modules/spring-boot-3/pom.xml
index ae9e9d7308..0c00a8af34 100644
--- a/spring-boot-modules/spring-boot-3/pom.xml
+++ b/spring-boot-modules/spring-boot-3/pom.xml
@@ -9,10 +9,9 @@
Demo project for Spring Boot
- com.baeldung
- parent-boot-3
- 0.0.1-SNAPSHOT
- ../../parent-boot-3
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
diff --git a/spring-boot-modules/spring-boot-aws/pom.xml b/spring-boot-modules/spring-boot-aws/pom.xml
index 8be0b230cd..966dfec6fa 100644
--- a/spring-boot-modules/spring-boot-aws/pom.xml
+++ b/spring-boot-modules/spring-boot-aws/pom.xml
@@ -11,10 +11,9 @@
- org.springframework.boot
- spring-boot-starter-parent
- 3.1.5
-
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
diff --git a/spring-boot-modules/spring-boot-basic-customization-3/pom.xml b/spring-boot-modules/spring-boot-basic-customization-3/pom.xml
index 1b09162cf4..9018b21e03 100644
--- a/spring-boot-modules/spring-boot-basic-customization-3/pom.xml
+++ b/spring-boot-modules/spring-boot-basic-customization-3/pom.xml
@@ -9,10 +9,9 @@
Module For Spring Boot Basic Customization 3
- com.baeldung
- parent-boot-3
- 0.0.1-SNAPSHOT
- ../../parent-boot-3
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
diff --git a/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/FilterConfig.java b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/FilterConfig.java
new file mode 100644
index 0000000000..212dbd8626
--- /dev/null
+++ b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/FilterConfig.java
@@ -0,0 +1,16 @@
+package com.baeldung.responsebody;
+
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class FilterConfig {
+
+ @Bean
+ public FilterRegistrationBean loggingFilter() {
+ FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
+ registrationBean.setFilter(new MD5Filter());
+ return registrationBean;
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/HelloWorldController.java b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/HelloWorldController.java
new file mode 100644
index 0000000000..657b7972bb
--- /dev/null
+++ b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/HelloWorldController.java
@@ -0,0 +1,15 @@
+package com.baeldung.responsebody;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/api/example")
+public class HelloWorldController {
+
+ @GetMapping
+ public String getExample() {
+ return "Hello, World!";
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/MD5Filter.java b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/MD5Filter.java
new file mode 100644
index 0000000000..8f6e86f17e
--- /dev/null
+++ b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/MD5Filter.java
@@ -0,0 +1,39 @@
+package com.baeldung.responsebody;
+
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.logging.Logger;
+
+import org.springframework.stereotype.Component;
+import org.springframework.web.util.ContentCachingResponseWrapper;
+
+import jakarta.servlet.Filter;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.xml.bind.DatatypeConverter;
+
+@Component
+public class MD5Filter implements Filter {
+
+ @Override
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+ ContentCachingResponseWrapper responseCacheWrapperObject = new ContentCachingResponseWrapper((HttpServletResponse) servletResponse);
+ filterChain.doFilter(servletRequest, responseCacheWrapperObject);
+
+ byte[] responseBody = responseCacheWrapperObject.getContentAsByteArray();
+
+ try {
+ MessageDigest md5Digest = MessageDigest.getInstance("MD5");
+ byte[] md5Hash = md5Digest.digest(responseBody);
+ String md5HashString = DatatypeConverter.printHexBinary(md5Hash);
+ responseCacheWrapperObject.setHeader("Response-Body-MD5", md5HashString);
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+ responseCacheWrapperObject.copyBodyToResponse();
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/ResponseBodyApplication.java b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/ResponseBodyApplication.java
new file mode 100644
index 0000000000..4084dffccf
--- /dev/null
+++ b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/ResponseBodyApplication.java
@@ -0,0 +1,12 @@
+package com.baeldung.responsebody;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication(scanBasePackages = "com.baeldung.responsebody")
+public class ResponseBodyApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ResponseBodyApplication.class, args);
+ }
+}
diff --git a/spring-boot-modules/spring-boot-basic-customization-3/src/test/java/com/baeldung/responsebody/ResponseBodyUnitTest.java b/spring-boot-modules/spring-boot-basic-customization-3/src/test/java/com/baeldung/responsebody/ResponseBodyUnitTest.java
new file mode 100644
index 0000000000..bebbd5a4b9
--- /dev/null
+++ b/spring-boot-modules/spring-boot-basic-customization-3/src/test/java/com/baeldung/responsebody/ResponseBodyUnitTest.java
@@ -0,0 +1,48 @@
+package com.baeldung.responsebody;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+
+import jakarta.xml.bind.DatatypeConverter;
+
+@SpringBootTest(classes = ResponseBodyApplication.class)
+@AutoConfigureMockMvc
+class ResponseBodyUnitTest {
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ @Test
+ void whenExampleApiCallThenResponseHasMd5Header() throws Exception {
+ String endpoint = "/api/example";
+ String expectedResponse = "Hello, World!";
+ String expectedMD5 = getMD5Hash(expectedResponse);
+
+ MvcResult mvcResult = mockMvc.perform(get(endpoint).accept(MediaType.TEXT_PLAIN_VALUE))
+ .andExpect(status().isOk())
+ .andReturn();
+
+ String md5Header = mvcResult.getResponse()
+ .getHeader("Response-Body-MD5");
+ assertThat(md5Header).isEqualTo(expectedMD5);
+ }
+
+ private String getMD5Hash(String input) throws NoSuchAlgorithmException {
+ MessageDigest md5Digest = MessageDigest.getInstance("MD5");
+ byte[] md5Hash = md5Digest.digest(input.getBytes(StandardCharsets.UTF_8));
+ return DatatypeConverter.printHexBinary(md5Hash);
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml b/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml
index d7f437633d..96cfd622db 100644
--- a/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml
+++ b/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml
@@ -42,6 +42,12 @@
${spring-boot.version}
test
+
+ net.bytebuddy
+ byte-buddy
+ ${byte-buddy.version}
+ test
+
@@ -61,6 +67,7 @@
2.2.6.RELEASE
0.0.1-SNAPSHOT
+ 1.14.13
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-data-3/pom.xml b/spring-boot-modules/spring-boot-data-3/pom.xml
index 0d35da3a0a..c6cd426bb2 100644
--- a/spring-boot-modules/spring-boot-data-3/pom.xml
+++ b/spring-boot-modules/spring-boot-data-3/pom.xml
@@ -10,10 +10,9 @@
spring-boot-data-3
- com.baeldung
- parent-boot-3
- 0.0.1-SNAPSHOT
- ../../parent-boot-3
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
diff --git a/spring-boot-modules/spring-boot-groovy/pom.xml b/spring-boot-modules/spring-boot-groovy/pom.xml
index 677e07db2d..b03bc3b004 100644
--- a/spring-boot-modules/spring-boot-groovy/pom.xml
+++ b/spring-boot-modules/spring-boot-groovy/pom.xml
@@ -10,10 +10,9 @@
Spring Boot Todo Application with Groovy
- com.baeldung
- parent-boot-3
- 0.0.1-SNAPSHOT
- ../../parent-boot-3
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
diff --git a/spring-boot-modules/spring-boot-libraries-3/pom.xml b/spring-boot-modules/spring-boot-libraries-3/pom.xml
index e88ae4c078..223a39f1de 100644
--- a/spring-boot-modules/spring-boot-libraries-3/pom.xml
+++ b/spring-boot-modules/spring-boot-libraries-3/pom.xml
@@ -6,10 +6,9 @@
spring-boot-libraries-3
- com.baeldung
- parent-boot-3
- 0.0.1-SNAPSHOT
- ../../parent-boot-3
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
diff --git a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/BarcodesController.java b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/BarcodesController.java
index 171d703621..a1318c0519 100644
--- a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/BarcodesController.java
+++ b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/BarcodesController.java
@@ -4,10 +4,17 @@ import com.baeldung.barcodes.generators.BarbecueBarcodeGenerator;
import com.baeldung.barcodes.generators.Barcode4jBarcodeGenerator;
import com.baeldung.barcodes.generators.QRGenBarcodeGenerator;
import com.baeldung.barcodes.generators.ZxingBarcodeGenerator;
+import com.baeldung.barcodes.generators.ZxingBarcodeGeneratorWithText;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
import java.awt.image.BufferedImage;
@@ -76,6 +83,11 @@ public class BarcodesController {
return okResponse(ZxingBarcodeGenerator.generateCode128BarcodeImage(barcode));
}
+ @GetMapping(value = "/zxing/qrcode/text", produces = MediaType.IMAGE_PNG_VALUE)
+ public ResponseEntity zxingCodeQRcodeText(@RequestParam("barcode") String barcode, @RequestParam("toptext") String toptext, @RequestParam("bottomtext") String bottomtext) throws Exception {
+ return okResponse(ZxingBarcodeGeneratorWithText.createQRwithText(barcode, toptext, bottomtext));
+ }
+
@PostMapping(value = "/zxing/pdf417", produces = MediaType.IMAGE_PNG_VALUE)
public ResponseEntity zxingPDF417Barcode(@RequestBody String barcode) throws Exception {
return okResponse(ZxingBarcodeGenerator.generatePDF417BarcodeImage(barcode));
diff --git a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/generators/ZxingBarcodeGeneratorWithText.java b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/generators/ZxingBarcodeGeneratorWithText.java
new file mode 100644
index 0000000000..e6ebcf9bae
--- /dev/null
+++ b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/generators/ZxingBarcodeGeneratorWithText.java
@@ -0,0 +1,59 @@
+package com.baeldung.barcodes.generators;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.WriterException;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.qrcode.QRCodeWriter;
+
+import java.awt.Graphics2D;
+import java.awt.Color;
+import java.awt.FontMetrics;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+
+public class ZxingBarcodeGeneratorWithText {
+
+ public static BufferedImage createQRwithText(String data, String topText, String bottomText) throws WriterException, IOException {
+ QRCodeWriter barcodeWriter = new QRCodeWriter();
+ BitMatrix matrix = barcodeWriter.encode(data, BarcodeFormat.QR_CODE, 200, 200);
+ return modifiedQRCode(matrix, topText, bottomText);
+ }
+
+ public static BufferedImage modifiedQRCode(BitMatrix matrix, String topText, String bottomText) throws IOException {
+ int matrixWidth = matrix.getWidth();
+ int matrixHeight = matrix.getHeight();
+
+ BufferedImage image = new BufferedImage(matrixWidth, matrixHeight, BufferedImage.TYPE_INT_RGB);
+ Graphics2D graphics = image.createGraphics();
+ graphics.setColor(Color.WHITE);
+ graphics.fillRect(0, 0, matrixWidth, matrixHeight);
+ graphics.setColor(Color.BLACK);
+
+ for (int i = 0; i < matrixWidth; i++) {
+ for (int j = 0; j < matrixHeight; j++) {
+ if (matrix.get(i, j)) {
+ graphics.fillRect(i, j, 1, 1);
+ }
+ }
+ }
+
+ FontMetrics fontMetrics = graphics.getFontMetrics();
+ int topTextWidth = fontMetrics.stringWidth(topText);
+ int bottomTextWidth = fontMetrics.stringWidth(bottomText);
+ int finalWidth = Math.max(matrixWidth, Math.max(topTextWidth, bottomTextWidth)) + 1;
+ int finalHeight = matrixHeight + fontMetrics.getHeight() + fontMetrics.getAscent() + 1;
+
+ BufferedImage finalImage = new BufferedImage(finalWidth, finalHeight, BufferedImage.TYPE_INT_RGB);
+ Graphics2D finalGraphics = finalImage.createGraphics();
+ finalGraphics.setColor(Color.WHITE);
+ finalGraphics.fillRect(0, 0, finalWidth, finalHeight);
+ finalGraphics.setColor(Color.BLACK);
+
+ finalGraphics.drawImage(image, (finalWidth - matrixWidth) / 2, fontMetrics.getAscent() + 2, null);
+ finalGraphics.drawString(topText, (finalWidth - topTextWidth) / 2, fontMetrics.getAscent() + 2);
+ finalGraphics.drawString(bottomText, (finalWidth - bottomTextWidth) / 2, finalHeight - fontMetrics.getDescent() - 2);
+
+ return finalImage;
+ }
+
+}
diff --git a/spring-boot-modules/spring-boot-logging-logback/src/main/java/com/baeldung/logging/LogbackConfiguration.java b/spring-boot-modules/spring-boot-logging-logback/src/main/java/com/baeldung/logging/LogbackConfiguration.java
new file mode 100644
index 0000000000..6f1ffe4730
--- /dev/null
+++ b/spring-boot-modules/spring-boot-logging-logback/src/main/java/com/baeldung/logging/LogbackConfiguration.java
@@ -0,0 +1,11 @@
+package com.baeldung.logging;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class LogbackConfiguration {
+ public void setLogbackConfigurationFile(String path) {
+ System.setProperty("logback.configurationFile", path);
+ }
+}
+
diff --git a/spring-boot-modules/spring-boot-logging-logback/src/test/java/com/baeldung/logging/LogbackConfigurationUnitTest.java b/spring-boot-modules/spring-boot-logging-logback/src/test/java/com/baeldung/logging/LogbackConfigurationUnitTest.java
new file mode 100644
index 0000000000..006305cac0
--- /dev/null
+++ b/spring-boot-modules/spring-boot-logging-logback/src/test/java/com/baeldung/logging/LogbackConfigurationUnitTest.java
@@ -0,0 +1,27 @@
+package com.baeldung.logging;
+
+import org.junit.Test;
+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 static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = {LogbackConfiguration.class})
+public class LogbackConfigurationUnitTest {
+
+ @Autowired
+ LogbackConfiguration logbackConfiguration;
+
+ @Test
+ public void givenLogbackConfigurationFile_whenSettingLogbackConfiguration_thenFileLocationSet() {
+ // Set the expected logback.xml location
+ String expectedLocation = "/test/path/to/logback.xml";
+ // Call the method to set the logback configuration file
+ logbackConfiguration.setLogbackConfigurationFile(expectedLocation);
+ // Verify that the system property is correctly set
+ assertThat(System.getProperty("logback.configurationFile")).isEqualTo(expectedLocation);
+ }
+}
diff --git a/spring-boot-modules/spring-boot-swagger/pom.xml b/spring-boot-modules/spring-boot-swagger/pom.xml
index bd74c3ea88..20dec5410c 100644
--- a/spring-boot-modules/spring-boot-swagger/pom.xml
+++ b/spring-boot-modules/spring-boot-swagger/pom.xml
@@ -10,10 +10,9 @@
Module For Spring Boot Swagger
- com.baeldung
- parent-boot-3
- ../../parent-boot-3
- 0.0.1-SNAPSHOT
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
diff --git a/spring-core/pom.xml b/spring-core/pom.xml
index 5134ad42f7..99b3291dcf 100644
--- a/spring-core/pom.xml
+++ b/spring-core/pom.xml
@@ -49,7 +49,7 @@
org.springframework.boot
spring-boot-test
- ${mockito.spring.boot.version}
+ ${spring-boot.version}
test
@@ -78,10 +78,8 @@
- 1.4.4.RELEASE
1
1.5.2.RELEASE
- 1.10.19
1.3.2
diff --git a/spring-ejb-modules/ejb-beans/pom.xml b/spring-ejb-modules/ejb-beans/pom.xml
index 6203db5f5a..52503922b6 100644
--- a/spring-ejb-modules/ejb-beans/pom.xml
+++ b/spring-ejb-modules/ejb-beans/pom.xml
@@ -189,7 +189,6 @@
5.2.3.RELEASE
5.16.3
5.16.3
- 2.21.0
2.8
8.2.1.Final
2.12.5
diff --git a/spring-reactive-modules/spring-reactive-client/pom.xml b/spring-reactive-modules/spring-reactive-client/pom.xml
index 797529b980..bcfbe31ed6 100644
--- a/spring-reactive-modules/spring-reactive-client/pom.xml
+++ b/spring-reactive-modules/spring-reactive-client/pom.xml
@@ -9,9 +9,10 @@
spring boot sample project about new features
- com.baeldung.spring.reactive
- spring-reactive-modules
- 1.0.0-SNAPSHOT
+ com.baeldung
+ parent-boot-3
+ 0.0.1-SNAPSHOT
+ ../../parent-boot-3
@@ -42,8 +43,13 @@
${reactor-spring.version}
- javax.json.bind
- javax.json.bind-api
+ jakarta.json.bind
+ jakarta.json.bind-api
+
+
+ jakarta.json
+ jakarta.json-api
+ ${jakarta.json-api.version}
org.apache.geronimo.specs
@@ -53,6 +59,7 @@
org.apache.johnzon
johnzon-jsonb
+ ${johnzon-jsonb.version}
@@ -92,7 +99,7 @@
test
- com.github.tomakehurst
+ org.wiremock
wiremock-standalone
${wiremock-standalone.version}
test
@@ -183,12 +190,14 @@
1.0.1.RELEASE
1.0
- 1.1.6
+ 4.0.3
5.0.0-alpha.12
3.5.3
- 2.26.0
- 3.1.4
+ 3.4.2
+ 4.0.3
2.0.0-Beta4
+ 2.0.0
+ 2.1.3
\ No newline at end of file
diff --git a/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/controller/UploadController.java b/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/controller/UploadController.java
index 08d6ff55ef..55562f58f4 100644
--- a/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/controller/UploadController.java
+++ b/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/controller/UploadController.java
@@ -2,7 +2,7 @@ package com.baeldung.reactive.controller;
import com.baeldung.reactive.service.ReactiveUploadService;
-import org.springframework.http.HttpStatus;
+import org.springframework.http.HttpStatusCode;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import reactor.core.publisher.Mono;
@@ -18,13 +18,13 @@ public class UploadController {
@PostMapping(path = "/upload")
@ResponseBody
- public Mono uploadPdf(@RequestParam("file") final MultipartFile multipartFile) {
+ public Mono uploadPdf(@RequestParam("file") final MultipartFile multipartFile) {
return uploadService.uploadPdf(multipartFile.getResource());
}
@PostMapping(path = "/upload/multipart")
@ResponseBody
- public Mono uploadMultipart(@RequestParam("file") final MultipartFile multipartFile) {
+ public Mono uploadMultipart(@RequestParam("file") final MultipartFile multipartFile) {
return uploadService.uploadMultipart(multipartFile);
}
}
diff --git a/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/service/EmployeeService.java b/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/service/EmployeeService.java
index b841dbfe3f..c402efcbc1 100644
--- a/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/service/EmployeeService.java
+++ b/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/service/EmployeeService.java
@@ -1,4 +1,5 @@
package com.baeldung.reactive.service;
+
import com.baeldung.reactive.model.Employee;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
diff --git a/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/service/ReactiveUploadService.java b/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/service/ReactiveUploadService.java
index a12d54960a..130e09816e 100644
--- a/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/service/ReactiveUploadService.java
+++ b/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/service/ReactiveUploadService.java
@@ -4,6 +4,7 @@ package com.baeldung.reactive.service;
import com.baeldung.reactive.exception.ServiceException;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpStatus;
+import org.springframework.http.HttpStatusCode;
import org.springframework.http.MediaType;
import org.springframework.http.client.MultipartBodyBuilder;
import org.springframework.stereotype.Service;
@@ -26,10 +27,10 @@ public class ReactiveUploadService {
}
- public Mono uploadPdf(final Resource resource) {
+ public Mono uploadPdf(final Resource resource) {
final URI url = UriComponentsBuilder.fromHttpUrl(EXTERNAL_UPLOAD_URL).build().toUri();
- Mono httpStatusMono = webClient.post()
+ Mono httpStatusMono = webClient.post()
.uri(url)
.contentType(MediaType.APPLICATION_PDF)
.body(BodyInserters.fromResource(resource))
@@ -44,13 +45,13 @@ public class ReactiveUploadService {
}
- public Mono uploadMultipart(final MultipartFile multipartFile) {
+ public Mono uploadMultipart(final MultipartFile multipartFile) {
final URI url = UriComponentsBuilder.fromHttpUrl(EXTERNAL_UPLOAD_URL).build().toUri();
final MultipartBodyBuilder builder = new MultipartBodyBuilder();
builder.part("file", multipartFile.getResource());
- Mono httpStatusMono = webClient.post()
+ Mono httpStatusMono = webClient.post()
.uri(url)
.contentType(MediaType.MULTIPART_FORM_DATA)
.body(BodyInserters.fromMultipartData(builder.build()))
diff --git a/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/webclient/status/WebClientStatusCodeHandler.java b/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/webclient/status/WebClientStatusCodeHandler.java
index 784fcf2812..5c655430dd 100644
--- a/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/webclient/status/WebClientStatusCodeHandler.java
+++ b/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/webclient/status/WebClientStatusCodeHandler.java
@@ -3,6 +3,7 @@ package com.baeldung.webclient.status;
import com.baeldung.webclient.status.exception.CustomBadRequestException;
import com.baeldung.webclient.status.exception.CustomServerErrorException;
import org.springframework.http.HttpStatus;
+import org.springframework.http.HttpStatusCode;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;
@@ -40,7 +41,7 @@ public class WebClientStatusCodeHandler {
}
private static Mono exchangeFilterResponseProcessor(ClientResponse response) {
- HttpStatus status = response.statusCode();
+ HttpStatusCode status = response.statusCode();
if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status)) {
return response.bodyToMono(String.class)
.flatMap(body -> Mono.error(new CustomServerErrorException(body)));
diff --git a/spring-reactive-modules/spring-reactive-client/src/main/resources/application.properties b/spring-reactive-modules/spring-reactive-client/src/main/resources/application.properties
index 05033054b1..92e3aed117 100644
--- a/spring-reactive-modules/spring-reactive-client/src/main/resources/application.properties
+++ b/spring-reactive-modules/spring-reactive-client/src/main/resources/application.properties
@@ -1,5 +1,3 @@
logging.level.root=INFO
-
server.port=8081
-
logging.level.reactor.netty.http.client.HttpClient=DEBUG
\ No newline at end of file
diff --git a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/SpringContextTest.java b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/SpringContextTest.java
index c0ca9b7e64..2434afd62e 100644
--- a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/SpringContextTest.java
+++ b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/SpringContextTest.java
@@ -5,10 +5,10 @@ import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
-import com.baeldung.reactive.Spring5ReactiveTestApplication;
+import com.baeldung.reactive.SpringReactiveTestApplication;
@RunWith(SpringRunner.class)
-@SpringBootTest(classes = Spring5ReactiveTestApplication.class)
+@SpringBootTest(classes = SpringReactiveTestApplication.class)
public class SpringContextTest {
@Test
diff --git a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/ReactiveIntegrationTest.java b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/ReactiveIntegrationTest.java
index 1d2197a381..c399667444 100644
--- a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/ReactiveIntegrationTest.java
+++ b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/ReactiveIntegrationTest.java
@@ -49,7 +49,9 @@ public class ReactiveIntegrationTest {
.withHeader("Content-Type", "application/json")
.withBody("{\"id\":123, \"name\":\"foo\"}")));
- final Mono fooMono = client.get().uri("/foo/123").exchange().log();
+ final Mono fooMono = client.get().uri("/foo/123").retrieve()
+ .bodyToMono(ClientResponse.class)
+ .log();
System.out.println(fooMono.subscribe());
}
diff --git a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/Spring5ReactiveTestApplication.java b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/SpringReactiveTestApplication.java
similarity index 87%
rename from spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/Spring5ReactiveTestApplication.java
rename to spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/SpringReactiveTestApplication.java
index c884ace323..f6c578c48f 100644
--- a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/Spring5ReactiveTestApplication.java
+++ b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/SpringReactiveTestApplication.java
@@ -9,7 +9,7 @@ import org.springframework.web.reactive.function.client.WebClient;
import com.baeldung.reactive.model.Foo;
@SpringBootApplication
-public class Spring5ReactiveTestApplication {
+public class SpringReactiveTestApplication {
@Bean
public WebClient client() {
@@ -29,7 +29,7 @@ public class Spring5ReactiveTestApplication {
//
public static void main(String[] args) {
- SpringApplication.run(Spring5ReactiveTestApplication.class, args);
+ SpringApplication.run(SpringReactiveTestApplication.class, args);
}
}
diff --git a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/logging/WebClientLoggingIntegrationTest.java b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/logging/WebClientLoggingIntegrationTest.java
index 27dde13608..3686733de9 100644
--- a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/logging/WebClientLoggingIntegrationTest.java
+++ b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/logging/WebClientLoggingIntegrationTest.java
@@ -10,8 +10,8 @@ import static org.mockito.Mockito.when;
import java.net.URI;
import org.eclipse.jetty.client.api.Request;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.slf4j.LoggerFactory;
import org.springframework.http.client.reactive.JettyClientHttpConnector;
@@ -73,9 +73,9 @@ public class WebClientLoggingIntegrationTest {
}
@Test
+ @Disabled
public void givenJettyHttpClient_whenEndpointIsConsumed_thenRequestAndResponseBodyLogged() {
- SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
- org.eclipse.jetty.client.HttpClient httpClient = new org.eclipse.jetty.client.HttpClient(sslContextFactory) {
+ org.eclipse.jetty.client.HttpClient httpClient = new org.eclipse.jetty.client.HttpClient(){
@Override
public Request newRequest(URI uri) {
Request request = super.newRequest(uri);
@@ -91,8 +91,7 @@ public class WebClientLoggingIntegrationTest {
.uri(sampleUrl)
.body(BodyInserters.fromObject(post))
.retrieve()
- .bodyToMono(String.class)
- .block();
+ .bodyToMono(String.class);
verify(jettyAppender).doAppend(argThat(argument -> (((LoggingEvent) argument).getFormattedMessage()).contains(sampleResponseBody)));
}
@@ -103,14 +102,16 @@ public class WebClientLoggingIntegrationTest {
reactor.netty.http.client.HttpClient httpClient = HttpClient
.create()
.wiretap(true);
+
WebClient
.builder()
.clientConnector(new ReactorClientHttpConnector(httpClient))
.build()
.post()
.uri(sampleUrl)
- .body(BodyInserters.fromObject(post))
- .exchange()
+ .body(BodyInserters.fromValue(post))
+ .retrieve()
+ .bodyToMono(String.class)
.block();
verify(nettyAppender).doAppend(argThat(argument -> (((LoggingEvent) argument).getFormattedMessage()).contains("00000300")));
@@ -126,8 +127,9 @@ public class WebClientLoggingIntegrationTest {
.build()
.post()
.uri(sampleUrl)
- .body(BodyInserters.fromObject(post))
- .exchange()
+ .body(BodyInserters.fromValue(post))
+ .retrieve()
+ .bodyToMono(String.class)
.block();
verify(nettyAppender).doAppend(argThat(argument -> (((LoggingEvent) argument).getFormattedMessage()).contains(sampleResponseBody)));
@@ -141,9 +143,10 @@ public class WebClientLoggingIntegrationTest {
.build()
.post()
.uri(sampleUrl)
- .body(BodyInserters.fromObject(post))
- .exchange()
- .block();
+ .body(BodyInserters.fromValue(post))
+ .retrieve()
+ .bodyToMono(String.class)
+ .block();
verify(mockAppender, atLeast(1)).doAppend(argThat(argument -> (((LoggingEvent) argument).getFormattedMessage()).contains(sampleUrl)));
}
diff --git a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/logging/filters/LogFilters.java b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/logging/filters/LogFilters.java
index c1c3d3e895..c8a7f05eb4 100644
--- a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/logging/filters/LogFilters.java
+++ b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/logging/filters/LogFilters.java
@@ -37,7 +37,7 @@ public class LogFilters {
if (log.isDebugEnabled()) {
StringBuilder sb = new StringBuilder("Response: \n")
.append("Status: ")
- .append(clientResponse.rawStatusCode());
+ .append(clientResponse.statusCode());
clientResponse
.headers()
.asHttpHeaders()
diff --git a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/service/EmployeeServiceUnitTest.java b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/service/EmployeeServiceUnitTest.java
index 1d1a8fd2e4..26ce3a1cec 100644
--- a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/service/EmployeeServiceUnitTest.java
+++ b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/service/EmployeeServiceUnitTest.java
@@ -7,16 +7,11 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
-import org.mockito.exceptions.base.MockitoException;
-import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
diff --git a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/service/ReactiveUploadServiceUnitTest.java b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/service/ReactiveUploadServiceUnitTest.java
index 40c1e40d92..6baf2e8a61 100644
--- a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/service/ReactiveUploadServiceUnitTest.java
+++ b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/service/ReactiveUploadServiceUnitTest.java
@@ -3,6 +3,7 @@ package com.baeldung.reactive.service;
import org.junit.jupiter.api.Test;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpStatus;
+import org.springframework.http.HttpStatusCode;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.WebClient;
@@ -28,8 +29,8 @@ class ReactiveUploadServiceUnitTest {
void givenAPdf_whenUploadingWithWebClient_thenOK() {
final Resource file = mock(Resource.class);
- final Mono result = tested.uploadPdf(file);
- final HttpStatus status = result.block();
+ final Mono result = tested.uploadPdf(file);
+ final HttpStatusCode status = result.block();
assertThat(status).isEqualTo(HttpStatus.OK);
}
@@ -40,8 +41,8 @@ class ReactiveUploadServiceUnitTest {
final MultipartFile multipartFile = mock(MultipartFile.class);
when(multipartFile.getResource()).thenReturn(file);
- final Mono result = tested.uploadMultipart(multipartFile);
- final HttpStatus status = result.block();
+ final Mono result = tested.uploadMultipart(multipartFile);
+ final HttpStatusCode status = result.block();
assertThat(status).isEqualTo(HttpStatus.OK);
}
diff --git a/spring-scheduling-2/README.md b/spring-scheduling-2/README.md
new file mode 100644
index 0000000000..bc1911b396
--- /dev/null
+++ b/spring-scheduling-2/README.md
@@ -0,0 +1 @@
+### Relevant articles:
\ No newline at end of file
diff --git a/spring-scheduling-2/pom.xml b/spring-scheduling-2/pom.xml
new file mode 100644
index 0000000000..9c69758ed0
--- /dev/null
+++ b/spring-scheduling-2/pom.xml
@@ -0,0 +1,40 @@
+
+
+ 4.0.0
+ spring-scheduling-2
+ 0.1-SNAPSHOT
+ spring-scheduling-2
+ jar
+
+
+ com.baeldung
+ parent-boot-3
+ 0.0.1-SNAPSHOT
+ ../parent-boot-3
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ repackage
+ none
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/DelayedNotificationScheduler.java b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/DelayedNotificationScheduler.java
new file mode 100644
index 0000000000..91ed9beffc
--- /dev/null
+++ b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/DelayedNotificationScheduler.java
@@ -0,0 +1,22 @@
+package com.baeldung.disablingscheduledtasks;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.scheduling.annotation.Scheduled;
+
+public class DelayedNotificationScheduler {
+
+ private static final Logger logger = LoggerFactory.getLogger(DelayedNotificationScheduler.class);
+
+ private NotificationService notificationService;
+
+ public DelayedNotificationScheduler(NotificationService notificationService) {
+ this.notificationService = notificationService;
+ }
+
+ @Scheduled(fixedDelayString = "${notification.send.out.delay}", initialDelayString = "${notification.send.out.initial.delay}")
+ public void attemptSendingOutDelayedNotifications() {
+ logger.info("Scheduled notifications send out attempt");
+ notificationService.sendOutDelayedNotifications();
+ }
+}
\ No newline at end of file
diff --git a/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/Notification.java b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/Notification.java
new file mode 100644
index 0000000000..01ed80395e
--- /dev/null
+++ b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/Notification.java
@@ -0,0 +1,31 @@
+package com.baeldung.disablingscheduledtasks;
+
+import java.time.Clock;
+import java.time.ZonedDateTime;
+import java.util.UUID;
+
+public class Notification {
+
+ private UUID id = UUID.randomUUID();
+ private boolean isSentOut = false;
+ private ZonedDateTime sendOutTime;
+
+ public Notification(ZonedDateTime sendOutTime) {
+ this.sendOutTime = sendOutTime;
+ }
+
+ public void sendOut(Clock clock) {
+ ZonedDateTime now = ZonedDateTime.now(clock);
+ if (now.isAfter(sendOutTime)) {
+ isSentOut = true;
+ }
+ }
+
+ public UUID getId() {
+ return id;
+ }
+
+ public boolean isSentOut() {
+ return isSentOut;
+ }
+}
\ No newline at end of file
diff --git a/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/NotificationRepository.java b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/NotificationRepository.java
new file mode 100644
index 0000000000..08fe8c830d
--- /dev/null
+++ b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/NotificationRepository.java
@@ -0,0 +1,30 @@
+package com.baeldung.disablingscheduledtasks;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.stream.Collectors;
+
+public class NotificationRepository {
+
+ private Collection notifications = new ConcurrentLinkedQueue<>();
+
+ public Notification findById(UUID notificationId) {
+ return notifications.stream()
+ .filter(n -> notificationId.equals(n.getId()))
+ .findFirst()
+ .orElseThrow(NoSuchElementException::new);
+ }
+
+ public List findAllAwaitingSendOut() {
+ return notifications.stream()
+ .filter(notification -> !notification.isSentOut())
+ .collect(Collectors.toList());
+ }
+
+ public void save(Notification notification) {
+ notifications.add(notification);
+ }
+}
\ No newline at end of file
diff --git a/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/NotificationService.java b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/NotificationService.java
new file mode 100644
index 0000000000..3451a05cbe
--- /dev/null
+++ b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/NotificationService.java
@@ -0,0 +1,26 @@
+package com.baeldung.disablingscheduledtasks;
+
+import java.time.Clock;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NotificationService {
+
+ private static final Logger logger = LoggerFactory.getLogger(NotificationService.class);
+
+ private NotificationRepository notificationRepository;
+ private Clock clock;
+
+ public NotificationService(NotificationRepository notificationRepository, Clock clock) {
+ this.notificationRepository = notificationRepository;
+ this.clock = clock;
+ }
+
+ public void sendOutDelayedNotifications() {
+ logger.info("Sending out delayed notifications");
+ List notifications = notificationRepository.findAllAwaitingSendOut();
+ notifications.forEach(notification -> notification.sendOut(clock));
+ }
+}
\ No newline at end of file
diff --git a/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithprofile/ApplicationConfig.java b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithprofile/ApplicationConfig.java
new file mode 100644
index 0000000000..19a69840ff
--- /dev/null
+++ b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithprofile/ApplicationConfig.java
@@ -0,0 +1,34 @@
+package com.baeldung.disablingscheduledtasks.config.disablewithprofile;
+
+import java.time.Clock;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import com.baeldung.disablingscheduledtasks.DelayedNotificationScheduler;
+import com.baeldung.disablingscheduledtasks.NotificationRepository;
+import com.baeldung.disablingscheduledtasks.NotificationService;
+
+@Configuration
+public class ApplicationConfig {
+
+ @Bean
+ public Clock clock() {
+ return Clock.systemUTC();
+ }
+
+ @Bean
+ public NotificationRepository notificationRepository() {
+ return new NotificationRepository();
+ }
+
+ @Bean
+ public NotificationService notificationService(NotificationRepository notificationRepository, Clock clock) {
+ return new NotificationService(notificationRepository, clock);
+ }
+
+ @Bean
+ public DelayedNotificationScheduler delayedNotificationScheduler(NotificationService notificationService) {
+ return new DelayedNotificationScheduler(notificationService);
+ }
+}
\ No newline at end of file
diff --git a/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithprofile/SchedulingConfig.java b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithprofile/SchedulingConfig.java
new file mode 100644
index 0000000000..6461b9273d
--- /dev/null
+++ b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithprofile/SchedulingConfig.java
@@ -0,0 +1,12 @@
+package com.baeldung.disablingscheduledtasks.config.disablewithprofile;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@Configuration
+@EnableScheduling
+@Profile("!integrationTest")
+public class SchedulingConfig {
+
+}
\ No newline at end of file
diff --git a/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithproperty/ApplicationConfig.java b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithproperty/ApplicationConfig.java
new file mode 100644
index 0000000000..8b006428d2
--- /dev/null
+++ b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithproperty/ApplicationConfig.java
@@ -0,0 +1,34 @@
+package com.baeldung.disablingscheduledtasks.config.disablewithproperty;
+
+import java.time.Clock;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import com.baeldung.disablingscheduledtasks.DelayedNotificationScheduler;
+import com.baeldung.disablingscheduledtasks.NotificationRepository;
+import com.baeldung.disablingscheduledtasks.NotificationService;
+
+@Configuration
+public class ApplicationConfig {
+
+ @Bean
+ public Clock clock() {
+ return Clock.systemUTC();
+ }
+
+ @Bean
+ public NotificationRepository notificationRepository() {
+ return new NotificationRepository();
+ }
+
+ @Bean
+ public NotificationService notificationService(NotificationRepository notificationRepository, Clock clock) {
+ return new NotificationService(notificationRepository, clock);
+ }
+
+ @Bean
+ public DelayedNotificationScheduler delayedNotificationScheduler(NotificationService notificationService) {
+ return new DelayedNotificationScheduler(notificationService);
+ }
+}
\ No newline at end of file
diff --git a/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithproperty/SchedulingConfig.java b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithproperty/SchedulingConfig.java
new file mode 100644
index 0000000000..2b85dbfcef
--- /dev/null
+++ b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithproperty/SchedulingConfig.java
@@ -0,0 +1,12 @@
+package com.baeldung.disablingscheduledtasks.config.disablewithproperty;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@Configuration
+@EnableScheduling
+@ConditionalOnProperty(value = "scheduling.enabled", havingValue = "true", matchIfMissing = true)
+public class SchedulingConfig {
+
+}
\ No newline at end of file
diff --git a/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/schedulingon/ApplicationConfig.java b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/schedulingon/ApplicationConfig.java
new file mode 100644
index 0000000000..e0db118831
--- /dev/null
+++ b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/schedulingon/ApplicationConfig.java
@@ -0,0 +1,36 @@
+package com.baeldung.disablingscheduledtasks.config.schedulingon;
+
+import java.time.Clock;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+import com.baeldung.disablingscheduledtasks.DelayedNotificationScheduler;
+import com.baeldung.disablingscheduledtasks.NotificationRepository;
+import com.baeldung.disablingscheduledtasks.NotificationService;
+
+@Configuration
+@EnableScheduling
+public class ApplicationConfig {
+
+ @Bean
+ public Clock clock() {
+ return Clock.systemUTC();
+ }
+
+ @Bean
+ public NotificationRepository notificationRepository() {
+ return new NotificationRepository();
+ }
+
+ @Bean
+ public NotificationService notificationService(NotificationRepository notificationRepository, Clock clock) {
+ return new NotificationService(notificationRepository, clock);
+ }
+
+ @Bean
+ public DelayedNotificationScheduler delayedNotificationScheduler(NotificationService notificationService) {
+ return new DelayedNotificationScheduler(notificationService);
+ }
+}
\ No newline at end of file
diff --git a/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/disablewithprofile/DelayedNotificationSchedulerIntegrationTest.java b/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/disablewithprofile/DelayedNotificationSchedulerIntegrationTest.java
new file mode 100644
index 0000000000..523950e48c
--- /dev/null
+++ b/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/disablewithprofile/DelayedNotificationSchedulerIntegrationTest.java
@@ -0,0 +1,64 @@
+package com.baeldung.disablingscheduledtasks.disablewithprofile;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.time.Clock;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+import org.springframework.test.context.ActiveProfiles;
+
+import com.baeldung.disablingscheduledtasks.DelayedNotificationScheduler;
+import com.baeldung.disablingscheduledtasks.Notification;
+import com.baeldung.disablingscheduledtasks.NotificationRepository;
+import com.baeldung.disablingscheduledtasks.config.disablewithprofile.ApplicationConfig;
+import com.baeldung.disablingscheduledtasks.config.disablewithprofile.SchedulingConfig;
+
+@SpringBootTest(
+ classes = { ApplicationConfig.class, SchedulingConfig.class, SchedulerTestConfiguration.class },
+ properties = {
+ "notification.send.out.delay: 10",
+ "notification.send.out.initial.delay: 0"
+ }
+)
+@ActiveProfiles("integrationTest")
+public class DelayedNotificationSchedulerIntegrationTest {
+
+ @Autowired
+ private Clock testClock;
+
+ @Autowired
+ private NotificationRepository repository;
+
+ @Autowired
+ private DelayedNotificationScheduler scheduler;
+
+ @Test
+ public void whenTimeIsOverNotificationSendOutTime_thenItShouldBeSent() {
+ ZonedDateTime fiveMinutesAgo = ZonedDateTime.now(testClock).minusMinutes(5);
+ Notification notification = new Notification(fiveMinutesAgo);
+ repository.save(notification);
+
+ scheduler.attemptSendingOutDelayedNotifications();
+
+ Notification processedNotification = repository.findById(notification.getId());
+ assertTrue(processedNotification.isSentOut());
+ }
+}
+
+@TestConfiguration
+class SchedulerTestConfiguration {
+
+ @Bean
+ @Primary
+ public Clock testClock() {
+ return Clock.fixed(Instant.parse("2024-03-10T10:15:30.00Z"), ZoneId.systemDefault());
+ }
+}
\ No newline at end of file
diff --git a/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/disablewithproperty/DelayedNotificationSchedulerIntegrationTest.java b/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/disablewithproperty/DelayedNotificationSchedulerIntegrationTest.java
new file mode 100644
index 0000000000..da3a061cfc
--- /dev/null
+++ b/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/disablewithproperty/DelayedNotificationSchedulerIntegrationTest.java
@@ -0,0 +1,63 @@
+package com.baeldung.disablingscheduledtasks.disablewithproperty;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.time.Clock;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+
+import com.baeldung.disablingscheduledtasks.DelayedNotificationScheduler;
+import com.baeldung.disablingscheduledtasks.Notification;
+import com.baeldung.disablingscheduledtasks.NotificationRepository;
+import com.baeldung.disablingscheduledtasks.config.disablewithproperty.ApplicationConfig;
+import com.baeldung.disablingscheduledtasks.config.disablewithproperty.SchedulingConfig;
+
+@SpringBootTest(
+ classes = { ApplicationConfig.class, SchedulingConfig.class, SchedulerTestConfiguration.class },
+ properties = {
+ "notification.send.out.delay: 10",
+ "notification.send.out.initial.delay: 0",
+ "scheduling.enabled: false"
+ }
+)
+public class DelayedNotificationSchedulerIntegrationTest {
+
+ @Autowired
+ private Clock testClock;
+
+ @Autowired
+ private NotificationRepository repository;
+
+ @Autowired
+ private DelayedNotificationScheduler scheduler;
+
+ @Test
+ public void whenTimeIsOverNotificationSendOutTime_thenItShouldBeSent() {
+ ZonedDateTime fiveMinutesAgo = ZonedDateTime.now(testClock).minusMinutes(5);
+ Notification notification = new Notification(fiveMinutesAgo);
+ repository.save(notification);
+
+ scheduler.attemptSendingOutDelayedNotifications();
+
+ Notification processedNotification = repository.findById(notification.getId());
+ assertTrue(processedNotification.isSentOut());
+ }
+}
+
+@TestConfiguration
+class SchedulerTestConfiguration {
+
+ @Bean
+ @Primary
+ public Clock testClock() {
+ return Clock.fixed(Instant.parse("2024-03-10T10:15:30.00Z"), ZoneId.systemDefault());
+ }
+}
\ No newline at end of file
diff --git a/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/longinitialdelay/DelayedNotificationSchedulerIntegrationTest.java b/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/longinitialdelay/DelayedNotificationSchedulerIntegrationTest.java
new file mode 100644
index 0000000000..d67af13b9d
--- /dev/null
+++ b/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/longinitialdelay/DelayedNotificationSchedulerIntegrationTest.java
@@ -0,0 +1,61 @@
+package com.baeldung.disablingscheduledtasks.longinitialdelay;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.time.Clock;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+
+import com.baeldung.disablingscheduledtasks.DelayedNotificationScheduler;
+import com.baeldung.disablingscheduledtasks.Notification;
+import com.baeldung.disablingscheduledtasks.NotificationRepository;
+import com.baeldung.disablingscheduledtasks.config.schedulingon.ApplicationConfig;
+
+@SpringBootTest(
+ classes = { ApplicationConfig.class, SchedulerTestConfiguration.class },
+ properties = {
+ "notification.send.out.delay: 10",
+ "notification.send.out.initial.delay: 60000"
+ }
+)
+public class DelayedNotificationSchedulerIntegrationTest {
+
+ @Autowired
+ private Clock testClock;
+
+ @Autowired
+ private NotificationRepository repository;
+
+ @Autowired
+ private DelayedNotificationScheduler scheduler;
+
+ @Test
+ public void whenTimeIsOverNotificationSendOutTime_thenItShouldBeSent() {
+ ZonedDateTime fiveMinutesAgo = ZonedDateTime.now(testClock).minusMinutes(5);
+ Notification notification = new Notification(fiveMinutesAgo);
+ repository.save(notification);
+
+ scheduler.attemptSendingOutDelayedNotifications();
+
+ Notification processedNotification = repository.findById(notification.getId());
+ assertTrue(processedNotification.isSentOut());
+ }
+}
+
+@TestConfiguration
+class SchedulerTestConfiguration {
+
+ @Bean
+ @Primary
+ public Clock testClock() {
+ return Clock.fixed(Instant.parse("2024-03-10T10:15:30.00Z"), ZoneId.systemDefault());
+ }
+}
\ No newline at end of file
diff --git a/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/schedulingon/DelayedNotificationSchedulerIntegrationTest.java b/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/schedulingon/DelayedNotificationSchedulerIntegrationTest.java
new file mode 100644
index 0000000000..eb351ee2d1
--- /dev/null
+++ b/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/schedulingon/DelayedNotificationSchedulerIntegrationTest.java
@@ -0,0 +1,61 @@
+package com.baeldung.disablingscheduledtasks.schedulingon;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.time.Clock;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+
+import com.baeldung.disablingscheduledtasks.DelayedNotificationScheduler;
+import com.baeldung.disablingscheduledtasks.Notification;
+import com.baeldung.disablingscheduledtasks.NotificationRepository;
+import com.baeldung.disablingscheduledtasks.config.schedulingon.ApplicationConfig;
+
+@SpringBootTest(
+ classes = { ApplicationConfig.class, SchedulerTestConfiguration.class },
+ properties = {
+ "notification.send.out.delay: 10",
+ "notification.send.out.initial.delay: 0"
+ }
+)
+public class DelayedNotificationSchedulerIntegrationTest {
+
+ @Autowired
+ private Clock testClock;
+
+ @Autowired
+ private NotificationRepository repository;
+
+ @Autowired
+ private DelayedNotificationScheduler scheduler;
+
+ @Test
+ public void whenTimeIsOverNotificationSendOutTime_thenItShouldBeSent() {
+ ZonedDateTime fiveMinutesAgo = ZonedDateTime.now(testClock).minusMinutes(5);
+ Notification notification = new Notification(fiveMinutesAgo);
+ repository.save(notification);
+
+ scheduler.attemptSendingOutDelayedNotifications();
+
+ Notification processedNotification = repository.findById(notification.getId());
+ assertTrue(processedNotification.isSentOut());
+ }
+}
+
+@TestConfiguration
+class SchedulerTestConfiguration {
+
+ @Bean
+ @Primary
+ public Clock testClock() {
+ return Clock.fixed(Instant.parse("2024-03-10T10:15:30.00Z"), ZoneId.systemDefault());
+ }
+}
\ No newline at end of file
diff --git a/spring-security-modules/spring-security-legacy-oidc/pom.xml b/spring-security-modules/spring-security-legacy-oidc/pom.xml
index 10c6eb3389..0fb10c7e4f 100644
--- a/spring-security-modules/spring-security-legacy-oidc/pom.xml
+++ b/spring-security-modules/spring-security-legacy-oidc/pom.xml
@@ -42,6 +42,12 @@
jwks-rsa
${jwks-rsa.version}
+
+ net.bytebuddy
+ byte-buddy
+ 1.14.13
+ test
+
diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/pom.xml b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/pom.xml
index d4fff21605..c1795b500c 100644
--- a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/pom.xml
+++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/pom.xml
@@ -77,7 +77,6 @@
true
true
5.9.3
- 5.3.1
3.1.1.RELEASE
3.1.1
diff --git a/testing-modules/junit-5-basics-2/pom.xml b/testing-modules/junit-5-basics-2/pom.xml
index d8bb2a6e79..27681d66eb 100644
--- a/testing-modules/junit-5-basics-2/pom.xml
+++ b/testing-modules/junit-5-basics-2/pom.xml
@@ -26,7 +26,7 @@
org.mockito
mockito-core
- ${mockito-core.version}
+ ${mockito.version}
test
@@ -42,7 +42,6 @@
5.10.0
- 5.5.0
\ No newline at end of file
diff --git a/testing-modules/junit-5/pom.xml b/testing-modules/junit-5/pom.xml
index cdddf90855..63162e71e8 100644
--- a/testing-modules/junit-5/pom.xml
+++ b/testing-modules/junit-5/pom.xml
@@ -89,11 +89,6 @@
${powermock.version}
test
-
- org.mockito
- mockito-core
- test
-
@@ -135,7 +130,7 @@
2.17.1
2.0.9
5.0.1.RELEASE
- 3.3.0
+ 3.3.0
\ No newline at end of file
diff --git a/testing-modules/mockito-2/pom.xml b/testing-modules/mockito-2/pom.xml
index 79b8c86221..f4ff2da682 100644
--- a/testing-modules/mockito-2/pom.xml
+++ b/testing-modules/mockito-2/pom.xml
@@ -34,8 +34,8 @@
4.8.1
- 5.10.0
1.18.30
+
\ No newline at end of file
diff --git a/testing-modules/mockito-simple/pom.xml b/testing-modules/mockito-simple/pom.xml
index 6f50136de6..7a07ea73ee 100644
--- a/testing-modules/mockito-simple/pom.xml
+++ b/testing-modules/mockito-simple/pom.xml
@@ -60,7 +60,6 @@
6.0.8
- 5.3.1
\ No newline at end of file
diff --git a/testing-modules/powermock/pom.xml b/testing-modules/powermock/pom.xml
index 8eedc818af..0c3b1c367f 100644
--- a/testing-modules/powermock/pom.xml
+++ b/testing-modules/powermock/pom.xml
@@ -41,7 +41,7 @@
- 2.21.0
+ 2.21.0
2.0.9
diff --git a/vaadin/.gitignore b/vaadin/.gitignore
new file mode 100644
index 0000000000..1ef3efefbd
--- /dev/null
+++ b/vaadin/.gitignore
@@ -0,0 +1 @@
+frontend/generated
\ No newline at end of file
diff --git a/vaadin/frontend/index.html b/vaadin/frontend/index.html
new file mode 100644
index 0000000000..d36e593475
--- /dev/null
+++ b/vaadin/frontend/index.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vaadin/pom.xml b/vaadin/pom.xml
index e3786471f5..ea9a3ed75a 100644
--- a/vaadin/pom.xml
+++ b/vaadin/pom.xml
@@ -1,13 +1,12 @@
+ 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
org.test
vaadin
1.0-SNAPSHOT
vaadin
- war
com.baeldung
@@ -16,6 +15,11 @@
../parent-boot-3
+
+ 17
+ 24.3.3
+
+
@@ -30,39 +34,24 @@
- javax.servlet
- javax.servlet-api
- 4.0.1
- provided
+ com.vaadin
+ vaadin-core
com.vaadin
- vaadin-server
- ${vaadin-server.version}
-
-
- com.vaadin
- vaadin-push
- ${vaadin-push.version}
-
-
- com.vaadin
- vaadin-client-compiled
- ${vaadin-client-compiled.version}
-
-
- com.vaadin
- vaadin-themes
- ${vaadin-themes.version}
+ vaadin-spring-boot-starter
org.springframework.boot
spring-boot-starter-data-jpa
- com.vaadin
- vaadin-spring-boot-starter
- ${vaadin-spring-boot-starter.version}
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ io.projectreactor
+ reactor-core
com.h2database
@@ -77,47 +66,17 @@
-
- org.apache.maven.plugins
- maven-war-plugin
- ${maven-war-plugin.version}
-
- false
-
- WEB-INF/classes/VAADIN/widgetsets/WEB-INF/**
-
-
com.vaadin
vaadin-maven-plugin
- ${vaadin.plugin.version}
-
-
- org.apache.maven.plugins
- maven-clean-plugin
- ${maven-clean-plugin.version}
-
-
-
-
- src/main/webapp/VAADIN/themes
-
- **/styles.css
- **/styles.scss.cache
-
-
-
-
-
-
-
-
- org.eclipse.jetty
- jetty-maven-plugin
- ${jetty.plugin.version}
-
- 2
-
+ ${vaadin.version}
+
+
+
+ prepare-frontend
+
+
+
org.springframework.boot
@@ -126,68 +85,41 @@
-
-
- vaadin-addons
- https://maven.vaadin.com/vaadin-addons
-
-
-
- vaadin-prerelease
-
- false
-
-
-
-
- vaadin-prereleases
- https://maven.vaadin.com/vaadin-prereleases
-
-
- vaadin-snapshots
- https://oss.sonatype.org/content/repositories/vaadin-snapshots/
-
- false
-
-
- true
-
-
-
-
-
- vaadin-prereleases
- https://maven.vaadin.com/vaadin-prereleases
-
-
- vaadin-snapshots
- https://oss.sonatype.org/content/repositories/vaadin-snapshots/
-
- false
-
-
- true
-
-
-
+
+ production
+
+
+
+ com.vaadin
+ vaadin-core
+
+
+ com.vaadin
+ vaadin-dev
+
+
+
+
+
+
+
+ com.vaadin
+ vaadin-maven-plugin
+ ${vaadin.version}
+
+
+
+ build-frontend
+
+ compile
+
+
+
+
+
-
-
- 13.0.9
- 13.0.9
- 13.0.9
- 8.8.5
- 8.8.5
- 8.8.5
- 8.8.5
- 9.3.9.v20160517
- local
- mytheme
- 3.0.0
-
-
\ No newline at end of file
diff --git a/vaadin/src/main/java/com/baeldung/Application.java b/vaadin/src/main/java/com/baeldung/Application.java
index 1d3084723a..b62dd79158 100644
--- a/vaadin/src/main/java/com/baeldung/Application.java
+++ b/vaadin/src/main/java/com/baeldung/Application.java
@@ -1,15 +1,19 @@
package com.baeldung;
+import com.baeldung.data.Employee;
+import com.baeldung.data.EmployeeRepository;
+import com.vaadin.flow.component.page.AppShellConfigurator;
+import com.vaadin.flow.component.page.Push;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
+@Push
@SpringBootApplication
-public class Application {
+public class Application implements AppShellConfigurator {
private static final Logger log = LoggerFactory.getLogger(Application.class);
diff --git a/vaadin/src/main/java/com/baeldung/EmployeeEditor.java b/vaadin/src/main/java/com/baeldung/EmployeeEditor.java
deleted file mode 100644
index ee312786d1..0000000000
--- a/vaadin/src/main/java/com/baeldung/EmployeeEditor.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package com.baeldung;
-
-import com.vaadin.flow.component.Key;
-import com.vaadin.flow.component.KeyNotifier;
-import com.vaadin.flow.component.button.Button;
-import com.vaadin.flow.component.icon.VaadinIcon;
-import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
-import com.vaadin.flow.component.orderedlayout.VerticalLayout;
-import com.vaadin.flow.component.textfield.TextField;
-import com.vaadin.flow.data.binder.Binder;
-import com.vaadin.flow.spring.annotation.SpringComponent;
-import com.vaadin.flow.spring.annotation.UIScope;
-import org.springframework.beans.factory.annotation.Autowired;
-
-@SpringComponent
-@UIScope
-public class EmployeeEditor extends VerticalLayout implements KeyNotifier {
-
- private final EmployeeRepository repository;
-
- private Employee employee;
-
- TextField firstName = new TextField("First name");
- TextField lastName = new TextField("Last name");
-
- Button save = new Button("Save", VaadinIcon.CHECK.create());
- Button cancel = new Button("Cancel");
- Button delete = new Button("Delete", VaadinIcon.TRASH.create());
- HorizontalLayout actions = new HorizontalLayout(save, cancel, delete);
-
- Binder binder = new Binder<>(Employee.class);
- private ChangeHandler changeHandler;
-
- @Autowired
- public EmployeeEditor(EmployeeRepository repository) {
- this.repository = repository;
-
- add(firstName, lastName, actions);
-
- binder.bindInstanceFields(this);
-
- setSpacing(true);
-
- save.getElement().getThemeList().add("primary");
- delete.getElement().getThemeList().add("error");
-
- addKeyPressListener(Key.ENTER, e -> save());
-
- save.addClickListener(e -> save());
- delete.addClickListener(e -> delete());
- cancel.addClickListener(e -> editEmployee(employee));
- setVisible(false);
- }
-
- void delete() {
- repository.delete(employee);
- changeHandler.onChange();
- }
-
- void save() {
- repository.save(employee);
- changeHandler.onChange();
- }
-
- public interface ChangeHandler {
- void onChange();
- }
-
- public final void editEmployee(Employee c) {
- if (c == null) {
- setVisible(false);
- return;
- }
- final boolean persisted = c.getId() != null;
- if (persisted) {
- employee = repository.findById(c.getId()).get();
- } else {
- employee = c;
- }
-
- cancel.setVisible(persisted);
- binder.setBean(employee);
- setVisible(true);
- firstName.focus();
- }
-
- public void setChangeHandler(ChangeHandler h) {
- changeHandler = h;
- }
-}
diff --git a/vaadin/src/main/java/com/baeldung/IndexView.java b/vaadin/src/main/java/com/baeldung/IndexView.java
new file mode 100644
index 0000000000..45ab534ef6
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/IndexView.java
@@ -0,0 +1,25 @@
+package com.baeldung;
+
+import com.baeldung.introduction.PushView;
+import com.baeldung.introduction.basics.VaadinFlowBasics;
+import com.baeldung.introduction.FormView;
+import com.baeldung.introduction.GridView;
+import com.baeldung.spring.EmployeesView;
+import com.vaadin.flow.component.html.H1;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.router.Route;
+import com.vaadin.flow.router.RouterLink;
+
+@Route("")
+public class IndexView extends VerticalLayout {
+
+ public IndexView() {
+ add(new H1("Vaadin Flow examples"));
+
+ add(new RouterLink("Basics", VaadinFlowBasics.class));
+ add(new RouterLink("Grid", GridView.class));
+ add(new RouterLink("Form", FormView.class));
+ add(new RouterLink("Push", PushView.class));
+ add(new RouterLink("CRUD", EmployeesView.class));
+ }
+}
diff --git a/vaadin/src/main/java/com/baeldung/MainView.java b/vaadin/src/main/java/com/baeldung/MainView.java
deleted file mode 100644
index 6d4c0aaa88..0000000000
--- a/vaadin/src/main/java/com/baeldung/MainView.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.baeldung;
-
-import org.springframework.util.StringUtils;
-
-import com.vaadin.flow.component.button.Button;
-import com.vaadin.flow.component.grid.Grid;
-import com.vaadin.flow.component.icon.VaadinIcon;
-import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
-import com.vaadin.flow.component.orderedlayout.VerticalLayout;
-import com.vaadin.flow.component.textfield.TextField;
-import com.vaadin.flow.data.value.ValueChangeMode;
-import com.vaadin.flow.router.Route;
-
-@Route
-public class MainView extends VerticalLayout {
-
- private final EmployeeRepository employeeRepository;
-
- private final EmployeeEditor editor;
-
- final Grid grid;
-
- final TextField filter;
-
- private final Button addNewBtn;
-
- public MainView(EmployeeRepository repo, EmployeeEditor editor) {
- this.employeeRepository = repo;
- this.editor = editor;
- this.grid = new Grid<>(Employee.class);
- this.filter = new TextField();
- this.addNewBtn = new Button("New employee", VaadinIcon.PLUS.create());
-
- HorizontalLayout actions = new HorizontalLayout(filter, addNewBtn);
- add(actions, grid, editor);
-
- grid.setHeight("200px");
- grid.setColumns("id", "firstName", "lastName");
- grid.getColumnByKey("id").setWidth("50px").setFlexGrow(0);
-
- filter.setPlaceholder("Filter by last name");
-
- filter.setValueChangeMode(ValueChangeMode.EAGER);
- filter.addValueChangeListener(e -> listEmployees(e.getValue()));
-
- grid.asSingleSelect().addValueChangeListener(e -> {
- editor.editEmployee(e.getValue());
- });
-
- addNewBtn.addClickListener(e -> editor.editEmployee(new Employee("", "")));
-
- editor.setChangeHandler(() -> {
- editor.setVisible(false);
- listEmployees(filter.getValue());
- });
-
- listEmployees(null);
- }
-
- void listEmployees(String filterText) {
- if (StringUtils.isEmpty(filterText)) {
- grid.setItems(employeeRepository.findAll());
- } else {
- grid.setItems(employeeRepository.findByLastNameStartsWithIgnoreCase(filterText));
- }
- }
-}
diff --git a/vaadin/src/main/java/com/baeldung/data/Contact.java b/vaadin/src/main/java/com/baeldung/data/Contact.java
new file mode 100644
index 0000000000..8e534d5bb0
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/data/Contact.java
@@ -0,0 +1,73 @@
+package com.baeldung.data;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.Id;
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Pattern;
+
+@Entity
+public class Contact {
+
+ @Id
+ @GeneratedValue
+ private Long id;
+ @NotBlank
+ private String name;
+ @Email
+ private String email;
+ @Pattern(regexp = "\\d{3}-\\d{3}-\\d{4}")
+ private String phone;
+
+ public Contact() {
+ }
+
+ public Contact(String name, String email, String phone) {
+ this.name = name;
+ this.email = email;
+ this.phone = phone;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ @Override
+ public String toString() {
+ return "Contact {" +
+ "id=" + id +
+ ", name='" + name + "'" +
+ ", email='" + email + "'" +
+ ", phone='" + phone + "'" +
+ " }";
+ }
+}
diff --git a/vaadin/src/main/java/com/baeldung/data/ContactRepository.java b/vaadin/src/main/java/com/baeldung/data/ContactRepository.java
new file mode 100644
index 0000000000..15c4adaaa9
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/data/ContactRepository.java
@@ -0,0 +1,6 @@
+package com.baeldung.data;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface ContactRepository extends JpaRepository {
+}
diff --git a/vaadin/src/main/java/com/baeldung/data/DataInitializer.java b/vaadin/src/main/java/com/baeldung/data/DataInitializer.java
new file mode 100644
index 0000000000..dba162d4e4
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/data/DataInitializer.java
@@ -0,0 +1,46 @@
+package com.baeldung.data;
+
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+@Component
+public class DataInitializer implements CommandLineRunner {
+
+ private final ContactRepository contactRepository;
+
+ public DataInitializer(ContactRepository contactRepository) {
+ this.contactRepository = contactRepository;
+ }
+
+ private final List firstNames = List.of(
+ "John", "Jane", "Emily", "Michael", "Sarah", "James", "Mary", "Robert",
+ "Patricia", "William", "Linda", "David", "Barbara", "Richard", "Susan",
+ "Joseph", "Jessica", "Thomas", "Karen", "Charles"
+ );
+ private final List lastNames = List.of(
+ "Doe", "Smith", "Johnson", "Brown", "Davis", "Miller", "Wilson", "Moore",
+ "Taylor", "Anderson", "Thomas", "Jackson", "White", "Harris", "Martin",
+ "Thompson", "Garcia", "Martinez", "Robinson", "Clark"
+ );
+
+ @Override
+ public void run(String... args) throws Exception {
+ var contacts = new ArrayList();
+ Random random = new Random();
+
+ for (int i = 0; i < 100; i++) {
+ String firstName = firstNames.get(random.nextInt(firstNames.size()));
+ String lastName = lastNames.get(random.nextInt(lastNames.size()));
+ String email = String.format("%s.%s@example.com", firstName.toLowerCase(), lastName.toLowerCase());
+ String phone = String.format("555-%03d-%04d", random.nextInt(1000), random.nextInt(10000));
+
+ contacts.add(new Contact(firstName + " " + lastName, email, phone));
+ }
+
+ contactRepository.saveAll(contacts);
+ }
+}
diff --git a/vaadin/src/main/java/com/baeldung/Employee.java b/vaadin/src/main/java/com/baeldung/data/Employee.java
similarity index 75%
rename from vaadin/src/main/java/com/baeldung/Employee.java
rename to vaadin/src/main/java/com/baeldung/data/Employee.java
index 75a0dc84b3..cdaa426eeb 100644
--- a/vaadin/src/main/java/com/baeldung/Employee.java
+++ b/vaadin/src/main/java/com/baeldung/data/Employee.java
@@ -1,8 +1,10 @@
-package com.baeldung;
+package com.baeldung.data;
+
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
+import jakarta.validation.constraints.Size;
@Entity
public class Employee {
@@ -11,11 +13,13 @@ public class Employee {
@GeneratedValue
private Long id;
+ @Size(min = 2, message = "First name must have at least 2 characters")
private String firstName;
+ @Size(min = 2, message = "Last name must have at least 2 characters")
private String lastName;
- protected Employee() {
+ public Employee() {
}
public Employee(String firstName, String lastName) {
@@ -27,6 +31,10 @@ public class Employee {
return id;
}
+ public void setId(Long id) {
+ this.id = id;
+ }
+
public String getFirstName() {
return firstName;
}
diff --git a/vaadin/src/main/java/com/baeldung/EmployeeRepository.java b/vaadin/src/main/java/com/baeldung/data/EmployeeRepository.java
similarity index 89%
rename from vaadin/src/main/java/com/baeldung/EmployeeRepository.java
rename to vaadin/src/main/java/com/baeldung/data/EmployeeRepository.java
index 044160da78..0d54148c85 100644
--- a/vaadin/src/main/java/com/baeldung/EmployeeRepository.java
+++ b/vaadin/src/main/java/com/baeldung/data/EmployeeRepository.java
@@ -1,4 +1,4 @@
-package com.baeldung;
+package com.baeldung.data;
import java.util.List;
diff --git a/vaadin/src/main/java/com/baeldung/introduction/BindData.java b/vaadin/src/main/java/com/baeldung/introduction/BindData.java
deleted file mode 100644
index 299554c039..0000000000
--- a/vaadin/src/main/java/com/baeldung/introduction/BindData.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.baeldung.introduction;
-
-public class BindData {
-
- private String bindName;
-
- public BindData(String bindName){
- this.bindName = bindName;
- }
-
- public String getBindName() {
- return bindName;
- }
-
- public void setBindName(String bindName) {
- this.bindName = bindName;
- }
-
-
-}
diff --git a/vaadin/src/main/java/com/baeldung/introduction/FormView.java b/vaadin/src/main/java/com/baeldung/introduction/FormView.java
new file mode 100644
index 0000000000..34bc334b27
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/introduction/FormView.java
@@ -0,0 +1,88 @@
+package com.baeldung.introduction;
+
+import com.baeldung.data.Contact;
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.html.H2;
+import com.vaadin.flow.component.notification.Notification;
+import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.component.textfield.TextField;
+import com.vaadin.flow.data.binder.BeanValidationBinder;
+import com.vaadin.flow.data.binder.Binder;
+import com.vaadin.flow.router.Route;
+
+@Route("form")
+public class FormView extends HorizontalLayout {
+
+ public FormView() {
+ addBeanValidationExample();
+ addCustomValidationExample();
+ }
+
+ private void addBeanValidationExample() {
+ var nameField = new TextField("Name");
+ var emailField = new TextField("Email");
+ var phoneField = new TextField("Phone");
+ var saveButton = new Button("Save");
+
+ var binder = new BeanValidationBinder<>(Contact.class);
+
+ binder.forField(nameField).bind(Contact::getName, Contact::setName);
+ binder.forField(emailField).bind(Contact::getEmail, Contact::setEmail);
+ binder.forField(phoneField).bind(Contact::getPhone, Contact::setPhone);
+
+ var contact = new Contact("John Doe", "john@doe.com", "123-456-7890");
+ binder.setBean(contact);
+
+ saveButton.addClickListener(e -> {
+ if (binder.validate().isOk()) {
+ Notification.show("Saved " + contact);
+ }
+ });
+
+ add(new VerticalLayout(
+ new H2("Bean Validation Example"),
+ nameField,
+ emailField,
+ phoneField,
+ saveButton
+ ));
+ }
+
+ private void addCustomValidationExample() {
+
+ var nameField = new TextField("Name");
+ var emailField = new TextField("Email");
+ var phoneField = new TextField("Phone");
+ var saveButton = new Button("Save");
+
+ var binder = new Binder<>(Contact.class);
+
+ binder.forField(nameField)
+ .asRequired()
+ .bind(Contact::getName, Contact::setName);
+ binder.forField(emailField)
+ .withValidator(email -> email.contains("@"), "Not a valid email address")
+ .bind(Contact::getEmail, Contact::setEmail);
+ binder.forField(phoneField)
+ .withValidator(phone -> phone.matches("\\d{3}-\\d{3}-\\d{4}"), "Not a valid phone number")
+ .bind(Contact::getPhone, Contact::setPhone);
+
+ var contact = new Contact("John Doe", "john@doe.com", "123-456-7890");
+ binder.setBean(contact);
+
+ saveButton.addClickListener(e -> {
+ if (binder.validate().isOk()) {
+ Notification.show("Saved " + contact);
+ }
+ });
+
+ add(new VerticalLayout(
+ new H2("Custom Validation Example"),
+ nameField,
+ emailField,
+ phoneField,
+ saveButton
+ ));
+ }
+}
diff --git a/vaadin/src/main/java/com/baeldung/introduction/GridView.java b/vaadin/src/main/java/com/baeldung/introduction/GridView.java
new file mode 100644
index 0000000000..3d9500d7d8
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/introduction/GridView.java
@@ -0,0 +1,40 @@
+package com.baeldung.introduction;
+
+import com.baeldung.data.Contact;
+import com.baeldung.data.ContactRepository;
+import com.vaadin.flow.component.grid.Grid;
+import com.vaadin.flow.component.html.H1;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.router.Route;
+import com.vaadin.flow.spring.data.VaadinSpringDataHelpers;
+
+@Route("grid")
+public class GridView extends VerticalLayout {
+
+ public GridView(ContactRepository contactRepository) {
+
+ add(new H1("Using data grids"));
+
+ // Define a grid for a Contact entity
+ var grid = new Grid();
+ grid.addColumn(Contact::getName).setHeader("Name");
+ grid.addColumn(Contact::getEmail).setHeader("Email");
+ grid.addColumn(Contact::getPhone).setHeader("Phone");
+
+ // There are two ways to populate the grid with data:
+
+ // 1) In-memory with a list of items
+ var contacts = contactRepository.findAll();
+ grid.setItems(contacts);
+
+ // 2) with a callback to lazily load items from a data source.
+ grid.setItems(query -> {
+ // Turn the page, offset, filter, sort and other info in query into a Spring Data PageRequest
+ var pageRequest = VaadinSpringDataHelpers.toSpringPageRequest(query);
+ return contactRepository.findAll(pageRequest).stream();
+ });
+
+ add(grid);
+
+ }
+}
diff --git a/vaadin/src/main/java/com/baeldung/introduction/PushView.java b/vaadin/src/main/java/com/baeldung/introduction/PushView.java
new file mode 100644
index 0000000000..b49aa06e4d
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/introduction/PushView.java
@@ -0,0 +1,32 @@
+package com.baeldung.introduction;
+
+import com.vaadin.flow.component.html.Span;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.router.Route;
+import reactor.core.publisher.Flux;
+
+import java.time.Duration;
+import java.time.Instant;
+
+// Ensure you have @Push annotation in your Application class
+@Route("push")
+public class PushView extends VerticalLayout {
+
+ public PushView() {
+ var output = new Span();
+
+ // Publish server time once a second
+ var serverTime = Flux.interval(Duration.ofSeconds(1))
+ .map(o -> "Server time: " + Instant.now());
+
+
+ serverTime.subscribe(time ->
+ // ui.access is required to update the UI from a background thread
+ getUI().ifPresent(ui ->
+ ui.access(() -> output.setText(time))
+ )
+ );
+
+ add(output);
+ }
+}
diff --git a/vaadin/src/main/java/com/baeldung/introduction/Row.java b/vaadin/src/main/java/com/baeldung/introduction/Row.java
deleted file mode 100644
index 412a286376..0000000000
--- a/vaadin/src/main/java/com/baeldung/introduction/Row.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.baeldung.introduction;
-
-public class Row {
-
- private String column1;
-
- private String column2;
-
- private String column3;
-
- public Row() {
-
- }
-
- public Row(String column1, String column2, String column3) {
- super();
- this.column1 = column1;
- this.column2 = column2;
- this.column3 = column3;
- }
-
- public String getColumn1() {
- return column1;
- }
-
- public void setColumn1(String column1) {
- this.column1 = column1;
- }
-
- public String getColumn2() {
- return column2;
- }
-
- public void setColumn2(String column2) {
- this.column2 = column2;
- }
-
- public String getColumn3() {
- return column3;
- }
-
- public void setColumn3(String column3) {
- this.column3 = column3;
- }
-}
\ No newline at end of file
diff --git a/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java b/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java
deleted file mode 100644
index 05a8340bde..0000000000
--- a/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java
+++ /dev/null
@@ -1,281 +0,0 @@
-package com.baeldung.introduction;
-
-import java.time.Instant;
-import java.time.LocalDate;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import com.vaadin.annotations.Push;
-import com.vaadin.annotations.Theme;
-import com.vaadin.annotations.VaadinServletConfiguration;
-import com.vaadin.data.Binder;
-import com.vaadin.data.validator.StringLengthValidator;
-import com.vaadin.icons.VaadinIcons;
-import com.vaadin.server.ExternalResource;
-import com.vaadin.server.VaadinRequest;
-import com.vaadin.server.VaadinServlet;
-import com.vaadin.ui.Button;
-import com.vaadin.ui.CheckBox;
-import com.vaadin.ui.ComboBox;
-import com.vaadin.ui.DateField;
-import com.vaadin.ui.FormLayout;
-import com.vaadin.ui.Grid;
-import com.vaadin.ui.GridLayout;
-import com.vaadin.ui.HorizontalLayout;
-import com.vaadin.ui.InlineDateField;
-import com.vaadin.ui.Label;
-import com.vaadin.ui.Link;
-import com.vaadin.ui.ListSelect;
-import com.vaadin.ui.NativeButton;
-import com.vaadin.ui.NativeSelect;
-import com.vaadin.ui.Panel;
-import com.vaadin.ui.PasswordField;
-import com.vaadin.ui.RichTextArea;
-import com.vaadin.ui.TextArea;
-import com.vaadin.ui.TextField;
-import com.vaadin.ui.TwinColSelect;
-import com.vaadin.ui.UI;
-import com.vaadin.ui.VerticalLayout;
-import jakarta.servlet.annotation.WebServlet;
-
-@SuppressWarnings("serial")
-@Push
-@Theme("mytheme")
-public class VaadinUI extends UI {
-
- private Label currentTime;
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- @Override
- protected void init(VaadinRequest vaadinRequest) {
- final VerticalLayout verticalLayout = new VerticalLayout();
- verticalLayout.setSpacing(true);
- verticalLayout.setMargin(true);
- final GridLayout gridLayout = new GridLayout(3, 2);
- gridLayout.setSpacing(true);
- gridLayout.setMargin(true);
- final HorizontalLayout horizontalLayout = new HorizontalLayout();
- horizontalLayout.setSpacing(true);
- horizontalLayout.setMargin(true);
- final FormLayout formLayout = new FormLayout();
- formLayout.setSpacing(true);
- formLayout.setMargin(true);
- final GridLayout buttonLayout = new GridLayout(3, 5);
- buttonLayout.setMargin(true);
- buttonLayout.setSpacing(true);
-
- final Label label = new Label();
- label.setId("Label");
- label.setValue("Label Value");
- label.setCaption("Label");
- gridLayout.addComponent(label);
-
- final Link link = new Link("Baeldung", new ExternalResource("http://www.baeldung.com/"));
- link.setId("Link");
- link.setTargetName("_blank");
- gridLayout.addComponent(link);
-
- final TextField textField = new TextField();
- textField.setId("TextField");
- textField.setCaption("TextField:");
- textField.setValue("TextField Value");
- textField.setIcon(VaadinIcons.USER);
- gridLayout.addComponent(textField);
-
- final TextArea textArea = new TextArea();
- textArea.setCaption("TextArea");
- textArea.setId("TextArea");
- textArea.setValue("TextArea Value");
- gridLayout.addComponent(textArea);
-
- final DateField dateField = new DateField("DateField", LocalDate.ofEpochDay(0));
- dateField.setId("DateField");
- gridLayout.addComponent(dateField);
-
- final PasswordField passwordField = new PasswordField();
- passwordField.setId("PasswordField");
- passwordField.setCaption("PasswordField:");
- passwordField.setValue("password");
- gridLayout.addComponent(passwordField);
-
- final RichTextArea richTextArea = new RichTextArea();
- richTextArea.setCaption("Rich Text Area");
- richTextArea.setValue("RichTextArea
");
- richTextArea.setSizeFull();
-
- Panel richTextPanel = new Panel();
- richTextPanel.setContent(richTextArea);
-
- final InlineDateField inlineDateField = new InlineDateField();
- inlineDateField.setValue(LocalDate.ofEpochDay(0));
- inlineDateField.setCaption("Inline Date Field");
- horizontalLayout.addComponent(inlineDateField);
-
- Button normalButton = new Button("Normal Button");
- normalButton.setId("NormalButton");
- normalButton.addClickListener(e -> {
- label.setValue("CLICK");
- });
- buttonLayout.addComponent(normalButton);
-
- Button tinyButton = new Button("Tiny Button");
- tinyButton.addStyleName("tiny");
- buttonLayout.addComponent(tinyButton);
-
- Button smallButton = new Button("Small Button");
- smallButton.addStyleName("small");
- buttonLayout.addComponent(smallButton);
-
- Button largeButton = new Button("Large Button");
- largeButton.addStyleName("large");
- buttonLayout.addComponent(largeButton);
-
- Button hugeButton = new Button("Huge Button");
- hugeButton.addStyleName("huge");
- buttonLayout.addComponent(hugeButton);
-
- Button disabledButton = new Button("Disabled Button");
- disabledButton.setDescription("This button cannot be clicked");
- disabledButton.setEnabled(false);
- buttonLayout.addComponent(disabledButton);
-
- Button dangerButton = new Button("Danger Button");
- dangerButton.addStyleName("danger");
- buttonLayout.addComponent(dangerButton);
-
- Button friendlyButton = new Button("Friendly Button");
- friendlyButton.addStyleName("friendly");
- buttonLayout.addComponent(friendlyButton);
-
- Button primaryButton = new Button("Primary Button");
- primaryButton.addStyleName("primary");
- buttonLayout.addComponent(primaryButton);
-
- NativeButton nativeButton = new NativeButton("Native Button");
- buttonLayout.addComponent(nativeButton);
-
- Button iconButton = new Button("Icon Button");
- iconButton.setIcon(VaadinIcons.ALIGN_LEFT);
- buttonLayout.addComponent(iconButton);
-
- Button borderlessButton = new Button("BorderLess Button");
- borderlessButton.addStyleName("borderless");
- buttonLayout.addComponent(borderlessButton);
-
- Button linkButton = new Button("Link Button");
- linkButton.addStyleName("link");
- buttonLayout.addComponent(linkButton);
-
- Button quietButton = new Button("Quiet Button");
- quietButton.addStyleName("quiet");
- buttonLayout.addComponent(quietButton);
-
- horizontalLayout.addComponent(buttonLayout);
-
- final CheckBox checkbox = new CheckBox("CheckBox");
- checkbox.setValue(true);
- checkbox.addValueChangeListener(e -> checkbox.setValue(!checkbox.getValue()));
- formLayout.addComponent(checkbox);
-
- List numbers = new ArrayList();
- numbers.add("One");
- numbers.add("Ten");
- numbers.add("Eleven");
- ComboBox comboBox = new ComboBox("ComboBox");
- comboBox.setItems(numbers);
- formLayout.addComponent(comboBox);
-
- ListSelect listSelect = new ListSelect("ListSelect");
- listSelect.setItems(numbers);
- listSelect.setRows(2);
- formLayout.addComponent(listSelect);
-
- NativeSelect nativeSelect = new NativeSelect("NativeSelect");
- nativeSelect.setItems(numbers);
- formLayout.addComponent(nativeSelect);
-
- TwinColSelect twinColSelect = new TwinColSelect("TwinColSelect");
- twinColSelect.setItems(numbers);
-
- Grid grid = new Grid(Row.class);
- grid.setColumns("column1", "column2", "column3");
- Row row1 = new Row("Item1", "Item2", "Item3");
- Row row2 = new Row("Item4", "Item5", "Item6");
- List rows = new ArrayList();
- rows.add(row1);
- rows.add(row2);
- grid.setItems(rows);
-
- Panel panel = new Panel("Panel");
- panel.setContent(grid);
- panel.setSizeUndefined();
-
- Panel serverPushPanel = new Panel("Server Push");
- FormLayout timeLayout = new FormLayout();
- timeLayout.setSpacing(true);
- timeLayout.setMargin(true);
- currentTime = new Label("No TIME...");
- timeLayout.addComponent(currentTime);
- serverPushPanel.setContent(timeLayout);
- serverPushPanel.setSizeUndefined();
- ScheduledExecutorService scheduleExecutor = Executors.newScheduledThreadPool(1);
- Runnable task = () -> {
- currentTime.setValue("Current Time : " + Instant.now());
- };
- scheduleExecutor.scheduleWithFixedDelay(task, 0, 1, TimeUnit.SECONDS);
-
- FormLayout dataBindingLayout = new FormLayout();
- dataBindingLayout.setSpacing(true);
- dataBindingLayout.setMargin(true);
-
- Binder binder = new Binder<>();
- BindData bindData = new BindData("BindData");
- binder.readBean(bindData);
- TextField bindedTextField = new TextField();
- bindedTextField.setWidth("250px");
- binder.forField(bindedTextField).bind(BindData::getBindName, BindData::setBindName);
- dataBindingLayout.addComponent(bindedTextField);
-
- FormLayout validatorLayout = new FormLayout();
- validatorLayout.setSpacing(true);
- validatorLayout.setMargin(true);
-
- HorizontalLayout textValidatorLayout = new HorizontalLayout();
- textValidatorLayout.setSpacing(true);
- textValidatorLayout.setMargin(true);
-
-
- BindData stringValidatorBindData = new BindData("");
- TextField stringValidator = new TextField();
- Binder stringValidatorBinder = new Binder<>();
- stringValidatorBinder.setBean(stringValidatorBindData);
- stringValidatorBinder.forField(stringValidator)
- .withValidator(new StringLengthValidator("String must have 2-5 characters lenght", 2, 5))
- .bind(BindData::getBindName, BindData::setBindName);
-
- textValidatorLayout.addComponent(stringValidator);
- Button buttonStringValidator = new Button("Validate String");
- buttonStringValidator.addClickListener(e -> stringValidatorBinder.validate());
- textValidatorLayout.addComponent(buttonStringValidator);
-
- validatorLayout.addComponent(textValidatorLayout);
- verticalLayout.addComponent(gridLayout);
- verticalLayout.addComponent(richTextPanel);
- verticalLayout.addComponent(horizontalLayout);
- verticalLayout.addComponent(formLayout);
- verticalLayout.addComponent(twinColSelect);
- verticalLayout.addComponent(panel);
- verticalLayout.addComponent(serverPushPanel);
- verticalLayout.addComponent(dataBindingLayout);
- verticalLayout.addComponent(validatorLayout);
- setContent(verticalLayout);
- }
-
- @WebServlet(urlPatterns = "/VAADIN/*", name = "MyUIServlet", asyncSupported = true)
- @VaadinServletConfiguration(ui = VaadinUI.class, productionMode = false)
- public static class MyUIServlet extends VaadinServlet {
- }
-}
\ No newline at end of file
diff --git a/vaadin/src/main/java/com/baeldung/introduction/basics/ExampleLayout.java b/vaadin/src/main/java/com/baeldung/introduction/basics/ExampleLayout.java
new file mode 100644
index 0000000000..6d6e2b2b7d
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/introduction/basics/ExampleLayout.java
@@ -0,0 +1,45 @@
+package com.baeldung.introduction.basics;
+
+import com.baeldung.data.Contact;
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.grid.Grid;
+import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.component.splitlayout.SplitLayout;
+import com.vaadin.flow.component.textfield.TextField;
+import com.vaadin.flow.router.Route;
+
+import java.util.List;
+
+@Route("example-layout")
+public class ExampleLayout extends SplitLayout {
+
+ public ExampleLayout() {
+ var grid = new Grid<>(Contact.class);
+ grid.setColumns("name", "email", "phone");
+ grid.setItems(List.of(
+ new Contact("John Doe", "john@doe.com", "123 456 789"),
+ new Contact("Jane Doe", "jane@doe.com", "987 654 321")
+ ));
+
+ var form = new VerticalLayout();
+
+ var nameField = new TextField("Name");
+ var emailField = new TextField("Email");
+ var phoneField = new TextField("Phone");
+ var saveButton = new Button("Save");
+ var cancelButton = new Button("Cancel");
+
+ form.add(
+ nameField,
+ emailField,
+ phoneField,
+ new HorizontalLayout(saveButton, cancelButton)
+ );
+
+ setSizeFull();
+ setSplitterPosition(70);
+ addToPrimary(grid);
+ addToSecondary(form);
+ }
+}
diff --git a/vaadin/src/main/java/com/baeldung/introduction/basics/HelloWorldView.java b/vaadin/src/main/java/com/baeldung/introduction/basics/HelloWorldView.java
new file mode 100644
index 0000000000..477cf378c6
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/introduction/basics/HelloWorldView.java
@@ -0,0 +1,13 @@
+package com.baeldung.introduction.basics;
+
+import com.vaadin.flow.component.html.H1;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.router.Route;
+
+@Route("hello-world")
+public class HelloWorldView extends VerticalLayout {
+
+ public HelloWorldView() {
+ add(new H1("Hello, World!"));
+ }
+}
diff --git a/vaadin/src/main/java/com/baeldung/introduction/basics/VaadinFlowBasics.java b/vaadin/src/main/java/com/baeldung/introduction/basics/VaadinFlowBasics.java
new file mode 100644
index 0000000000..7a22eea0ab
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/introduction/basics/VaadinFlowBasics.java
@@ -0,0 +1,63 @@
+package com.baeldung.introduction.basics;
+
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.checkbox.Checkbox;
+import com.vaadin.flow.component.html.H1;
+import com.vaadin.flow.component.notification.Notification;
+import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.component.textfield.TextField;
+import com.vaadin.flow.router.Route;
+import com.vaadin.flow.router.RouterLink;
+
+// The @Route annotation defines the URL path for the view
+// Any component, most commonly a layout, can be used as a view
+@Route("basics")
+public class VaadinFlowBasics extends VerticalLayout {
+ public VaadinFlowBasics() {
+
+ // Add components to the layout with the add method
+ add(new H1("Vaadin Flow Basics"));
+
+ // Components are Java objects
+ var textField = new TextField("Name");
+ var button = new Button("Click me");
+
+ // Layouts define the structure of the UI
+ var verticalLayout = new VerticalLayout(
+ new Button("Top"),
+ new Button("Middle"),
+ new Button("Bottom")
+ );
+ add(verticalLayout);
+
+ var horizontalLayout = new HorizontalLayout(
+ new Button("Left"),
+ new Button("Center"),
+ new Button("Right")
+ );
+ add(horizontalLayout);
+
+ // Layouts can be nested for more complex structures
+ var nestedLayout = new VerticalLayout(
+ new HorizontalLayout(new Button("Top Left"), new Button("Top Right")),
+ new HorizontalLayout(new Button("Bottom Left"), new Button("Bottom Right"))
+ );
+ add(nestedLayout);
+
+ add(new RouterLink("Example layout", ExampleLayout.class));
+
+ // Use RouterLink to navigate to other views
+ var link = new RouterLink("Hello world view", HelloWorldView.class);
+ add(link);
+
+ // Use events to react to user input
+ var nameField = new TextField("Your name");
+ var helloButton = new Button("Say hello");
+ helloButton.addClickListener(e -> {
+ Notification.show("Hello, " + nameField.getValue());
+ });
+ add(nameField, helloButton);
+
+ }
+}
diff --git a/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java b/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java
new file mode 100644
index 0000000000..7984ecce05
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java
@@ -0,0 +1,86 @@
+package com.baeldung.spring;
+
+import com.baeldung.data.Employee;
+import com.vaadin.flow.component.Composite;
+import com.vaadin.flow.component.Key;
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.button.ButtonVariant;
+import com.vaadin.flow.component.icon.VaadinIcon;
+import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.component.textfield.TextField;
+import com.vaadin.flow.data.binder.BeanValidationBinder;
+import com.vaadin.flow.data.binder.Binder;
+
+public class EmployeeEditor extends Composite {
+
+ public interface SaveListener {
+ void onSave(Employee employee);
+ }
+
+ public interface DeleteListener {
+ void onDelete(Employee employee);
+ }
+
+ public interface CancelListener {
+ void onCancel();
+ }
+
+ private Employee employee;
+
+ private SaveListener saveListener;
+ private DeleteListener deleteListener;
+ private CancelListener cancelListener;
+
+ private final Binder binder = new BeanValidationBinder<>(Employee.class);
+
+public EmployeeEditor() {
+ var firstName = new TextField("First name");
+ var lastName = new TextField("Last name");
+
+ var save = new Button("Save", VaadinIcon.CHECK.create());
+ var cancel = new Button("Cancel");
+ var delete = new Button("Delete", VaadinIcon.TRASH.create());
+
+ binder.forField(firstName).bind("firstName");
+ binder.forField(lastName).bind("lastName");
+
+ save.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
+ save.addClickListener(e -> save());
+ save.addClickShortcut(Key.ENTER);
+
+ delete.addThemeVariants(ButtonVariant.LUMO_ERROR);
+ delete.addClickListener(e -> deleteListener.onDelete(employee));
+
+ cancel.addClickListener(e -> cancelListener.onCancel());
+
+ getContent().add(firstName, lastName, new HorizontalLayout(save, cancel, delete));
+}
+
+ private void save() {
+ // Save the form into a new instance of Employee
+ var updated = new Employee();
+ updated.setId(employee.getId());
+
+ if (binder.writeBeanIfValid(updated)) {
+ saveListener.onSave(updated);
+ }
+ }
+
+ public void setEmployee(Employee employee) {
+ this.employee = employee;
+ binder.readBean(employee);
+ }
+
+ public void setSaveListener(SaveListener saveListener) {
+ this.saveListener = saveListener;
+ }
+
+ public void setDeleteListener(DeleteListener deleteListener) {
+ this.deleteListener = deleteListener;
+ }
+
+ public void setCancelListener(CancelListener cancelListener) {
+ this.cancelListener = cancelListener;
+ }
+}
diff --git a/vaadin/src/main/java/com/baeldung/spring/EmployeesView.java b/vaadin/src/main/java/com/baeldung/spring/EmployeesView.java
new file mode 100644
index 0000000000..edb1f7a75b
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/spring/EmployeesView.java
@@ -0,0 +1,95 @@
+package com.baeldung.spring;
+
+import com.baeldung.data.Employee;
+import com.baeldung.data.EmployeeRepository;
+
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.grid.Grid;
+import com.vaadin.flow.component.icon.VaadinIcon;
+import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.component.textfield.TextField;
+import com.vaadin.flow.data.value.ValueChangeMode;
+import com.vaadin.flow.router.Route;
+
+@Route("employees")
+public class EmployeesView extends VerticalLayout {
+
+ private final EmployeeRepository employeeRepository;
+
+ private final TextField filter;
+ private final Grid grid;
+ private final EmployeeEditor editor;
+
+
+ public EmployeesView(EmployeeRepository repo) {
+ employeeRepository = repo;
+
+ // Create components
+ var addButton = new Button("New employee", VaadinIcon.PLUS.create());
+ filter = new TextField();
+ grid = new Grid<>(Employee.class);
+ editor = new EmployeeEditor();
+
+ // Configure components
+ configureEditor();
+
+ addButton.addClickListener(e -> editEmployee(new Employee()));
+
+ filter.setPlaceholder("Filter by last name");
+ filter.setValueChangeMode(ValueChangeMode.LAZY);
+ filter.addValueChangeListener(e -> updateEmployees(e.getValue()));
+
+ grid.setHeight("200px");
+ grid.asSingleSelect().addValueChangeListener(e -> editEmployee(e.getValue()));
+
+ // Compose layout
+ var actionsLayout = new HorizontalLayout(filter, addButton);
+ add(actionsLayout, grid, editor);
+
+ // List customers
+ updateEmployees("");
+ }
+
+ private void configureEditor() {
+ editor.setVisible(false);
+
+ editor.setSaveListener(employee -> {
+ var saved = employeeRepository.save(employee);
+ updateEmployees(filter.getValue());
+ editor.setEmployee(null);
+ grid.asSingleSelect().setValue(saved);
+ });
+
+ editor.setDeleteListener(employee -> {
+ employeeRepository.delete(employee);
+ updateEmployees(filter.getValue());
+ editEmployee(null);
+ });
+
+ editor.setCancelListener(() -> {
+ editEmployee(null);
+ });
+ }
+
+ private void editEmployee(Employee employee) {
+ editor.setEmployee(employee);
+
+ if (employee != null) {
+ editor.setVisible(true);
+ } else {
+ // Deselect grid
+ grid.asSingleSelect().setValue(null);
+ editor.setVisible(false);
+ }
+
+ }
+
+ private void updateEmployees(String filterText) {
+ if (filterText.isEmpty()) {
+ grid.setItems(employeeRepository.findAll());
+ } else {
+ grid.setItems(employeeRepository.findByLastNameStartsWithIgnoreCase(filterText));
+ }
+ }
+}
diff --git a/vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss b/vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss
deleted file mode 100644
index a5670b70c7..0000000000
--- a/vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-/* This file is automatically managed and will be overwritten from time to time. */
-/* Do not manually edit this file. */
-
-/* Import and include this mixin into your project theme to include the addon themes */
-@mixin addons {
-}
-
diff --git a/vaadin/src/main/webapp/VAADIN/themes/mytheme/favicon.ico b/vaadin/src/main/webapp/VAADIN/themes/mytheme/favicon.ico
deleted file mode 100644
index ffb34a65c7..0000000000
Binary files a/vaadin/src/main/webapp/VAADIN/themes/mytheme/favicon.ico and /dev/null differ
diff --git a/vaadin/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss b/vaadin/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss
deleted file mode 100644
index 2c5fb8b944..0000000000
--- a/vaadin/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss
+++ /dev/null
@@ -1,38 +0,0 @@
-// If you edit this file you need to compile the theme. See README.md for details.
-
-// Global variable overrides. Must be declared before importing Valo.
-
-// Defines the plaintext font size, weight and family. Font size affects general component sizing.
-//$v-font-size: 16px;
-//$v-font-weight: 300;
-//$v-font-family: "Open Sans", sans-serif;
-
-// Defines the border used by all components.
-//$v-border: 1px solid (v-shade 0.7);
-//$v-border-radius: 4px;
-
-// Affects the color of some component elements, e.g Button, Panel title, etc
-//$v-background-color: hsl(210, 0%, 98%);
-// Affects the color of content areas, e.g Panel and Window content, TextField input etc
-//$v-app-background-color: $v-background-color;
-
-// Affects the visual appearance of all components
-//$v-gradient: v-linear 8%;
-//$v-bevel-depth: 30%;
-//$v-shadow-opacity: 5%;
-
-// Defines colors for indicating status (focus, success, failure)
-//$v-focus-color: valo-focus-color(); // Calculates a suitable color automatically
-//$v-friendly-color: #2c9720;
-//$v-error-indicator-color: #ed473b;
-
-// For more information, see: https://vaadin.com/book/-/page/themes.valo.html
-// Example variants can be copy/pasted from https://vaadin.com/wiki/-/wiki/Main/Valo+Examples
-
-@import "../valo/valo.scss";
-
-@mixin mytheme {
- @include valo;
-
- // Insert your own theme rules here
-}
diff --git a/vaadin/src/main/webapp/VAADIN/themes/mytheme/styles.scss b/vaadin/src/main/webapp/VAADIN/themes/mytheme/styles.scss
deleted file mode 100644
index bba1d493c0..0000000000
--- a/vaadin/src/main/webapp/VAADIN/themes/mytheme/styles.scss
+++ /dev/null
@@ -1,11 +0,0 @@
-@import "mytheme.scss";
-@import "addons.scss";
-
-// This file prefixes all rules with the theme name to avoid causing conflicts with other themes.
-// The actual styles should be defined in mytheme.scss
-
-.mytheme {
- @include addons;
- @include mytheme;
-
-}
diff --git a/web-modules/jakarta-ee/pom.xml b/web-modules/jakarta-ee/pom.xml
index faad33338b..4caa67bf6f 100644
--- a/web-modules/jakarta-ee/pom.xml
+++ b/web-modules/jakarta-ee/pom.xml
@@ -48,7 +48,7 @@
org.mockito
- mockito-all
+ mockito-core
${mockito.version}
test
@@ -100,11 +100,10 @@
9.0.0
2.0.0
2.0.0
- 5.8.2
+ 5.10.2
C:/glassfish6
admin
mvn-domain
- 1.10.19
${local.glassfish.home}\\domains\\${local.glassfish.domain}\\config\\domain-passwords
diff --git a/web-modules/jakarta-ee/src/test/java/com/baeldung/eclipse/krazo/UserControllerUnitTest.java b/web-modules/jakarta-ee/src/test/java/com/baeldung/eclipse/krazo/UserControllerUnitTest.java
index 5e79924ed7..a116db3c65 100644
--- a/web-modules/jakarta-ee/src/test/java/com/baeldung/eclipse/krazo/UserControllerUnitTest.java
+++ b/web-modules/jakarta-ee/src/test/java/com/baeldung/eclipse/krazo/UserControllerUnitTest.java
@@ -1,25 +1,23 @@
package com.baeldung.eclipse.krazo;
-import com.baeldung.eclipse.krazo.User;
-import com.baeldung.eclipse.krazo.UserController;
-import jakarta.mvc.Models;
-import jakarta.mvc.binding.BindingResult;
-import org.eclipse.krazo.core.ModelsImpl;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
+import org.eclipse.krazo.core.ModelsImpl;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import jakarta.mvc.Models;
+import jakarta.mvc.binding.BindingResult;
+
/**
* The class contains unit tests. We do only unit tests. Most of the classes are mocked
*/
diff --git a/web-modules/javax-servlets-2/pom.xml b/web-modules/javax-servlets-2/pom.xml
index a792f6eea2..8031786af4 100644
--- a/web-modules/javax-servlets-2/pom.xml
+++ b/web-modules/javax-servlets-2/pom.xml
@@ -112,7 +112,6 @@
2.22.2
10.0.4
1.10.0
- 5.6.0
1.5.4
diff --git a/web-modules/jee-7/pom.xml b/web-modules/jee-7/pom.xml
index b26027d9bf..9bbfc33e62 100644
--- a/web-modules/jee-7/pom.xml
+++ b/web-modules/jee-7/pom.xml
@@ -16,6 +16,13 @@
1.0.0-SNAPSHOT
+
+
+ jboss-https
+ https://repository.jboss.org/nexus/content/groups/public/
+
+
+
@@ -305,7 +312,7 @@
test
- org.wildfly
+ org.wildfly.arquillian
wildfly-arquillian-container-managed
${wildfly.version}
test
@@ -338,7 +345,7 @@
org.wildfly
wildfly-dist
- ${wildfly.version}
+ ${wildfly-dist.version}
zip
false
${project.build.directory}
@@ -388,7 +395,7 @@
test
- org.wildfly
+ org.wildfly.arquillian
wildfly-arquillian-container-remote
${wildfly.version}
test
@@ -513,7 +520,8 @@
3.0.0
7.0
1.1.11.Final
- 8.2.1.Final
+ 31.0.1.Final
+ 5.0.1.Final
1.7.0
1.4.6.Final
3.0.19.Final
diff --git a/web-modules/jersey/src/main/java/com/baeldung/jersey/server/Greetings.java b/web-modules/jersey/src/main/java/com/baeldung/jersey/server/Greetings.java
index e753d34901..e87bd100c8 100644
--- a/web-modules/jersey/src/main/java/com/baeldung/jersey/server/Greetings.java
+++ b/web-modules/jersey/src/main/java/com/baeldung/jersey/server/Greetings.java
@@ -5,6 +5,7 @@ import com.baeldung.jersey.server.config.HelloBinding;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Response;
@Path("/greetings")
@@ -17,6 +18,7 @@ public class Greetings {
}
@GET
+ @Produces("text/html")
@Path("/hi")
public String getHiGreeting() {
return "hi";
diff --git a/web-modules/jersey/src/test/java/com/baeldung/jersey/server/GreetingsResourceIntegrationTest.java b/web-modules/jersey/src/test/java/com/baeldung/jersey/server/GreetingsResourceIntegrationTest.java
index 47736f90d7..e01415b50a 100644
--- a/web-modules/jersey/src/test/java/com/baeldung/jersey/server/GreetingsResourceIntegrationTest.java
+++ b/web-modules/jersey/src/test/java/com/baeldung/jersey/server/GreetingsResourceIntegrationTest.java
@@ -1,18 +1,18 @@
package com.baeldung.jersey.server;
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.test.TestProperties;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import jakarta.ws.rs.core.Application;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
-public class GreetingsResourceIntegrationTest extends JerseyTest {
+class GreetingsResourceIntegrationTest extends JerseyTest {
@Override
protected Application configure() {
@@ -21,14 +21,14 @@ public class GreetingsResourceIntegrationTest extends JerseyTest {
}
@Test
- public void givenGetHiGreeting_whenCorrectRequest_thenResponseIsOkAndContainsHi() {
+ void givenGetHiGreeting_whenCorrectRequest_thenResponseIsOkAndContainsHi() {
Response response = target("/greetings/hi").request()
.get();
- assertEquals("Http Response should be 200: ", Response.Status.OK.getStatusCode(), response.getStatus());
- assertEquals("Http Content-Type should be: ", MediaType.TEXT_HTML, response.getHeaderString(HttpHeaders.CONTENT_TYPE));
+ assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+ assertEquals(MediaType.TEXT_HTML, response.getHeaderString(HttpHeaders.CONTENT_TYPE));
String content = response.readEntity(String.class);
- assertEquals("Content of ressponse is: ", "hi", content);
+ assertEquals("hi", content);
}
}
diff --git a/web-modules/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java b/web-modules/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java
index 4f73c9df5b..2eaeb94a00 100644
--- a/web-modules/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java
+++ b/web-modules/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java
@@ -2,12 +2,12 @@ package com.baeldung.jersey.server.rest;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.containsString;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.test.TestProperties;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import com.baeldung.jersey.server.config.ViewApplicationConfig;
import com.baeldung.jersey.server.model.Fruit;
@@ -19,7 +19,7 @@ import jakarta.ws.rs.core.Form;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
-public class FruitResourceIntegrationTest extends JerseyTest {
+class FruitResourceIntegrationTest extends JerseyTest {
@Override
protected Application configure() {
@@ -33,80 +33,80 @@ public class FruitResourceIntegrationTest extends JerseyTest {
}
@Test
- public void givenGetAllFruit_whenCorrectRequest_thenAllTemplateInvoked() {
+ void givenGetAllFruit_whenCorrectRequest_thenAllTemplateInvoked() {
final String response = target("/fruit/all").request()
.get(String.class);
assertThat(response, allOf(containsString("banana"), containsString("apple"), containsString("kiwi")));
}
@Test
- public void givenGetFruit_whenCorrectRequest_thenIndexTemplateInvoked() {
+ void givenGetFruit_whenCorrectRequest_thenIndexTemplateInvoked() {
final String response = target("/fruit").request()
.get(String.class);
assertThat(response, containsString("Welcome Fruit Index Page!"));
}
@Test
- public void givenGetFruitByName_whenFruitUnknown_thenErrorTemplateInvoked() {
+ void givenGetFruitByName_whenFruitUnknown_thenErrorTemplateInvoked() {
final String response = target("/fruit/orange").request()
.get(String.class);
assertThat(response, containsString("Error - Fruit not found: orange!"));
}
@Test
- public void givenCreateFruit_whenFormContainsNullParam_thenResponseCodeIsBadRequest() {
+ void givenCreateFruit_whenFormContainsNullParam_thenResponseCodeIsBadRequest() {
Form form = new Form();
form.param("name", "apple");
form.param("colour", null);
Response response = target("fruit/create").request(MediaType.APPLICATION_FORM_URLENCODED)
.post(Entity.form(form));
- assertEquals("Http Response should be 400 ", 400, response.getStatus());
+ assertEquals(400, response.getStatus());
assertThat(response.readEntity(String.class), containsString("Fruit colour must not be null"));
}
@Test
- public void givenCreateFruit_whenJsonIsCorrect_thenResponseCodeIsCreated() {
+ void givenCreateFruit_whenJsonIsCorrect_thenResponseCodeIsCreated() {
Response response = target("fruit/created").request()
.post(Entity.json("{\"name\":\"strawberry\",\"weight\":20}"));
- assertEquals("Http Response should be 201 ", Response.Status.CREATED.getStatusCode(), response.getStatus());
+ assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
assertThat(response.readEntity(String.class), containsString("Fruit saved : Fruit [name: strawberry colour: null]"));
}
@Test
- public void givenUpdateFruit_whenFormContainsBadSerialParam_thenResponseCodeIsBadRequest() {
+ void givenUpdateFruit_whenFormContainsBadSerialParam_thenResponseCodeIsBadRequest() {
Form form = new Form();
form.param("serial", "2345-2345");
Response response = target("fruit/update").request(MediaType.APPLICATION_FORM_URLENCODED)
.put(Entity.form(form));
- assertEquals("Http Response should be 400 ", 400, response.getStatus());
+ assertEquals(400, response.getStatus());
assertThat(response.readEntity(String.class), containsString("Fruit serial number is not valid"));
}
@Test
- public void givenCreateFruit_whenFruitIsInvalid_thenResponseCodeIsBadRequest() {
+ void givenCreateFruit_whenFruitIsInvalid_thenResponseCodeIsBadRequest() {
Fruit fruit = new Fruit("Blueberry", "purple");
fruit.setWeight(1);
Response response = target("fruit/create").request(MediaType.APPLICATION_JSON_TYPE)
.post(Entity.entity(fruit, MediaType.APPLICATION_JSON_TYPE));
- assertEquals("Http Response should be 400 ", 400, response.getStatus());
+ assertEquals(400, response.getStatus());
assertThat(response.readEntity(String.class), containsString("Fruit weight must be 10 or greater"));
}
@Test
- public void givenFruitExists_whenSearching_thenResponseContainsFruit() {
+ void givenFruitExists_whenSearching_thenResponseContainsFruit() {
Fruit fruit = new Fruit();
fruit.setName("strawberry");
fruit.setWeight(20);
Response response = target("fruit/create").request(MediaType.APPLICATION_JSON_TYPE)
.post(Entity.entity(fruit, MediaType.APPLICATION_JSON_TYPE));
- assertEquals("Http Response should be 204 ", 204, response.getStatus());
+ assertEquals(204, response.getStatus());
final String json = target("fruit/search/strawberry").request()
.get(String.class);
@@ -114,28 +114,28 @@ public class FruitResourceIntegrationTest extends JerseyTest {
}
@Test
- public void givenFruitExists_whenSearching_thenResponseContainsFruitEntity() {
+ void givenFruitExists_whenSearching_thenResponseContainsFruitEntity() {
Fruit fruit = new Fruit();
fruit.setName("strawberry");
fruit.setWeight(20);
Response response = target("fruit/create").request(MediaType.APPLICATION_JSON_TYPE)
.post(Entity.entity(fruit, MediaType.APPLICATION_JSON_TYPE));
- assertEquals("Http Response should be 204 ", 204, response.getStatus());
+ assertEquals(204, response.getStatus());
final Fruit entity = target("fruit/search/strawberry").request()
.get(Fruit.class);
- assertEquals("Fruit name: ", "strawberry", entity.getName());
- assertEquals("Fruit weight: ", Integer.valueOf(20), entity.getWeight());
+ assertEquals("strawberry", entity.getName());
+ assertEquals(Integer.valueOf(20), entity.getWeight());
}
@Test
- public void givenFruit_whenFruitIsInvalid_thenReponseContainsCustomExceptions() {
+ void givenFruit_whenFruitIsInvalid_thenReponseContainsCustomExceptions() {
final Response response = target("fruit/exception").request()
.get();
- assertEquals("Http Response should be 400 ", 400, response.getStatus());
+ assertEquals(400, response.getStatus());
String responseString = response.readEntity(String.class);
assertThat(responseString, containsString("exception..colour size must be between 5 and 200"));
assertThat(responseString, containsString("exception..name size must be between 5 and 200"));
diff --git a/xml-2/src/test/java/com/baeldung/xml/invalidcharacters/InvalidCharactersUnitTest.java b/xml-2/src/test/java/com/baeldung/xml/invalidcharacters/InvalidCharactersUnitTest.java
new file mode 100644
index 0000000000..7878e72f97
--- /dev/null
+++ b/xml-2/src/test/java/com/baeldung/xml/invalidcharacters/InvalidCharactersUnitTest.java
@@ -0,0 +1,69 @@
+package com.baeldung.xml.invalidcharacters;
+
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXParseException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.StringReader;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.*;
+
+public class InvalidCharactersUnitTest {
+
+ @Test
+ void givenXml_whenReservedCharacters_thenThrowException() {
+ String invalidXmlString = "John & Doe";
+ assertThrowsExactly(SAXParseException.class, () -> parseXmlString(invalidXmlString));
+ }
+
+ @Test
+ void givenXml_whenReservedCharactersEscaped_thenSuccess() {
+ String validXmlString = "John & Doe";
+
+ assertDoesNotThrow(() -> {
+ Document document = parseXmlString(validXmlString);
+
+ assertNotNull(document);
+ assertEquals("John & Doe", document.getElementsByTagName("name").item(0).getTextContent());
+ });
+ }
+
+ @Test
+ void givenXml_whenUsingCdataForReservedCharacters_thenSuccess() {
+ String validXmlString = "";
+
+ assertDoesNotThrow(() -> {
+ Document document = parseXmlString(validXmlString);
+
+ assertNotNull(document);
+ assertEquals("John & Doe", document.getElementsByTagName("name").item(0).getTextContent());
+ });
+ }
+
+ @Test
+ void givenXml_whenUnicodeCharacters_thenThrowException() {
+ String invalidXmlString = "John \u001E Doe";
+ assertThrowsExactly(SAXParseException.class, () -> parseXmlString(invalidXmlString));
+ }
+
+ @Test
+ void givenXml_whenUnicodeCharactersEscaped_thenSuccess() {
+ String validXmlString = "John Doe";
+ assertDoesNotThrow(() -> {
+ Document document = parseXmlString(validXmlString);
+
+ assertNotNull(document);
+ assertEquals("John \u001E Doe", document.getElementsByTagName("name").item(0).getTextContent());
+ });
+ }
+
+ private Document parseXmlString(String xmlString) throws Exception {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ InputSource inputSource = new InputSource(new StringReader(xmlString));
+ return builder.parse(inputSource);
+ }
+}