diff --git a/core-java-modules/core-java-9-new-features/README.md b/core-java-modules/core-java-9-new-features/README.md
index d547b9a221..c2ef63a530 100644
--- a/core-java-modules/core-java-9-new-features/README.md
+++ b/core-java-modules/core-java-9-new-features/README.md
@@ -12,3 +12,4 @@ This module contains articles about core Java features that have been introduced
- [Introduction to Java 9 StackWalking API](https://www.baeldung.com/java-9-stackwalking-api)
- [Java 9 Platform Logging API](https://www.baeldung.com/java-9-logging-api)
- [Java 9 Reactive Streams](https://www.baeldung.com/java-9-reactive-streams)
+- [Multi-Release JAR Files with Maven](https://www.baeldung.com/maven-multi-release-jars)
diff --git a/core-java-modules/core-java-9-new-features/pom.xml b/core-java-modules/core-java-9-new-features/pom.xml
index b0fb6ab7f9..70fae73bd5 100644
--- a/core-java-modules/core-java-9-new-features/pom.xml
+++ b/core-java-modules/core-java-9-new-features/pom.xml
@@ -28,8 +28,104 @@
${junit.platform.version}
test
+
+ org.awaitility
+ awaitility
+ ${awaitility.version}
+ test
+
-
+
+
+ incubator-features
+
+ core-java-9-new-features
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+
+ ${maven.compiler.target}
+ --add-modules=jdk.incubator.httpclient
+
+
+
+ maven-surefire-plugin
+
+ --add-modules=jdk.incubator.httpclient
+
+
+
+
+
+
+ mrjar-generation
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ compile-java-8
+
+ compile
+
+
+
+ 1.8
+
+ ${project.basedir}/src/main/java8
+
+
+
+
+ compile-java-9
+ compile
+
+ compile
+
+
+ 9
+
+ ${project.basedir}/src/main/java9
+
+ ${project.build.outputDirectory}/META-INF/versions/9
+
+
+
+ default-testCompile
+ test-compile
+
+ testCompile
+
+
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ ${maven-jar-plugin.version}
+
+
+
+ true
+
+
+ com.baeldung.multireleaseapp.App
+
+
+
+
+
+
+
+
core-java-9-new-features
@@ -56,8 +152,10 @@
3.10.0
1.2.0
+ 4.0.2
1.9
1.9
+ 3.2.0
diff --git a/core-java-modules/core-java-9-new-features/src/main/java8/com/baeldung/multireleaseapp/App.java b/core-java-modules/core-java-9-new-features/src/main/java8/com/baeldung/multireleaseapp/App.java
new file mode 100644
index 0000000000..cc00223e05
--- /dev/null
+++ b/core-java-modules/core-java-9-new-features/src/main/java8/com/baeldung/multireleaseapp/App.java
@@ -0,0 +1,14 @@
+package com.baeldung.multireleaseapp;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class App {
+
+ private static final Logger logger = LoggerFactory.getLogger(App.class);
+
+ public static void main(String[] args) {
+ logger.info(String.format("Running on %s", new DefaultVersion().version()));
+ }
+
+}
diff --git a/core-java-modules/core-java-9-new-features/src/main/java8/com/baeldung/multireleaseapp/DefaultVersion.java b/core-java-modules/core-java-9-new-features/src/main/java8/com/baeldung/multireleaseapp/DefaultVersion.java
new file mode 100644
index 0000000000..b24be606de
--- /dev/null
+++ b/core-java-modules/core-java-9-new-features/src/main/java8/com/baeldung/multireleaseapp/DefaultVersion.java
@@ -0,0 +1,9 @@
+package com.baeldung.multireleaseapp;
+
+public class DefaultVersion implements Version {
+
+ @Override
+ public String version() {
+ return System.getProperty("java.version");
+ }
+}
diff --git a/core-java-modules/core-java-9-new-features/src/main/java8/com/baeldung/multireleaseapp/Version.java b/core-java-modules/core-java-9-new-features/src/main/java8/com/baeldung/multireleaseapp/Version.java
new file mode 100644
index 0000000000..ef95f08205
--- /dev/null
+++ b/core-java-modules/core-java-9-new-features/src/main/java8/com/baeldung/multireleaseapp/Version.java
@@ -0,0 +1,5 @@
+package com.baeldung.multireleaseapp;
+
+interface Version {
+ public String version();
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-9-new-features/src/main/java9/com/baeldung/multireleaseapp/DefaultVersion.java b/core-java-modules/core-java-9-new-features/src/main/java9/com/baeldung/multireleaseapp/DefaultVersion.java
new file mode 100644
index 0000000000..0842f578dd
--- /dev/null
+++ b/core-java-modules/core-java-9-new-features/src/main/java9/com/baeldung/multireleaseapp/DefaultVersion.java
@@ -0,0 +1,9 @@
+package com.baeldung.multireleaseapp;
+
+public class DefaultVersion implements Version {
+
+ @Override
+ public String version() {
+ return Runtime.version().toString();
+ }
+}
diff --git a/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpClientTest.java b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpClientIntegrationTest.java
similarity index 98%
rename from core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpClientTest.java
rename to core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpClientIntegrationTest.java
index 5cf3b9098f..fc59ae8d8d 100644
--- a/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpClientTest.java
+++ b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpClientIntegrationTest.java
@@ -24,7 +24,7 @@ import static org.junit.Assert.assertThat;
/**
* Created by adam.
*/
-public class HttpClientTest {
+public class HttpClientIntegrationTest {
@Test
public void shouldReturnSampleDataContentWhenConnectViaSystemProxy() throws IOException, InterruptedException, URISyntaxException {
@@ -55,7 +55,7 @@ public class HttpClientTest {
.send(request, HttpResponse.BodyHandler.asString());
assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_MOVED_PERM));
- assertThat(response.body(), containsString("https://stackoverflow.com/"));
+ assertThat(response.body(), containsString(""));
}
@Test
diff --git a/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpRequestTest.java b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpRequestIntegrationTest.java
similarity index 99%
rename from core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpRequestTest.java
rename to core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpRequestIntegrationTest.java
index 7c0e9a90e0..17af7bd8ba 100644
--- a/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpRequestTest.java
+++ b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpRequestIntegrationTest.java
@@ -22,7 +22,7 @@ import static org.junit.Assert.assertThat;
/**
* Created by adam.
*/
-public class HttpRequestTest {
+public class HttpRequestIntegrationTest {
@Test
public void shouldReturnStatusOKWhenSendGetRequest() throws IOException, InterruptedException, URISyntaxException {
diff --git a/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpResponseTest.java b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpResponseIntegrationTest.java
similarity index 97%
rename from core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpResponseTest.java
rename to core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpResponseIntegrationTest.java
index 80295ff34c..5c6f9c8a52 100644
--- a/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpResponseTest.java
+++ b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpResponseIntegrationTest.java
@@ -18,7 +18,7 @@ import static org.junit.Assert.assertThat;
/**
* Created by adam.
*/
-public class HttpResponseTest {
+public class HttpResponseIntegrationTest {
@Test
public void shouldReturnStatusOKWhenSendGetRequest() throws IOException, InterruptedException, URISyntaxException {
diff --git a/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/streams.reactive/ReactiveStreamsTest.java b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/streams/reactive/ReactiveStreamsUnitTest.java
similarity index 86%
rename from core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/streams.reactive/ReactiveStreamsTest.java
rename to core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/streams/reactive/ReactiveStreamsUnitTest.java
index 647557532d..92cdc1c074 100644
--- a/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/streams.reactive/ReactiveStreamsTest.java
+++ b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/streams/reactive/ReactiveStreamsUnitTest.java
@@ -5,10 +5,12 @@ import org.junit.Test;
import java.util.List;
import java.util.concurrent.SubmissionPublisher;
+import java.util.concurrent.TimeUnit;
-import static org.assertj.core.api.Java6Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Awaitility.await;
-public class ReactiveStreamsTest {
+public class ReactiveStreamsUnitTest {
@Test
public void givenPublisher_whenSubscribeToIt_thenShouldConsumeAllElements() throws InterruptedException {
@@ -25,7 +27,7 @@ public class ReactiveStreamsTest {
//then
- await().atMost(1000, TimeUnit.MILLISECONDS).until(
+ await().atMost(1000, TimeUnit.MILLISECONDS).untilAsserted(
() -> assertThat(subscriber.consumedElements).containsExactlyElementsOf(items)
);
}
@@ -46,7 +48,7 @@ public class ReactiveStreamsTest {
publisher.close();
//then
- await().atMost(1000, TimeUnit.MILLISECONDS).until(
+ await().atMost(1000, TimeUnit.MILLISECONDS).untilAsserted(
() -> assertThat(subscriber.consumedElements).containsExactlyElementsOf(expectedResult)
);
}
@@ -66,7 +68,7 @@ public class ReactiveStreamsTest {
publisher.close();
//then
- await().atMost(1000, TimeUnit.MILLISECONDS).until(
+ await().atMost(1000, TimeUnit.MILLISECONDS).untilAsserted(
() -> assertThat(subscriber.consumedElements).containsExactlyElementsOf(expected)
);
}
diff --git a/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/varhandles/VariableHandlesTest.java b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/varhandles/VariableHandlesUnitTest.java
similarity index 75%
rename from core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/varhandles/VariableHandlesTest.java
rename to core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/varhandles/VariableHandlesUnitTest.java
index 50766502ec..56e34f06a0 100644
--- a/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/varhandles/VariableHandlesTest.java
+++ b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/varhandles/VariableHandlesUnitTest.java
@@ -7,7 +7,7 @@ import java.lang.invoke.VarHandle;
import static org.assertj.core.api.Assertions.assertThat;
-public class VariableHandlesTest {
+public class VariableHandlesUnitTest {
public int publicTestVariable = 1;
private int privateTestVariable = 1;
@@ -20,22 +20,22 @@ public class VariableHandlesTest {
public void whenVariableHandleForPublicVariableIsCreated_ThenItIsInitializedProperly() throws NoSuchFieldException, IllegalAccessException {
VarHandle publicIntHandle = MethodHandles
.lookup()
- .in(VariableHandlesTest.class)
- .findVarHandle(VariableHandlesTest.class, "publicTestVariable", int.class);
+ .in(VariableHandlesUnitTest.class)
+ .findVarHandle(VariableHandlesUnitTest.class, "publicTestVariable", int.class);
assertThat(publicIntHandle.coordinateTypes().size() == 1);
- assertThat(publicIntHandle.coordinateTypes().get(0) == VariableHandles.class);
+ assertThat(publicIntHandle.coordinateTypes().get(0) == VariableHandlesUnitTest.class);
}
@Test
public void whenVariableHandleForPrivateVariableIsCreated_ThenItIsInitializedProperly() throws NoSuchFieldException, IllegalAccessException {
VarHandle privateIntHandle = MethodHandles
- .privateLookupIn(VariableHandlesTest.class, MethodHandles.lookup())
- .findVarHandle(VariableHandlesTest.class, "privateTestVariable", int.class);
+ .privateLookupIn(VariableHandlesUnitTest.class, MethodHandles.lookup())
+ .findVarHandle(VariableHandlesUnitTest.class, "privateTestVariable", int.class);
assertThat(privateIntHandle.coordinateTypes().size() == 1);
- assertThat(privateIntHandle.coordinateTypes().get(0) == VariableHandlesTest.class);
+ assertThat(privateIntHandle.coordinateTypes().get(0) == VariableHandlesUnitTest.class);
}
@@ -52,8 +52,8 @@ public class VariableHandlesTest {
public void givenVarHandle_whenGetIsInvoked_ThenValueOfVariableIsReturned() throws NoSuchFieldException, IllegalAccessException {
VarHandle publicIntHandle = MethodHandles
.lookup()
- .in(VariableHandlesTest.class)
- .findVarHandle(VariableHandlesTest.class, "publicTestVariable", int.class);
+ .in(VariableHandlesUnitTest.class)
+ .findVarHandle(VariableHandlesUnitTest.class, "publicTestVariable", int.class);
assertThat((int) publicIntHandle.get(this) == 1);
}
@@ -62,8 +62,8 @@ public class VariableHandlesTest {
public void givenVarHandle_whenSetIsInvoked_ThenValueOfVariableIsChanged() throws NoSuchFieldException, IllegalAccessException {
VarHandle publicIntHandle = MethodHandles
.lookup()
- .in(VariableHandlesTest.class)
- .findVarHandle(VariableHandlesTest.class, "variableToSet", int.class);
+ .in(VariableHandlesUnitTest.class)
+ .findVarHandle(VariableHandlesUnitTest.class, "variableToSet", int.class);
publicIntHandle.set(this, 15);
assertThat((int) publicIntHandle.get(this) == 15);
@@ -73,8 +73,8 @@ public class VariableHandlesTest {
public void givenVarHandle_whenCompareAndSetIsInvoked_ThenValueOfVariableIsChanged() throws NoSuchFieldException, IllegalAccessException {
VarHandle publicIntHandle = MethodHandles
.lookup()
- .in(VariableHandlesTest.class)
- .findVarHandle(VariableHandlesTest.class, "variableToCompareAndSet", int.class);
+ .in(VariableHandlesUnitTest.class)
+ .findVarHandle(VariableHandlesUnitTest.class, "variableToCompareAndSet", int.class);
publicIntHandle.compareAndSet(this, 1, 100);
assertThat((int) publicIntHandle.get(this) == 100);
@@ -84,8 +84,8 @@ public class VariableHandlesTest {
public void givenVarHandle_whenGetAndAddIsInvoked_ThenValueOfVariableIsChanged() throws NoSuchFieldException, IllegalAccessException {
VarHandle publicIntHandle = MethodHandles
.lookup()
- .in(VariableHandlesTest.class)
- .findVarHandle(VariableHandlesTest.class, "variableToGetAndAdd", int.class);
+ .in(VariableHandlesUnitTest.class)
+ .findVarHandle(VariableHandlesUnitTest.class, "variableToGetAndAdd", int.class);
int before = (int) publicIntHandle.getAndAdd(this, 200);
assertThat(before == 0);
@@ -96,8 +96,8 @@ public class VariableHandlesTest {
public void givenVarHandle_whenGetAndBitwiseOrIsInvoked_ThenValueOfVariableIsChanged() throws NoSuchFieldException, IllegalAccessException {
VarHandle publicIntHandle = MethodHandles
.lookup()
- .in(VariableHandlesTest.class)
- .findVarHandle(VariableHandlesTest.class, "variableToBitwiseOr", byte.class);
+ .in(VariableHandlesUnitTest.class)
+ .findVarHandle(VariableHandlesUnitTest.class, "variableToBitwiseOr", byte.class);
byte before = (byte) publicIntHandle.getAndBitwiseOr(this, (byte) 127);
assertThat(before == 0);
diff --git a/core-java-modules/core-java-io-conversions-2/README.md b/core-java-modules/core-java-io-conversions-2/README.md
index 5cb9c21c54..9ce36e7437 100644
--- a/core-java-modules/core-java-io-conversions-2/README.md
+++ b/core-java-modules/core-java-io-conversions-2/README.md
@@ -5,4 +5,5 @@ This module contains articles about core Java input/output(IO) conversions.
### Relevant Articles:
- [Java InputStream to String](https://www.baeldung.com/convert-input-stream-to-string)
- [Java – Write an InputStream to a File](https://www.baeldung.com/convert-input-stream-to-a-file)
+- [Converting a BufferedReader to a JSONObject](https://www.baeldung.com/java-bufferedreader-to-jsonobject)
- More articles: [[<-- prev]](/core-java-modules/core-java-io-conversions)
diff --git a/core-java-modules/core-java-jvm/src/test/java/com/baeldung/error/oom/ExecutorServiceUnitTest.java b/core-java-modules/core-java-jvm/src/test/java/com/baeldung/error/oom/ExecutorServiceUnitTest.java
new file mode 100644
index 0000000000..47bb668727
--- /dev/null
+++ b/core-java-modules/core-java-jvm/src/test/java/com/baeldung/error/oom/ExecutorServiceUnitTest.java
@@ -0,0 +1,40 @@
+package com.baeldung.error.oom;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.IntStream;
+
+import org.junit.jupiter.api.Test;
+
+public class ExecutorServiceUnitTest {
+
+ @Test
+ public void givenAnExecutorService_WhenMoreTasksSubmitted_ThenAdditionalTasksWait() {
+
+ // Given
+ int noOfThreads = 5;
+ ExecutorService executorService = Executors.newFixedThreadPool(noOfThreads);
+
+ Runnable runnableTask = () -> {
+ try {
+ TimeUnit.HOURS.sleep(1);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ };
+
+ // When
+ IntStream.rangeClosed(1, 10)
+ .forEach(i -> executorService.submit(runnableTask));
+
+ // Then
+ assertThat(((ThreadPoolExecutor) executorService).getQueue()
+ .size(), is(equalTo(5)));
+ }
+}
diff --git a/core-kotlin-modules/core-kotlin-2/src/test/kotlin/com/baeldung/nullassertion/NotNullAssertionUnitTest.kt b/core-kotlin-modules/core-kotlin-2/src/test/kotlin/com/baeldung/nullassertion/NotNullAssertionUnitTest.kt
new file mode 100644
index 0000000000..434f177927
--- /dev/null
+++ b/core-kotlin-modules/core-kotlin-2/src/test/kotlin/com/baeldung/nullassertion/NotNullAssertionUnitTest.kt
@@ -0,0 +1,20 @@
+package com.baeldung.nullassertion
+
+import org.junit.Test
+import kotlin.test.assertEquals
+
+class NotNullAssertionUnitTest {
+
+ @Test
+ fun givenNullableValue_WhenNotNull_ShouldExtractTheValue() {
+ val answer: String? = "42"
+
+ assertEquals(42, answer!!.toInt())
+ }
+
+ @Test(expected = KotlinNullPointerException::class)
+ fun givenNullableValue_WhenIsNull_ThenShouldThrow() {
+ val noAnswer: String? = null
+ noAnswer!!
+ }
+}
diff --git a/jhipster/jhipster-uaa/gateway/src/main/java/com/baeldung/jhipster/gateway/web/rest/errors/ExceptionTranslator.java b/jhipster/jhipster-uaa/gateway/src/main/java/com/baeldung/jhipster/gateway/web/rest/errors/ExceptionTranslator.java
index d5c9e577a6..fd6e04dadc 100644
--- a/jhipster/jhipster-uaa/gateway/src/main/java/com/baeldung/jhipster/gateway/web/rest/errors/ExceptionTranslator.java
+++ b/jhipster/jhipster-uaa/gateway/src/main/java/com/baeldung/jhipster/gateway/web/rest/errors/ExceptionTranslator.java
@@ -14,6 +14,7 @@ import org.zalando.problem.Problem;
import org.zalando.problem.ProblemBuilder;
import org.zalando.problem.Status;
import org.zalando.problem.spring.web.advice.ProblemHandling;
+import org.zalando.problem.spring.web.advice.security.SecurityAdviceTrait;
import org.zalando.problem.violations.ConstraintViolationProblem;
import javax.annotation.Nonnull;
@@ -28,7 +29,7 @@ import java.util.stream.Collectors;
* The error response follows RFC7807 - Problem Details for HTTP APIs (https://tools.ietf.org/html/rfc7807)
*/
@ControllerAdvice
-public class ExceptionTranslator implements ProblemHandling {
+public class ExceptionTranslator implements ProblemHandling, SecurityAdviceTrait {
/**
* Post-process the Problem payload to add the message key for the front-end if needed
diff --git a/jhipster/jhipster-uaa/quotes/src/main/java/com/baeldung/jhipster/quotes/web/rest/errors/ExceptionTranslator.java b/jhipster/jhipster-uaa/quotes/src/main/java/com/baeldung/jhipster/quotes/web/rest/errors/ExceptionTranslator.java
index 18baa42736..3bf4995405 100644
--- a/jhipster/jhipster-uaa/quotes/src/main/java/com/baeldung/jhipster/quotes/web/rest/errors/ExceptionTranslator.java
+++ b/jhipster/jhipster-uaa/quotes/src/main/java/com/baeldung/jhipster/quotes/web/rest/errors/ExceptionTranslator.java
@@ -14,6 +14,7 @@ import org.zalando.problem.Problem;
import org.zalando.problem.ProblemBuilder;
import org.zalando.problem.Status;
import org.zalando.problem.spring.web.advice.ProblemHandling;
+import org.zalando.problem.spring.web.advice.security.SecurityAdviceTrait;
import org.zalando.problem.violations.ConstraintViolationProblem;
import javax.annotation.Nonnull;
@@ -28,7 +29,7 @@ import java.util.stream.Collectors;
* The error response follows RFC7807 - Problem Details for HTTP APIs (https://tools.ietf.org/html/rfc7807)
*/
@ControllerAdvice
-public class ExceptionTranslator implements ProblemHandling {
+public class ExceptionTranslator implements ProblemHandling, SecurityAdviceTrait {
/**
* Post-process the Problem payload to add the message key for the front-end if needed
diff --git a/jhipster/jhipster-uaa/uaa/src/main/java/com/baeldung/jhipster/uaa/web/rest/errors/ExceptionTranslator.java b/jhipster/jhipster-uaa/uaa/src/main/java/com/baeldung/jhipster/uaa/web/rest/errors/ExceptionTranslator.java
index 320636c51d..6af9fd126c 100644
--- a/jhipster/jhipster-uaa/uaa/src/main/java/com/baeldung/jhipster/uaa/web/rest/errors/ExceptionTranslator.java
+++ b/jhipster/jhipster-uaa/uaa/src/main/java/com/baeldung/jhipster/uaa/web/rest/errors/ExceptionTranslator.java
@@ -14,6 +14,7 @@ import org.zalando.problem.Problem;
import org.zalando.problem.ProblemBuilder;
import org.zalando.problem.Status;
import org.zalando.problem.spring.web.advice.ProblemHandling;
+import org.zalando.problem.spring.web.advice.security.SecurityAdviceTrait;
import org.zalando.problem.violations.ConstraintViolationProblem;
import javax.annotation.Nonnull;
@@ -28,7 +29,7 @@ import java.util.stream.Collectors;
* The error response follows RFC7807 - Problem Details for HTTP APIs (https://tools.ietf.org/html/rfc7807)
*/
@ControllerAdvice
-public class ExceptionTranslator implements ProblemHandling {
+public class ExceptionTranslator implements ProblemHandling, SecurityAdviceTrait {
/**
* Post-process the Problem payload to add the message key for the front-end if needed
diff --git a/jmh/src/main/java/com/baeldung/BenchMark.java b/jmh/src/main/java/com/baeldung/BenchMark.java
index b0e1caf4dc..3c5c840db2 100644
--- a/jmh/src/main/java/com/baeldung/BenchMark.java
+++ b/jmh/src/main/java/com/baeldung/BenchMark.java
@@ -1,14 +1,20 @@
package com.baeldung;
-import com.google.common.hash.HashFunction;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;
import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.infra.Blackhole;
import java.nio.charset.Charset;
+import java.util.concurrent.TimeUnit;
public class BenchMark {
+ @State(Scope.Benchmark)
+ public static class Log {
+ public int x = 8;
+ }
+
@State(Scope.Benchmark)
public static class ExecutionPlan {
@@ -45,4 +51,44 @@ public class BenchMark {
// Do nothing
}
+ @Benchmark
+ @OutputTimeUnit(TimeUnit.NANOSECONDS)
+ @BenchmarkMode(Mode.AverageTime)
+ public void doNothing() {
+
+ }
+
+ @Benchmark
+ @OutputTimeUnit(TimeUnit.NANOSECONDS)
+ @BenchmarkMode(Mode.AverageTime)
+ public void objectCreation() {
+ new Object();
+ }
+
+ @Benchmark
+ @OutputTimeUnit(TimeUnit.NANOSECONDS)
+ @BenchmarkMode(Mode.AverageTime)
+ public Object pillarsOfCreation() {
+ return new Object();
+ }
+
+ @Benchmark
+ @OutputTimeUnit(TimeUnit.NANOSECONDS)
+ @BenchmarkMode(Mode.AverageTime)
+ public void blackHole(Blackhole blackhole) {
+ blackhole.consume(new Object());
+ }
+
+ @Benchmark
+ public double foldedLog() {
+ int x = 8;
+
+ return Math.log(x);
+ }
+
+ @Benchmark
+ public double log(Log input) {
+ return Math.log(input.x);
+ }
+
}
diff --git a/libraries-data-db/pom.xml b/libraries-data-db/pom.xml
index f028ffe8c3..d51580ccbc 100644
--- a/libraries-data-db/pom.xml
+++ b/libraries-data-db/pom.xml
@@ -211,7 +211,7 @@
5.0.2
5.0.4
3.2.0-m7
- 2.7.2
+ 3.4.5
11.22.4
diff --git a/libraries-server-2/.gitignore b/libraries-server-2/.gitignore
new file mode 100644
index 0000000000..e594daf27a
--- /dev/null
+++ b/libraries-server-2/.gitignore
@@ -0,0 +1,9 @@
+*.class
+
+# Folders #
+/gensrc
+/target
+
+# Packaged files #
+*.jar
+/bin/
diff --git a/libraries-server-2/README.md b/libraries-server-2/README.md
new file mode 100644
index 0000000000..38166bcd77
--- /dev/null
+++ b/libraries-server-2/README.md
@@ -0,0 +1,8 @@
+## Server
+
+This module contains articles about server libraries.
+
+### Relevant Articles:
+
+- [HTTP/2 in Jetty](https://www.baeldung.com/jetty-http-2)
+- More articles: [[<-- prev]](../libraries-server)
diff --git a/libraries-server-2/pom.xml b/libraries-server-2/pom.xml
new file mode 100644
index 0000000000..5f500a7ced
--- /dev/null
+++ b/libraries-server-2/pom.xml
@@ -0,0 +1,77 @@
+
+
+ 4.0.0
+ libraries-server-2
+ 0.0.1-SNAPSHOT
+ libraries-server-2
+ war
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+ org.eclipse.jetty
+ jetty-server
+ ${jetty.version}
+
+
+ org.eclipse.jetty
+ jetty-servlet
+ ${jetty.version}
+
+
+ org.eclipse.jetty
+ jetty-webapp
+ ${jetty.version}
+
+
+
+
+
+
+ org.eclipse.jetty
+ jetty-maven-plugin
+ ${jetty.version}
+
+ 8888
+ quit
+
+ -Xbootclasspath/p:${settings.localRepository}/org/mortbay/jetty/alpn/alpn-boot/${alpn.version}/alpn-boot-${alpn.version}.jar
+
+ ${basedir}/src/main/config/jetty.xml
+
+ /
+
+
+
+
+ org.eclipse.jetty.http2
+ http2-server
+ ${jetty.version}
+
+
+ org.eclipse.jetty
+ jetty-alpn-openjdk8-server
+ ${jetty.version}
+
+
+ org.eclipse.jetty
+ jetty-servlets
+ ${jetty.version}
+
+
+
+
+
+
+
+ 9.4.27.v20200227
+ 8.1.11.v20170118
+
+
+
\ No newline at end of file
diff --git a/libraries-server/src/main/config/jetty.xml b/libraries-server-2/src/main/config/jetty.xml
similarity index 100%
rename from libraries-server/src/main/config/jetty.xml
rename to libraries-server-2/src/main/config/jetty.xml
diff --git a/libraries-server/src/main/java/com/baeldung/jetty/http2/Http2JettyServlet.java b/libraries-server-2/src/main/java/com/baeldung/jetty/http2/Http2JettyServlet.java
similarity index 100%
rename from libraries-server/src/main/java/com/baeldung/jetty/http2/Http2JettyServlet.java
rename to libraries-server-2/src/main/java/com/baeldung/jetty/http2/Http2JettyServlet.java
diff --git a/libraries-server/src/main/resources/keystore.jks b/libraries-server-2/src/main/resources/keystore.jks
similarity index 100%
rename from libraries-server/src/main/resources/keystore.jks
rename to libraries-server-2/src/main/resources/keystore.jks
diff --git a/libraries-server-2/src/main/resources/logback.xml b/libraries-server-2/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/libraries-server-2/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libraries-server/src/main/resources/truststore.jks b/libraries-server-2/src/main/resources/truststore.jks
similarity index 100%
rename from libraries-server/src/main/resources/truststore.jks
rename to libraries-server-2/src/main/resources/truststore.jks
diff --git a/libraries-server/src/main/webapp/WEB-INF/web.xml b/libraries-server-2/src/main/webapp/WEB-INF/web.xml
similarity index 100%
rename from libraries-server/src/main/webapp/WEB-INF/web.xml
rename to libraries-server-2/src/main/webapp/WEB-INF/web.xml
diff --git a/libraries-server/src/main/webapp/http2.html b/libraries-server-2/src/main/webapp/http2.html
similarity index 100%
rename from libraries-server/src/main/webapp/http2.html
rename to libraries-server-2/src/main/webapp/http2.html
diff --git a/libraries-server/src/main/webapp/images/homepage-latest_articles.jpg b/libraries-server-2/src/main/webapp/images/homepage-latest_articles.jpg
similarity index 100%
rename from libraries-server/src/main/webapp/images/homepage-latest_articles.jpg
rename to libraries-server-2/src/main/webapp/images/homepage-latest_articles.jpg
diff --git a/libraries-server/src/main/webapp/images/homepage-rest_with_spring.jpg b/libraries-server-2/src/main/webapp/images/homepage-rest_with_spring.jpg
similarity index 100%
rename from libraries-server/src/main/webapp/images/homepage-rest_with_spring.jpg
rename to libraries-server-2/src/main/webapp/images/homepage-rest_with_spring.jpg
diff --git a/libraries-server/src/main/webapp/images/homepage-weekly_reviews.jpg b/libraries-server-2/src/main/webapp/images/homepage-weekly_reviews.jpg
similarity index 100%
rename from libraries-server/src/main/webapp/images/homepage-weekly_reviews.jpg
rename to libraries-server-2/src/main/webapp/images/homepage-weekly_reviews.jpg
diff --git a/libraries-server/src/main/webapp/index.html b/libraries-server-2/src/main/webapp/index.html
similarity index 100%
rename from libraries-server/src/main/webapp/index.html
rename to libraries-server-2/src/main/webapp/index.html
diff --git a/libraries-server/README.md b/libraries-server/README.md
index 7e41f33a0c..570806611f 100644
--- a/libraries-server/README.md
+++ b/libraries-server/README.md
@@ -13,4 +13,4 @@ This module contains articles about server libraries.
- [MQTT Client in Java](https://www.baeldung.com/java-mqtt-client)
- [Guide to XMPP Smack Client](https://www.baeldung.com/xmpp-smack-chat-client)
- [A Guide to NanoHTTPD](https://www.baeldung.com/nanohttpd)
-- [HTTP/2 in Jetty](https://www.baeldung.com/jetty-http-2)
+- More articles: [[more -->]](../libraries-server-2)
\ No newline at end of file
diff --git a/libraries-server/pom.xml b/libraries-server/pom.xml
index eb9cb61e56..d9546f1678 100644
--- a/libraries-server/pom.xml
+++ b/libraries-server/pom.xml
@@ -5,7 +5,6 @@
libraries-server
0.0.1-SNAPSHOT
libraries-server
- war
com.baeldung
@@ -107,50 +106,11 @@
-
-
-
- org.eclipse.jetty
- jetty-maven-plugin
- ${jetty.version}
-
- 8888
- quit
-
- -Xbootclasspath/p:${settings.localRepository}/org/mortbay/jetty/alpn/alpn-boot/${alpn.version}/alpn-boot-${alpn.version}.jar
-
- ${basedir}/src/main/config/jetty.xml
-
- /
-
-
-
-
- org.eclipse.jetty.http2
- http2-server
- ${jetty.version}
-
-
- org.eclipse.jetty
- jetty-alpn-openjdk8-server
- ${jetty.version}
-
-
- org.eclipse.jetty
- jetty-servlets
- ${jetty.version}
-
-
-
-
-
-
3.6.2
4.5.3
9.4.27.v20200227
4.1.20.Final
- 8.1.11.v20170118
8.5.24
4.3.1
1.2.0
diff --git a/netty/src/main/java/com/baeldung/http/server/CustomHttpServerHandler.java b/netty/src/main/java/com/baeldung/http/server/CustomHttpServerHandler.java
new file mode 100644
index 0000000000..038f559329
--- /dev/null
+++ b/netty/src/main/java/com/baeldung/http/server/CustomHttpServerHandler.java
@@ -0,0 +1,116 @@
+package com.baeldung.http.server;
+
+import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;
+import static io.netty.handler.codec.http.HttpResponseStatus.CONTINUE;
+import static io.netty.handler.codec.http.HttpResponseStatus.OK;
+import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
+
+import java.util.Set;
+
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import io.netty.handler.codec.http.DefaultFullHttpResponse;
+import io.netty.handler.codec.http.FullHttpResponse;
+import io.netty.handler.codec.http.HttpContent;
+import io.netty.handler.codec.http.HttpHeaderNames;
+import io.netty.handler.codec.http.HttpHeaderValues;
+import io.netty.handler.codec.http.HttpObject;
+import io.netty.handler.codec.http.HttpRequest;
+import io.netty.handler.codec.http.HttpUtil;
+import io.netty.handler.codec.http.LastHttpContent;
+import io.netty.handler.codec.http.cookie.Cookie;
+import io.netty.handler.codec.http.cookie.ServerCookieDecoder;
+import io.netty.handler.codec.http.cookie.ServerCookieEncoder;
+import io.netty.util.CharsetUtil;
+
+public class CustomHttpServerHandler extends SimpleChannelInboundHandler
-
+
org.springframework.boot
@@ -28,10 +29,43 @@
spring-boot-starter-data-jdbc
+
+ org.springframework.boot
+ spring-boot-starter-cache
+
+
com.h2database
h2
+
+
+ org.mapstruct
+ mapstruct-jdk8
+ 1.3.1.Final
+ provided
+
+
-
+
+ src/main/java
+
+
+ maven-compiler-plugin
+ 3.8.1
+
+
+ 1.8
+
+
+ org.mapstruct
+ mapstruct-processor
+ 1.3.1.Final
+
+
+
+
+
+
+
diff --git a/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/PartialUpdateApplication.java b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/PartialUpdateApplication.java
new file mode 100644
index 0000000000..a750fcadf7
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/PartialUpdateApplication.java
@@ -0,0 +1,12 @@
+package com.baeldung.partialupdate;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class PartialUpdateApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(PartialUpdateApplication.class, args);
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/ContactPhone.java b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/ContactPhone.java
new file mode 100644
index 0000000000..352e361bd9
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/ContactPhone.java
@@ -0,0 +1,22 @@
+package com.baeldung.partialupdate.model;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+public class ContactPhone {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ public long id;
+ @Column(nullable=false)
+ public long customerId;
+ public String phone;
+
+ @Override
+ public String toString() {
+ return phone;
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/Customer.java b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/Customer.java
new file mode 100644
index 0000000000..b19d0b7952
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/Customer.java
@@ -0,0 +1,23 @@
+package com.baeldung.partialupdate.model;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+public class Customer {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ public long id;
+ public String name;
+ public String phone;
+ //...
+ public String phone99;
+
+ @Override public String toString() {
+ return String.format("Customer %s, Phone: %s",
+ this.name, this.phone);
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/CustomerDto.java b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/CustomerDto.java
new file mode 100644
index 0000000000..0ecf206d9a
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/CustomerDto.java
@@ -0,0 +1,31 @@
+package com.baeldung.partialupdate.model;
+
+public class CustomerDto {
+ private long id;
+ public String name;
+ public String phone;
+ //...
+ private String phone99;
+
+ public CustomerDto(long id) {
+ this.id = id;
+ }
+
+ public CustomerDto(Customer c) {
+ this.id = c.id;
+ this.name = c.name;
+ this.phone = c.phone;
+ }
+
+ public long getId() {
+ return this.id;
+ }
+
+ public Customer convertToEntity() {
+ Customer c = new Customer();
+ c.id = id;
+ c.name = name;
+ c.phone = phone;
+ return c;
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/CustomerStructured.java b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/CustomerStructured.java
new file mode 100644
index 0000000000..dd053a963d
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/CustomerStructured.java
@@ -0,0 +1,27 @@
+package com.baeldung.partialupdate.model;
+
+import java.util.List;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+
+@Entity
+public class CustomerStructured {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ public long id;
+ public String name;
+ @OneToMany(fetch = FetchType.EAGER, targetEntity = ContactPhone.class, mappedBy = "customerId")
+ public List contactPhones;
+
+ @Override public String toString() {
+ return String.format("Customer %s, Phone: %s",
+ this.name, this.contactPhones.stream()
+ .map(e -> e.toString()).reduce("", String::concat));
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/repository/ContactPhoneRepository.java b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/repository/ContactPhoneRepository.java
new file mode 100644
index 0000000000..4668181e05
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/repository/ContactPhoneRepository.java
@@ -0,0 +1,12 @@
+package com.baeldung.partialupdate.repository;
+
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
+
+import com.baeldung.partialupdate.model.ContactPhone;
+
+@Repository
+public interface ContactPhoneRepository extends CrudRepository {
+ ContactPhone findById(long id);
+ ContactPhone findByCustomerId(long id);
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/repository/CustomerRepository.java b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/repository/CustomerRepository.java
new file mode 100644
index 0000000000..43e61df8ab
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/repository/CustomerRepository.java
@@ -0,0 +1,18 @@
+package com.baeldung.partialupdate.repository;
+
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import com.baeldung.partialupdate.model.Customer;
+
+@Repository
+public interface CustomerRepository extends CrudRepository {
+ Customer findById(long id);
+
+ @Modifying
+ @Query("update Customer u set u.phone = :phone where u.id = :id")
+ void updatePhone(@Param(value = "id") long id, @Param(value = "phone") String phone);
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/repository/CustomerStructuredRepository.java b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/repository/CustomerStructuredRepository.java
new file mode 100644
index 0000000000..0f9fd1e92e
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/repository/CustomerStructuredRepository.java
@@ -0,0 +1,11 @@
+package com.baeldung.partialupdate.repository;
+
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
+
+import com.baeldung.partialupdate.model.CustomerStructured;
+
+@Repository
+public interface CustomerStructuredRepository extends CrudRepository {
+ CustomerStructured findById(long id);
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/service/CustomerService.java b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/service/CustomerService.java
new file mode 100644
index 0000000000..9da97a7775
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/service/CustomerService.java
@@ -0,0 +1,87 @@
+package com.baeldung.partialupdate.service;
+
+import javax.transaction.Transactional;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.baeldung.partialupdate.model.ContactPhone;
+import com.baeldung.partialupdate.model.Customer;
+import com.baeldung.partialupdate.model.CustomerDto;
+import com.baeldung.partialupdate.model.CustomerStructured;
+import com.baeldung.partialupdate.repository.ContactPhoneRepository;
+import com.baeldung.partialupdate.repository.CustomerRepository;
+import com.baeldung.partialupdate.repository.CustomerStructuredRepository;
+import com.baeldung.partialupdate.util.CustomerMapper;
+
+@Service
+@Transactional
+public class CustomerService {
+
+ @Autowired
+ CustomerRepository repo;
+ @Autowired
+ CustomerStructuredRepository repo2;
+ @Autowired
+ ContactPhoneRepository repo3;
+ @Autowired
+ CustomerMapper mapper;
+
+ public Customer getCustomer(long id) {
+ return repo.findById(id);
+ }
+
+ public void updateCustomerWithCustomQuery(long id, String phone) {
+ repo.updatePhone(id, phone);
+ }
+
+ public Customer addCustomer(String name) {
+ Customer myCustomer = new Customer();
+ myCustomer.name = name;
+ repo.save(myCustomer);
+ return myCustomer;
+ }
+
+ public Customer updateCustomer(long id, String phone) {
+ Customer myCustomer = repo.findById(id);
+ myCustomer.phone = phone;
+ repo.save(myCustomer);
+ return myCustomer;
+ }
+
+ public Customer addCustomer(CustomerDto dto) {
+ Customer myCustomer = new Customer();
+ mapper.updateCustomerFromDto(dto, myCustomer);
+ repo.save(myCustomer);
+ return myCustomer;
+ }
+
+ public Customer updateCustomer(CustomerDto dto) {
+ Customer myCustomer = repo.findById(dto.getId());
+ mapper.updateCustomerFromDto(dto, myCustomer);
+ repo.save(myCustomer);
+ return myCustomer;
+ }
+
+ public CustomerStructured addCustomerStructured(String name) {
+ CustomerStructured myCustomer = new CustomerStructured();
+ myCustomer.name = name;
+ repo2.save(myCustomer);
+ return myCustomer;
+ }
+
+ public void addCustomerPhone(long customerId, String phone) {
+ ContactPhone myPhone = new ContactPhone();
+ myPhone.phone = phone;
+ myPhone.customerId = customerId;
+ repo3.save(myPhone);
+ }
+
+ public CustomerStructured updateCustomerStructured(long id, String name) {
+ CustomerStructured myCustomer = repo2.findById(id);
+ myCustomer.name = name;
+ repo2.save(myCustomer);
+ return myCustomer;
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/util/CustomerMapper.java b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/util/CustomerMapper.java
new file mode 100644
index 0000000000..8a666e3e6c
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/util/CustomerMapper.java
@@ -0,0 +1,15 @@
+package com.baeldung.partialupdate.util;
+
+import org.mapstruct.BeanMapping;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingTarget;
+import org.mapstruct.NullValuePropertyMappingStrategy;
+
+import com.baeldung.partialupdate.model.Customer;
+import com.baeldung.partialupdate.model.CustomerDto;
+
+@Mapper(componentModel = "spring")
+public interface CustomerMapper {
+ @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
+ void updateCustomerFromDto(CustomerDto dto, @MappingTarget Customer entity);
+}
diff --git a/persistence-modules/spring-data-jpa-5/src/test/java/com/baeldung/partialupdate/PartialUpdateUnitTest.java b/persistence-modules/spring-data-jpa-5/src/test/java/com/baeldung/partialupdate/PartialUpdateUnitTest.java
new file mode 100644
index 0000000000..874e18c4ad
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/test/java/com/baeldung/partialupdate/PartialUpdateUnitTest.java
@@ -0,0 +1,63 @@
+package com.baeldung.partialupdate;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+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 com.baeldung.partialupdate.model.Customer;
+import com.baeldung.partialupdate.model.CustomerDto;
+import com.baeldung.partialupdate.model.CustomerStructured;
+import com.baeldung.partialupdate.service.CustomerService;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = PartialUpdateApplication.class)
+public class PartialUpdateUnitTest {
+
+ @Autowired
+ CustomerService service;
+
+ @Test
+ public void givenCustomer_whenUpdate_thenSuccess() {
+ Customer myCustomer = service.addCustomer("John");
+ myCustomer = service.updateCustomer(myCustomer.id, "+00");
+ assertEquals("+00", myCustomer.phone);
+ }
+
+ @Test
+ public void givenCustomer_whenUpdateWithQuery_thenSuccess() {
+ Customer myCustomer = service.addCustomer("John");
+ service.updateCustomerWithCustomQuery(myCustomer.id, "+88");
+ myCustomer = service.getCustomer(myCustomer.id);
+ assertEquals("+88", myCustomer.phone);
+ }
+
+ @Test
+ public void givenCustomerDto_whenUpdateWithMapper_thenSuccess() {
+ CustomerDto dto = new CustomerDto(new Customer());
+ dto.name = "Johnny";
+ Customer entity = service.addCustomer(dto);
+
+ CustomerDto dto2 = new CustomerDto(entity.id);
+ dto2.phone = "+44";
+ entity = service.updateCustomer(dto2);
+
+ assertEquals("Johnny", entity.name);
+ }
+
+ @Test
+ public void givenCustomerStructured_whenUpdateCustomerPhone_thenSuccess() {
+ CustomerStructured myCustomer = service.addCustomerStructured("John");
+ assertEquals(null, myCustomer.contactPhones);
+
+ service.addCustomerPhone(myCustomer.id, "+44");
+ myCustomer = service.updateCustomerStructured(myCustomer.id, "Mr. John");
+
+ assertNotEquals(null, myCustomer.contactPhones);
+ assertEquals(1, myCustomer.contactPhones.size());
+ }
+}
diff --git a/persistence-modules/spring-data-redis/README.md b/persistence-modules/spring-data-redis/README.md
index 175634376b..95cba2c159 100644
--- a/persistence-modules/spring-data-redis/README.md
+++ b/persistence-modules/spring-data-redis/README.md
@@ -4,7 +4,6 @@
- [Introduction to Spring Data Redis](https://www.baeldung.com/spring-data-redis-tutorial)
- [PubSub Messaging with Spring Data Redis](https://www.baeldung.com/spring-data-redis-pub-sub)
- [An Introduction to Spring Data Redis Reactive](https://www.baeldung.com/spring-data-redis-reactive)
-- [Delete Everything in Redis](https://www.baeldung.com/redis-delete-data)
### Build the Project with Tests Running
```
@@ -15,4 +14,3 @@ mvn clean install
```
mvn test
```
-
diff --git a/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/config/RedisConfig.java b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/config/RedisConfig.java
index fdc279be42..497e1506bd 100644
--- a/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/config/RedisConfig.java
+++ b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/config/RedisConfig.java
@@ -35,18 +35,6 @@ public class RedisConfig {
template.setValueSerializer(new GenericToStringSerializer