This commit is contained in:
Ulisses Lima 2023-05-31 09:41:18 -03:00
commit 8a6a9b3273
193 changed files with 4021 additions and 1015 deletions

View File

@ -23,7 +23,7 @@ public class Graph {
adjVertices.get(src).add(dest);
}
public void dfsWithoutRecursion(int start) {
public boolean[] dfsWithoutRecursion(int start) {
Stack<Integer> stack = new Stack<Integer>();
boolean[] isVisited = new boolean[adjVertices.size()];
stack.push(start);
@ -38,20 +38,22 @@ public class Graph {
}
}
}
return isVisited;
}
public void dfs(int start) {
public boolean[] dfs(int start) {
boolean[] isVisited = new boolean[adjVertices.size()];
dfsRecursive(start, isVisited);
return dfsRecursive(start, isVisited);
}
private void dfsRecursive(int current, boolean[] isVisited) {
private boolean[] dfsRecursive(int current, boolean[] isVisited) {
isVisited[current] = true;
visit(current);
for (int dest : adjVertices.get(current)) {
if (!isVisited[dest])
dfsRecursive(dest, isVisited);
}
return isVisited;
}
public List<Integer> topologicalSort(int start) {

View File

@ -1,7 +1,9 @@
package com.baeldung.algorithms.dfs;
import java.util.Arrays;
import java.util.List;
import org.junit.Assert;
import org.junit.jupiter.api.Test;
class GraphUnitTest {
@ -9,9 +11,12 @@ class GraphUnitTest {
@Test
void givenDirectedGraph_whenDFS_thenPrintAllValues() {
Graph graph = createDirectedGraph();
graph.dfs(0);
System.out.println();
graph.dfsWithoutRecursion(0);
boolean[] visited;
visited = graph.dfs(0);
boolean[] expected = new boolean[]{true, true, true, true, true, true};
Assert.assertArrayEquals(expected, visited);
visited = graph.dfsWithoutRecursion(0);
Assert.assertArrayEquals(expected, visited);
}
@Test
@ -19,6 +24,8 @@ class GraphUnitTest {
Graph graph = createDirectedGraph();
List<Integer> list = graph.topologicalSort(0);
System.out.println(list);
List<Integer> expected = Arrays.asList(0, 2, 1, 3, 4, 5);
Assert.assertEquals(expected, list);
}
private Graph createDirectedGraph() {

View File

@ -1,7 +1,7 @@
package com.baeldung.httpclient;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
@ -9,30 +9,36 @@ import java.util.concurrent.Future;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
import org.apache.http.nio.reactor.ConnectingIOReactor;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContexts;
import org.junit.Test;
import org.junit.jupiter.api.Test;
public class HttpAsyncClientLiveTest {
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
import org.apache.hc.client5.http.auth.AuthScope;
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.cookie.BasicCookieStore;
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
import org.apache.hc.client5.http.impl.cookie.BasicClientCookie;
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.ssl.ClientTlsStrategyBuilder;
import org.apache.hc.core5.concurrent.FutureCallback;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
import org.apache.hc.core5.http.protocol.BasicHttpContext;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.reactor.IOReactorConfig;
import org.apache.hc.core5.ssl.SSLContexts;
import org.apache.hc.core5.ssl.TrustStrategy;
class HttpAsyncClientLiveTest {
private static final String HOST = "http://www.google.com";
private static final String HOST_WITH_SSL = "https://mms.nw.ru/";
@ -48,23 +54,33 @@ public class HttpAsyncClientLiveTest {
// tests
@Test
public void whenUseHttpAsyncClient_thenCorrect() throws InterruptedException, ExecutionException, IOException {
void whenUseHttpAsyncClient_thenCorrect() throws InterruptedException, ExecutionException, IOException {
final HttpHost target = new HttpHost(HOST);
final SimpleHttpRequest request = SimpleRequestBuilder.get()
.setHttpHost(target)
.build();
final CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
client.start();
final HttpGet request = new HttpGet(HOST);
final Future<HttpResponse> future = client.execute(request, null);
final Future<SimpleHttpResponse> future = client.execute(request, null);
final HttpResponse response = future.get();
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
assertThat(response.getCode(), equalTo(200));
client.close();
}
@Test
public void whenUseMultipleHttpAsyncClient_thenCorrect() throws Exception {
final ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor();
final PoolingNHttpClientConnectionManager cm = new PoolingNHttpClientConnectionManager(ioReactor);
final CloseableHttpAsyncClient client = HttpAsyncClients.custom().setConnectionManager(cm).build();
void whenUseMultipleHttpAsyncClient_thenCorrect() throws Exception {
final IOReactorConfig ioReactorConfig = IOReactorConfig
.custom()
.build();
final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
.setIOReactorConfig(ioReactorConfig)
.build();
client.start();
final String[] toGet = { "http://www.google.com/", "http://www.apache.org/", "http://www.bing.com/" };
@ -85,36 +101,68 @@ public class HttpAsyncClientLiveTest {
}
@Test
public void whenUseProxyWithHttpClient_thenCorrect() throws Exception {
void whenUseProxyWithHttpClient_thenCorrect() throws Exception {
final CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
client.start();
final HttpHost proxy = new HttpHost("127.0.0.1", 8080);
final RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
final HttpGet request = new HttpGet(HOST_WITH_PROXY);
final SimpleHttpRequest request = new SimpleHttpRequest("GET" ,HOST_WITH_PROXY);
request.setConfig(config);
final Future<HttpResponse> future = client.execute(request, null);
final HttpResponse response = future.get();
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
final Future<SimpleHttpResponse> future = client.execute(request, new FutureCallback<>(){
@Override
public void completed(SimpleHttpResponse response) {
System.out.println("responseData");
}
@Override
public void failed(Exception ex) {
System.out.println("Error executing HTTP request: " + ex.getMessage());
}
@Override
public void cancelled() {
System.out.println("HTTP request execution cancelled");
}
});
final HttpResponse response = future.get();
assertThat(response.getCode(), equalTo(200));
client.close();
}
@Test
public void whenUseSSLWithHttpAsyncClient_thenCorrect() throws Exception {
void whenUseSSLWithHttpAsyncClient_thenCorrect() throws Exception {
final TrustStrategy acceptingTrustStrategy = (certificate, authType) -> true;
final SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
final CloseableHttpAsyncClient client = HttpAsyncClients.custom().setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).setSSLContext(sslContext).build();
final SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(null, acceptingTrustStrategy)
.build();
final TlsStrategy tlsStrategy = ClientTlsStrategyBuilder.create()
.setSslContext(sslContext)
.build();
final PoolingAsyncClientConnectionManager cm = PoolingAsyncClientConnectionManagerBuilder.create()
.setTlsStrategy(tlsStrategy)
.build();
final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
.setConnectionManager(cm)
.build();
client.start();
final HttpGet request = new HttpGet(HOST_WITH_SSL);
final Future<HttpResponse> future = client.execute(request, null);
final SimpleHttpRequest request = new SimpleHttpRequest("GET",HOST_WITH_SSL);
final Future<SimpleHttpResponse> future = client.execute(request, null);
final HttpResponse response = future.get();
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
assertThat(response.getCode(), equalTo(200));
client.close();
}
@Test
public void whenUseCookiesWithHttpAsyncClient_thenCorrect() throws Exception {
void whenUseCookiesWithHttpAsyncClient_thenCorrect() throws Exception {
final BasicCookieStore cookieStore = new BasicCookieStore();
final BasicClientCookie cookie = new BasicClientCookie(COOKIE_NAME, "1234");
cookie.setDomain(COOKIE_DOMAIN);
@ -122,29 +170,36 @@ public class HttpAsyncClientLiveTest {
cookieStore.addCookie(cookie);
final CloseableHttpAsyncClient client = HttpAsyncClients.custom().build();
client.start();
final HttpGet request = new HttpGet(HOST_WITH_COOKIE);
final SimpleHttpRequest request = new SimpleHttpRequest("GET" ,HOST_WITH_COOKIE);
final HttpContext localContext = new BasicHttpContext();
localContext.setAttribute(HttpClientContext.COOKIE_STORE, cookieStore);
final Future<HttpResponse> future = client.execute(request, localContext, null);
final Future<SimpleHttpResponse> future = client.execute(request, localContext, null);
final HttpResponse response = future.get();
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
assertThat(response.getCode(), equalTo(200));
client.close();
}
@Test
public void whenUseAuthenticationWithHttpAsyncClient_thenCorrect() throws Exception {
final CredentialsProvider provider = new BasicCredentialsProvider();
final UsernamePasswordCredentials creds = new UsernamePasswordCredentials(DEFAULT_USER, DEFAULT_PASS);
provider.setCredentials(AuthScope.ANY, creds);
final CloseableHttpAsyncClient client = HttpAsyncClients.custom().setDefaultCredentialsProvider(provider).build();
void whenUseAuthenticationWithHttpAsyncClient_thenCorrect() throws Exception {
final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
final UsernamePasswordCredentials credentials =
new UsernamePasswordCredentials(DEFAULT_USER, DEFAULT_PASS.toCharArray());
credsProvider.setCredentials(new AuthScope(URL_SECURED_BY_BASIC_AUTHENTICATION, 80) ,credentials);
final CloseableHttpAsyncClient client = HttpAsyncClients
.custom()
.setDefaultCredentialsProvider(credsProvider).build();
final SimpleHttpRequest request = new SimpleHttpRequest("GET" ,URL_SECURED_BY_BASIC_AUTHENTICATION);
final HttpGet request = new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION);
client.start();
final Future<HttpResponse> future = client.execute(request, null);
final Future<SimpleHttpResponse> future = client.execute(request, null);
final HttpResponse response = future.get();
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
assertThat(response.getCode(), equalTo(200));
client.close();
}
@ -163,9 +218,9 @@ public class HttpAsyncClientLiveTest {
@Override
public void run() {
try {
final Future<HttpResponse> future = client.execute(request, context, null);
final Future<SimpleHttpResponse> future = client.execute(SimpleHttpRequest.copy(request), context, null);
final HttpResponse response = future.get();
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
assertThat(response.getCode(), equalTo(200));
} catch (final Exception ex) {
System.out.println(ex.getLocalizedMessage());
}

View File

@ -0,0 +1,174 @@
package com.baeldung.httpclient;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
import org.apache.http.nio.reactor.ConnectingIOReactor;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContexts;
import org.junit.jupiter.api.Test;
class HttpAsyncClientV4LiveTest {
private static final String HOST = "http://www.google.com";
private static final String HOST_WITH_SSL = "https://mms.nw.ru/";
private static final String HOST_WITH_PROXY = "http://httpbin.org/";
private static final String URL_SECURED_BY_BASIC_AUTHENTICATION = "http://browserspy.dk/password-ok.php";// "http://localhost:8080/spring-security-rest-basic-auth/api/foos/1";
private static final String DEFAULT_USER = "test";// "user1";
private static final String DEFAULT_PASS = "test";// "user1Pass";
private static final String HOST_WITH_COOKIE = "http://yuilibrary.com/yui/docs/cookie/cookie-simple-example.html"; // "http://github.com";
private static final String COOKIE_DOMAIN = ".yuilibrary.com"; // ".github.com";
private static final String COOKIE_NAME = "example"; // "JSESSIONID";
// tests
@Test
void whenUseHttpAsyncClient_thenCorrect() throws InterruptedException, ExecutionException, IOException {
final CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
client.start();
final HttpGet request = new HttpGet(HOST);
final Future<HttpResponse> future = client.execute(request, null);
final HttpResponse response = future.get();
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
client.close();
}
@Test
void whenUseMultipleHttpAsyncClient_thenCorrect() throws Exception {
final ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor();
final PoolingNHttpClientConnectionManager cm = new PoolingNHttpClientConnectionManager(ioReactor);
final CloseableHttpAsyncClient client = HttpAsyncClients.custom().setConnectionManager(cm).build();
client.start();
final String[] toGet = { "http://www.google.com/", "http://www.apache.org/", "http://www.bing.com/" };
final GetThread[] threads = new GetThread[toGet.length];
for (int i = 0; i < threads.length; i++) {
final HttpGet request = new HttpGet(toGet[i]);
threads[i] = new GetThread(client, request);
}
for (final GetThread thread : threads) {
thread.start();
}
for (final GetThread thread : threads) {
thread.join();
}
}
@Test
void whenUseProxyWithHttpClient_thenCorrect() throws Exception {
final CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
client.start();
final HttpHost proxy = new HttpHost("127.0.0.1", 8080);
final RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
final HttpGet request = new HttpGet(HOST_WITH_PROXY);
request.setConfig(config);
final Future<HttpResponse> future = client.execute(request, null);
final HttpResponse response = future.get();
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
client.close();
}
@Test
void whenUseSSLWithHttpAsyncClient_thenCorrect() throws Exception {
final TrustStrategy acceptingTrustStrategy = (certificate, authType) -> true;
final SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
final CloseableHttpAsyncClient client = HttpAsyncClients.custom().setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).setSSLContext(sslContext).build();
client.start();
final HttpGet request = new HttpGet(HOST_WITH_SSL);
final Future<HttpResponse> future = client.execute(request, null);
final HttpResponse response = future.get();
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
client.close();
}
@Test
void whenUseCookiesWithHttpAsyncClient_thenCorrect() throws Exception {
final BasicCookieStore cookieStore = new BasicCookieStore();
final BasicClientCookie cookie = new BasicClientCookie(COOKIE_NAME, "1234");
cookie.setDomain(COOKIE_DOMAIN);
cookie.setPath("/");
cookieStore.addCookie(cookie);
final CloseableHttpAsyncClient client = HttpAsyncClients.custom().build();
client.start();
final HttpGet request = new HttpGet(HOST_WITH_COOKIE);
final HttpContext localContext = new BasicHttpContext();
localContext.setAttribute(HttpClientContext.COOKIE_STORE, cookieStore);
final Future<HttpResponse> future = client.execute(request, localContext, null);
final HttpResponse response = future.get();
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
client.close();
}
@Test
void whenUseAuthenticationWithHttpAsyncClient_thenCorrect() throws Exception {
final CredentialsProvider provider = new BasicCredentialsProvider();
final UsernamePasswordCredentials creds = new UsernamePasswordCredentials(DEFAULT_USER, DEFAULT_PASS);
provider.setCredentials(AuthScope.ANY, creds);
final CloseableHttpAsyncClient client = HttpAsyncClients.custom().setDefaultCredentialsProvider(provider).build();
final HttpGet request = new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION);
client.start();
final Future<HttpResponse> future = client.execute(request, null);
final HttpResponse response = future.get();
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
client.close();
}
static class GetThread extends Thread {
private final CloseableHttpAsyncClient client;
private final HttpContext context;
private final HttpGet request;
GetThread(final CloseableHttpAsyncClient client, final HttpGet request) {
this.client = client;
context = HttpClientContext.create();
this.request = request;
}
@Override
public void run() {
try {
final Future<HttpResponse> future = client.execute(request, context, null);
final HttpResponse response = future.get();
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
} catch (final Exception ex) {
System.out.println(ex.getLocalizedMessage());
}
}
}
}

View File

@ -8,3 +8,4 @@ You can build the project from the command line using: *mvn clean install*, or i
### Relevant Articles:
- [Guide to Check if Apache Kafka Server Is Running](https://www.baeldung.com/apache-kafka-check-server-is-running)
- [Add Custom Headers to a Kafka Message](https://www.baeldung.com/java-kafka-custom-headers)
- [Get Last N Messages in Apache Kafka Topic](https://www.baeldung.com/java-apache-kafka-get-last-n-messages)

View File

@ -0,0 +1,81 @@
package com.baeldung.kafka.consumer;
import java.time.Duration;
import java.util.Arrays;
import java.util.Properties;
import java.util.UUID;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.kafka.common.serialization.StringSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ConsumeFromBeginning {
private static Logger logger = LoggerFactory.getLogger(ConsumeFromBeginning.class);
private static String TOPIC = "baeldung";
private static int messagesInTopic = 10;
private static KafkaProducer<String, String> producer;
private static KafkaConsumer<String, String> consumer;
public static void main(String[] args) {
setup();
publishMessages();
consumeFromBeginning();
}
private static void consumeFromBeginning() {
consumer.subscribe(Arrays.asList(TOPIC));
ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(10));
for (ConsumerRecord<String, String> record : records) {
logger.info(record.value());
}
consumer.seekToBeginning(consumer.assignment());
records = consumer.poll(Duration.ofSeconds(10));
for (ConsumerRecord<String, String> record : records) {
logger.info(record.value());
}
}
private static void publishMessages() {
for (int i = 1; i <= messagesInTopic; i++) {
ProducerRecord<String, String> record = new ProducerRecord<>(TOPIC, String.valueOf(i));
producer.send(record);
}
}
private static void setup() {
Properties producerProperties = new Properties();
producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
Properties consumerProperties = new Properties();
consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, UUID.randomUUID()
.toString());
producer = new KafkaProducer<>(producerProperties);
consumer = new KafkaConsumer<>(consumerProperties);
}
}

View File

@ -0,0 +1,106 @@
package com.baeldung.kafka.message;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.Properties;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.apache.kafka.clients.admin.Admin;
import org.apache.kafka.clients.admin.AdminClientConfig;
import org.apache.kafka.clients.admin.NewTopic;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.kafka.common.serialization.StringSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MessageWithKey {
private static Logger logger = LoggerFactory.getLogger(MessageWithKey.class);
private static String TOPIC = "baeldung";
private static int PARTITIONS = 5;
private static short REPLICATION_FACTOR = 1;
private static String MESSAGE_KEY = "message-key";
private static Admin admin;
private static KafkaProducer<String, String> producer;
private static KafkaConsumer<String, String> consumer;
public static void main(String[] args) throws ExecutionException, InterruptedException {
setup();
publishMessagesWithoutKey();
consumeMessages();
publishMessagesWithKey();
consumeMessages();
}
private static void consumeMessages() {
consumer.subscribe(Arrays.asList(TOPIC));
ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(5));
for (ConsumerRecord<String, String> record : records) {
logger.info("Key : {}, Value : {}", record.key(), record.value());
}
}
private static void publishMessagesWithKey() throws ExecutionException, InterruptedException {
for (int i = 1; i <= 10; i++) {
ProducerRecord<String, String> record = new ProducerRecord<>(TOPIC, MESSAGE_KEY, String.valueOf(i));
Future<RecordMetadata> future = producer.send(record);
RecordMetadata metadata = future.get();
logger.info(String.valueOf(metadata.partition()));
}
}
private static void publishMessagesWithoutKey() throws ExecutionException, InterruptedException {
for (int i = 1; i <= 10; i++) {
ProducerRecord<String, String> record = new ProducerRecord<>(TOPIC, String.valueOf(i));
Future<RecordMetadata> future = producer.send(record);
RecordMetadata metadata = future.get();
logger.info(String.valueOf(metadata.partition()));
}
}
private static void setup() {
Properties adminProperties = new Properties();
adminProperties.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
Properties producerProperties = new Properties();
producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
Properties consumerProperties = new Properties();
consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, UUID.randomUUID()
.toString());
admin = Admin.create(adminProperties);
producer = new KafkaProducer<>(producerProperties);
consumer = new KafkaConsumer<>(consumerProperties);
admin.createTopics(Collections.singleton(new NewTopic(TOPIC, PARTITIONS, REPLICATION_FACTOR)));
}
}

View File

@ -0,0 +1,109 @@
package com.baeldung.kafka.consumer;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.time.Duration;
import java.util.Arrays;
import java.util.Properties;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.kafka.common.serialization.StringSerializer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.KafkaContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
// This live test needs a Docker Daemon running so that a kafka container can be created
@Testcontainers
public class ConsumeFromBeginningLiveTest {
private static Logger logger = LoggerFactory.getLogger(ConsumeFromBeginningLiveTest.class);
private static String TOPIC = "baeldung";
private static int messagesInTopic = 10;
private static KafkaProducer<String, String> producer;
private static KafkaConsumer<String, String> consumer;
@Container
private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest"));
@BeforeAll
static void setup() {
KAFKA_CONTAINER.addExposedPort(9092);
Properties producerProperties = new Properties();
producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
Properties consumerProperties = new Properties();
consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, UUID.randomUUID()
.toString());
producer = new KafkaProducer<>(producerProperties);
consumer = new KafkaConsumer<>(consumerProperties);
}
private static void publishMessages() throws ExecutionException, InterruptedException {
for (int i = 1; i <= messagesInTopic; i++) {
ProducerRecord<String, String> record = new ProducerRecord<>(TOPIC, String.valueOf(i));
producer.send(record)
.get();
}
}
@AfterAll
static void destroy() {
KAFKA_CONTAINER.stop();
}
@Test
void givenMessages_whenConsumedFromBeginning_thenCheckIfConsumedFromBeginning() throws ExecutionException, InterruptedException {
publishMessages();
consumer.subscribe(Arrays.asList(TOPIC));
ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(10));
int messageCount = 0;
for (ConsumerRecord<String, String> record : records) {
logger.info(record.value());
messageCount++;
}
assertEquals(messagesInTopic, messageCount);
consumer.seekToBeginning(consumer.assignment());
records = consumer.poll(Duration.ofSeconds(10));
messageCount = 0;
for (ConsumerRecord<String, String> record : records) {
logger.info(record.value());
messageCount++;
}
assertEquals(messagesInTopic, messageCount);
}
}

View File

@ -0,0 +1,130 @@
package com.baeldung.kafka.message;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.Properties;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.apache.kafka.clients.admin.Admin;
import org.apache.kafka.clients.admin.AdminClientConfig;
import org.apache.kafka.clients.admin.NewTopic;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.kafka.common.serialization.StringSerializer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.KafkaContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
// This live test needs a Docker Daemon running so that a kafka container can be created
@Testcontainers
public class MessageWithKeyLiveTest {
private static String TOPIC = "baeldung";
private static int PARTITIONS = 5;
private static short REPLICATION_FACTOR = 1;
private static String MESSAGE_KEY = "message-key";
private static String MESSAGE_VALUE = "Hello World";
private static Admin admin;
private static KafkaProducer<String, String> producer;
private static KafkaConsumer<String, String> consumer;
@Container
private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest"));
@BeforeAll
static void setup() {
KAFKA_CONTAINER.addExposedPort(9092);
Properties adminProperties = new Properties();
adminProperties.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
Properties producerProperties = new Properties();
producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
Properties consumerProperties = new Properties();
consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, UUID.randomUUID()
.toString());
admin = Admin.create(adminProperties);
producer = new KafkaProducer<>(producerProperties);
consumer = new KafkaConsumer<>(consumerProperties);
admin.createTopics(Collections.singleton(new NewTopic(TOPIC, PARTITIONS, REPLICATION_FACTOR)));
}
@AfterAll
static void destroy() {
KAFKA_CONTAINER.stop();
}
@Test
void givenAMessageWithKey_whenPublishedToKafkaAndConsumed_thenCheckForKey() throws ExecutionException, InterruptedException {
ProducerRecord<String, String> producerRecord = new ProducerRecord<>(TOPIC, MESSAGE_KEY, MESSAGE_VALUE);
Future<RecordMetadata> future = producer.send(producerRecord);
RecordMetadata metadata = future.get();
assertNotNull(metadata);
consumer.subscribe(Arrays.asList(TOPIC));
ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(5));
for (ConsumerRecord<String, String> consumerRecord : records) {
assertEquals(MESSAGE_KEY, consumerRecord.key());
assertEquals(MESSAGE_VALUE, consumerRecord.value());
}
}
@Test
void givenAListOfMessageWithKeys_whenPublishedToKafka_thenCheckedIfPublishedToSamePartition() throws ExecutionException, InterruptedException {
boolean isSamePartition = true;
int partition = 0;
for (int i = 1; i <= 10; i++) {
ProducerRecord<String, String> producerRecord = new ProducerRecord<>(TOPIC, MESSAGE_KEY, MESSAGE_VALUE);
Future<RecordMetadata> future = producer.send(producerRecord);
RecordMetadata metadata = future.get();
assertNotNull(metadata);
if (i == 1) {
partition = metadata.partition();
} else {
if (partition != metadata.partition()) {
isSamePartition = false;
}
}
}
assertTrue(isSamePartition);
}
}

View File

@ -20,5 +20,5 @@ Two scripts are included to easily start middleware using Docker matching the pr
- [Multi-Entity Aggregates in Axon](https://www.baeldung.com/java-axon-multi-entity-aggregates)
- [Snapshotting Aggregates in Axon](https://www.baeldung.com/axon-snapshotting-aggregates)
- [Dispatching Queries in Axon Framework](https://www.baeldung.com/axon-query-dispatching)
- [Persisting the Query Model](https://www.baeldung.com/persisting-the-query-model)
- [Using and testing Axon applications via REST](https://www.baeldung.com/using-and-testing-axon-applications-via-rest)
- [Persisting the Query Model](https://www.baeldung.com/axon-persisting-query-model)
- [Using and Testing Axon Applications via REST](https://www.baeldung.com/using-and-testing-axon-applications-via-rest)

View File

@ -4,4 +4,5 @@
### Relevant Articles:
- [Introduction to Roaring Bitmap](https://www.baeldung.com/java-roaring-bitmap-intro)
- [Creating Custom Iterator in Java](https://www.baeldung.com/java-creating-custom-iterator)
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-4)

View File

@ -6,3 +6,4 @@ This module contains articles about the Java List collection
- [Java List Interface](https://www.baeldung.com/java-list-interface)
- [Finding All Duplicates in a List in Java](https://www.baeldung.com/java-list-find-duplicates)
- [Moving Items Around in an Arraylist](https://www.baeldung.com/java-arraylist-move-items)
- [Check if a List Contains an Element From Another List in Java](https://www.baeldung.com/java-check-elements-between-lists)

View File

@ -1,65 +1,77 @@
package com.baeldung.arrayandlistperformance;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class ArrayAndArrayListPerformance {
@Benchmark
public void arrayCreation() {
int[] array = new int[1000000];
}
@Benchmark
public void arrayListCreation() {
ArrayList<Integer> list = new ArrayList<>(1000000);
}
@Benchmark
public void arrayItemSetting() {
int[] array = new int[1000000];
array[0] = 10;
}
@Benchmark
public void arrayListItemSetting() {
ArrayList<Integer> list = new ArrayList<>(1000000);
list.add(0, 10);
}
@Benchmark
public void arrayItemRetrieval() {
int[] array = new int[1000000];
array[0] = 10;
int item = array[0];
}
@Benchmark
public void arrayListItemRetrieval() {
ArrayList<Integer> list = new ArrayList<>(1000000);
list.add(0, 10);
int item2 = list.get(0);
}
@Benchmark
public void arrayCloning() {
int[] array = new int[1000000];
int[] newArray = array.clone();
}
@Benchmark
public void arrayListCloning() {
ArrayList<Integer> list = new ArrayList<>(1000000);
ArrayList<Integer> newList = new ArrayList<>(list);
}
public static void main(String[] args) throws Exception {
org.openjdk.jmh.runner.Runner runner = new org.openjdk.jmh.runner.Runner(new OptionsBuilder()
.include(ArrayAndArrayListPerformance.class.getSimpleName())
.forks(1)
.build());
org.openjdk.jmh.runner.Runner runner = new org.openjdk.jmh.runner.Runner(new OptionsBuilder().include(ArrayAndArrayListPerformance.class.getSimpleName()).forks(1).build());
runner.run();
}
}
public static Integer[] array = Collections.nCopies(256, 1).toArray(new Integer[0]);
public static ArrayList<Integer> list = new ArrayList<Integer>(
Arrays.asList(array));
@Benchmark
public Integer[] arrayCreation() {
return new Integer[256];
}
@Benchmark
public ArrayList<Integer> arrayListCreation() {
return new ArrayList<>(256);
}
@Benchmark
public Integer[] arrayItemsSetting() {
for (int i = 0; i < 256; i++) {
array[i] = i;
}
return array;
}
@Benchmark
public ArrayList<Integer> arrayListItemsSetting() {
for (int i = 0; i < 256; i++) {
list.set(i,i);
}
return list;
}
@Benchmark
public void arrayItemsRetrieval(Blackhole blackhole) {
for (int i = 0; i < 256; i++) {
int item = array[i];
blackhole.consume(item);
}
}
@Benchmark
public void arrayListItemsRetrieval(Blackhole blackhole) {
for (int i = 0; i < 256; i++) {
int item = list.get(i);
blackhole.consume(item);
}
}
@Benchmark
public void arrayCloning(Blackhole blackhole) {
Integer[] newArray = array.clone();
blackhole.consume(newArray);
}
@Benchmark
public void arrayListCloning(Blackhole blackhole) {
ArrayList<Integer> newList = new ArrayList<>(list);
blackhole.consume(newList);
}
}

View File

@ -0,0 +1,92 @@
package com.baeldung.java.listwithdefault;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.function.Supplier;
import org.junit.jupiter.api.Test;
import com.google.common.collect.Lists;
public class ListWithDefaultValuesUnitTest {
private static final List<String> EXPECTED_LIST = Lists.newArrayList("new", "new", "new", "new", "new");
private static final Date DATE_EPOCH = Date.from(Instant.EPOCH);
private static final Date DATE_NOW = new Date();
static <T> List<T> newListWithDefault(T value, int size) {
List<T> list = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
list.add(value);
}
return list;
}
static <T> List<T> newListWithDefault2(Supplier<T> supplier, int size) {
List<T> list = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
list.add(supplier.get());
}
return list;
}
@Test
void whenUsingArraysFill_thenGetExpectedList() {
String[] strings = new String[5];
Arrays.fill(strings, "new");
List<String> result = Arrays.asList(strings);
assertEquals(EXPECTED_LIST, result);
//result is a fixed size list
assertThrows(UnsupportedOperationException.class, () -> result.add("a new string"));
assertThrows(UnsupportedOperationException.class, () -> result.remove(0));
//result's element can be "set"
result.set(2, "a new value");
assertEquals("a new value", result.get(2));
Date[] dates = new Date[2];
Arrays.fill(dates, Date.from(Instant.EPOCH));
List<Date> dateList = Arrays.asList(dates);
assertEquals(Lists.newArrayList(DATE_EPOCH, DATE_EPOCH), dateList);
dateList.get(0)
.setTime(DATE_NOW.getTime());
assertEquals(Lists.newArrayList(DATE_NOW, DATE_NOW), dateList);
}
@Test
void whenUsingNewListWithDefault_thenGetExpectedList() {
List<String> result = newListWithDefault("new", 5);
assertEquals(EXPECTED_LIST, result);
List<Integer> intList = newListWithDefault(42, 3);
assertEquals(Lists.newArrayList(42, 42, 42), intList);
List<Date> dateList = newListWithDefault(Date.from(Instant.EPOCH), 2);
assertEquals(Lists.newArrayList(DATE_EPOCH, DATE_EPOCH), dateList);
dateList.get(0)
.setTime(DATE_NOW.getTime());
assertEquals(Lists.newArrayList(DATE_NOW, DATE_NOW), dateList);
}
@Test
void whenUsingNewListWithDefault2_thenGetExpectedList() {
List<String> result = newListWithDefault2(() -> "new", 5);
assertEquals(EXPECTED_LIST, result);
List<Integer> intList = newListWithDefault2(() -> 42, 3);
assertEquals(Lists.newArrayList(42, 42, 42), intList);
List<Date> dateList = newListWithDefault2(() -> Date.from(Instant.EPOCH), 2);
assertEquals(Lists.newArrayList(DATE_EPOCH, DATE_EPOCH), dateList);
dateList.get(0)
.setTime(DATE_NOW.getTime());
assertEquals(Lists.newArrayList(DATE_NOW, DATE_EPOCH), dateList);
}
}

View File

@ -17,16 +17,7 @@ import java.util.HashMap;
import java.util.Map;
public class MapToJsonUnitTest {
final TypeAdapter<JsonElement> strictAdapter = new Gson().getAdapter(JsonElement.class);
public boolean isValid(String json) {
try {
strictAdapter.fromJson(json);
} catch (JsonSyntaxException | IOException e) {
return false;
}
return true;
}
String originalJsonData = "{\"CS\":\"Post1\",\"Linux\":\"Post1\",\"Kotlin\":\"Post1\"}";
@Test
public void given_HashMapData_whenUsingJackson_thenConvertToJson() throws JsonProcessingException {
@ -36,7 +27,7 @@ public class MapToJsonUnitTest {
data.put("Kotlin", "Post1");
ObjectMapper objectMapper = new ObjectMapper();
String jacksonData = objectMapper.writeValueAsString(data);
Assertions.assertTrue(isValid(jacksonData));
Assertions.assertEquals(originalJsonData,jacksonData);
}
@Test
@ -49,7 +40,7 @@ public class MapToJsonUnitTest {
Type typeObject = new TypeToken<HashMap>() {
}.getType();
String gsonData = gson.toJson(data, typeObject);
Assertions.assertTrue(isValid(gsonData));
Assertions.assertEquals(originalJsonData,gsonData);
}
@Test
@ -60,6 +51,6 @@ public class MapToJsonUnitTest {
data.put("Kotlin", "Post1");
JSONObject jsonObject = new JSONObject(data);
String orgJsonData = jsonObject.toString();
Assertions.assertTrue(isValid(orgJsonData));
Assertions.assertEquals(originalJsonData,orgJsonData);
}
}

View File

@ -8,7 +8,7 @@ This module contains articles about core Java input and output (IO)
- [Simulate touch Command in Java](https://www.baeldung.com/java-simulate-touch-command)
- [SequenceInputStream Class in Java](https://www.baeldung.com/java-sequenceinputstream)
- [Read a File Into a Map in Java](https://www.baeldung.com/java-read-file-into-map)
- [Read User Input Until a Condition is Met](https://www.baeldung.com/java-read-input-until-condition)
- [Read User Input Until a Condition Is Met](https://www.baeldung.com/java-read-input-until-condition)
- [Java Scanner.skip method with examples](https://www.baeldung.com/java-scanner-skip)
- [Generate the MD5 Checksum for a File in Java](https://www.baeldung.com/java-md5-checksum-file)
- [Getting the Filename From a String Containing an Absolute File Path](https://www.baeldung.com/java-filename-full-path)

View File

@ -10,3 +10,5 @@ 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)
- [Java: Read Multiple Inputs on Same Line](https://www.baeldung.com/java-read-multiple-inputs-same-line)
- [Storing Java Scanner Input in an Array](https://www.baeldung.com/java-store-scanner-input-in-array)
- [How to Take Input as String With Spaces in Java Using Scanner?](https://www.baeldung.com/java-scanner-input-with-spaces)
- [Write Console Output to Text File in Java](https://www.baeldung.com/java-write-console-output-file)

View File

@ -99,9 +99,6 @@
<scope>compile</scope>
</dependency>
</dependencies>
<properties>
<junit-jupiter-version>5.2.0</junit-jupiter-version>
</properties>
<build>
<finalName>core-java-io-apis-2</finalName>
<resources>
@ -111,5 +108,7 @@
</resource>
</resources>
</build>
<properties>
<junit-jupiter-version>5.9.3</junit-jupiter-version>
</properties>
</project>

View File

@ -0,0 +1,58 @@
package com.baeldung.scanner;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.NoSuchElementException;
import java.util.Scanner;
public class ScannerNoSuchElementException {
public static String readFileV1(String pathname) throws IOException {
Path pathFile = Paths.get(pathname);
if (Files.notExists(pathFile)) {
return "";
}
try (Scanner scanner = new Scanner(pathFile)) {
return scanner.nextLine();
}
}
public static String readFileV2(String pathname) throws IOException {
Path pathFile = Paths.get(pathname);
if (Files.notExists(pathFile)) {
return "";
}
try (Scanner scanner = new Scanner(pathFile)) {
return scanner.hasNextLine() ? scanner.nextLine() : "";
}
}
public static String readFileV3(String pathname) throws IOException {
Path pathFile = Paths.get(pathname);
if (Files.notExists(pathFile) || Files.size(pathFile) == 0) {
return "";
}
try (Scanner scanner = new Scanner(pathFile)) {
return scanner.nextLine();
}
}
public static String readFileV4(String pathname) throws IOException {
Path pathFile = Paths.get(pathname);
if (Files.notExists(pathFile)) {
return "";
}
try (Scanner scanner = new Scanner(pathFile)) {
return scanner.nextLine();
} catch (NoSuchElementException exception) {
return "";
}
}
}

View File

@ -0,0 +1,94 @@
package com.baeldung.outputtofile;
import static org.junit.jupiter.api.Assertions.assertLinesMatch;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import com.google.common.collect.Lists;
class DualPrintStream extends PrintStream {
private final PrintStream second;
public DualPrintStream(OutputStream main, PrintStream second) {
super(main);
this.second = second;
}
@Override
public void close() {
super.close();
second.close();
}
@Override
public void flush() {
super.flush();
second.flush();
}
@Override
public void write(byte[] buf, int off, int len) {
super.write(buf, off, len);
second.write(buf, off, len);
}
@Override
public void write(int b) {
super.write(b);
second.write(b);
}
@Override
public void write(byte[] b) throws IOException {
super.write(b);
second.write(b);
}
}
public class ConsoleOutputToFileUnitTest {
// @formatter:off
private final static List<String> OUTPUT_LINES = Lists.newArrayList(
"I came",
"I saw",
"I conquered");
// @formatter:on
@Test
void whenReplacingSystemOutPrintStreamWithFileOutputStream_thenOutputsGoToFile(@TempDir Path tempDir) throws IOException {
PrintStream originalOut = System.out;
Path outputFilePath = tempDir.resolve("file-output.txt");
PrintStream out = new PrintStream(Files.newOutputStream(outputFilePath), true);
System.setOut(out);
OUTPUT_LINES.forEach(line -> System.out.println(line));
assertTrue(outputFilePath.toFile()
.exists(), "The file exists");
assertLinesMatch(OUTPUT_LINES, Files.readAllLines(outputFilePath));
System.setOut(originalOut);
}
@Test
void whenUsingDualPrintStream_thenOutputsGoToConsoleAndFile(@TempDir Path tempDir) throws IOException {
PrintStream originalOut = System.out;
Path outputFilePath = tempDir.resolve("dual-output.txt");
DualPrintStream dualOut = new DualPrintStream(Files.newOutputStream(outputFilePath), System.out);
System.setOut(dualOut);
OUTPUT_LINES.forEach(line -> System.out.println(line));
assertTrue(outputFilePath.toFile()
.exists(), "The file exists");
assertLinesMatch(OUTPUT_LINES, Files.readAllLines(outputFilePath));
System.setOut(originalOut);
}
}

View File

@ -0,0 +1,97 @@
package com.baeldung.scanner;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import org.junit.jupiter.api.Test;
import com.google.common.collect.Lists;
public class InputWithSpacesUnitTest {
@Test
void whenValuesContainSpaces_thenNextBreaksTheValue() {
String input = new StringBuilder().append("Michael Jackson\n")
.append("He was the 'King of Pop'.\n")
.toString();
Scanner sc = new Scanner(input);
String name = sc.next();
String description = sc.next();
assertEquals("Michael", name);
assertEquals("Jackson", description);
}
@Test
void whenOneValuePerLineUsingNextLine_thenGetExpectedResult() {
String input = new StringBuilder().append("Michael Jackson\n")
.append("He was the 'King of Pop'.\n")
.toString();
Scanner sc = new Scanner(input);
String name = sc.nextLine();
String description = sc.nextLine();
assertEquals("Michael Jackson", name);
assertEquals("He was the 'King of Pop'.", description);
}
@Test
void whenOneValuePerLineUsingNewLineAsDelimiter_thenGetExpectedResult() {
String input = new StringBuilder().append("Michael Jackson\n")
.append("He was the 'King of Pop'.\n")
.toString();
Scanner sc = new Scanner(input);
sc.useDelimiter("\\n");
String name = sc.next();
String description = sc.next();
assertEquals("Michael Jackson", name);
assertEquals("He was the 'King of Pop'.", description);
}
@Test
void whenValuesAreSeparatedByCommaUsingSplit_thenGetExpectedResult() {
String input = "Michael Jackson, Whitney Houston, John Lennon\n";
Scanner sc = new Scanner(input);
String[] names = sc.nextLine()
.split(", ");
assertArrayEquals(new String[] { "Michael Jackson", "Whitney Houston", "John Lennon" }, names);
}
@Test
void whenValuesAreSeparatedByCommaSettingDelimiterWithoutNewline_thenGetExpectedResult() {
String input = new StringBuilder().append("Michael Jackson, Whitney Houston, John Lennon\n")
.append("Elvis Presley\n")
.toString();
Scanner sc = new Scanner(input);
sc.useDelimiter(", ");
List<String> names = new ArrayList<>();
while (sc.hasNext()) {
names.add(sc.next());
}
//assertEquals(Lists.newArrayList("Michael Jackson", "Whitney Houston", "John Lennon", "Elvis Presley"), names); <-- Fail
assertEquals(3, names.size());
assertEquals("John Lennon\nElvis Presley\n", names.get(2));
}
@Test
void whenValuesAreSeparatedByCommaSettingDelimiter_thenGetExpectedResult() {
String input = new StringBuilder().append("Michael Jackson, Whitney Houston, John Lennon\n")
.append("Elvis Presley\n")
.toString();
Scanner sc = new Scanner(input);
sc.useDelimiter(", |\\n");
List<String> names = new ArrayList<>();
while (sc.hasNext()) {
names.add(sc.next());
}
assertEquals(Lists.newArrayList("Michael Jackson", "Whitney Houston", "John Lennon", "Elvis Presley"), names);
}
}

View File

@ -0,0 +1,51 @@
package com.baeldung.scanner;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.Scanner;
import org.junit.jupiter.api.Test;
class NextVsNextLineUnitTest {
@Test
void givenInput_whenUsingNextMethod_thenReturnToken() {
String input = "Hello world";
try (Scanner scanner = new Scanner(input)) {
assertEquals("Hello", scanner.next());
assertEquals("world", scanner.next());
}
}
@Test
void givenInput_whenUsingNextMethodWithCustomDelimiter_thenReturnToken() {
String input = "Hello :world";
try (Scanner scanner = new Scanner(input)) {
scanner.useDelimiter(":");
assertEquals("Hello ", scanner.next());
assertEquals("world", scanner.next());
}
}
@Test
void givenInput_whenUsingNextLineMethod_thenReturnEntireLine() {
String input = "Hello world\nWelcome to baeldung.com";
try (Scanner scanner = new Scanner(input)) {
assertEquals("Hello world", scanner.nextLine());
assertEquals("Welcome to baeldung.com", scanner.nextLine());
}
}
@Test
void givenInput_whenUsingNextLineWithCustomDelimiter_thenIgnoreDelimiter() {
String input = "Hello:world\nWelcome:to baeldung.com";
try (Scanner scanner = new Scanner(input)) {
scanner.useDelimiter(":");
assertEquals("Hello:world", scanner.nextLine());
assertEquals("Welcome:to baeldung.com", scanner.nextLine());
}
}
}

View File

@ -0,0 +1,43 @@
package com.baeldung.scanner;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.io.IOException;
import java.util.NoSuchElementException;
import org.junit.jupiter.api.Test;
class ScannerNoSuchElementExceptionUnitTest {
@Test
void givenEmptyFile_whenUsingReadFileV1_thenThrowException() {
Exception exception = assertThrows(NoSuchElementException.class, () -> {
ScannerNoSuchElementException.readFileV1("src/test/resources/emptyFile.txt");
});
assertEquals("No line found", exception.getMessage());
}
@Test
void givenEmptyFile_whenUsingReadFileV2_thenSuccess() throws IOException {
String emptyLine = ScannerNoSuchElementException.readFileV2("src/test/resources/emptyFile.txt");
assertEquals("", emptyLine);
}
@Test
void givenEmptyFile_whenUsingReadFileV3_thenSuccess() throws IOException {
String emptyLine = ScannerNoSuchElementException.readFileV3("src/test/resources/emptyFile.txt");
assertEquals("", emptyLine);
}
@Test
void givenEmptyFile_whenUsingReadFileV4_thenSuccess() throws IOException {
String emptyLine = ScannerNoSuchElementException.readFileV4("src/test/resources/emptyFile.txt");
assertEquals("", emptyLine);
}
}

View File

@ -4,7 +4,7 @@ This module contains articles about core features in the Java language
- [The Java final Keyword Impact on Performance](https://www.baeldung.com/java-final-performance)
- [The package-info.java File](https://www.baeldung.com/java-package-info)
- [What are Compile-time Constants in Java?](https://www.baeldung.com/java-compile-time-constants)
- [What Are Compile-Time Constants in Java?](https://www.baeldung.com/java-compile-time-constants)
- [Java Objects.hash() vs Objects.hashCode()](https://www.baeldung.com/java-objects-hash-vs-objects-hashcode)
- [Referencing a Method in Javadoc Comments](https://www.baeldung.com/java-method-in-javadoc)
- [Tiered Compilation in JVM](https://www.baeldung.com/jvm-tiered-compilation)

View File

@ -16,7 +16,7 @@ class Voucher {
return true;
if (!(o instanceof Voucher))
return false;
Voucher other = (Voucher)o;
Voucher other = (Voucher) o;
boolean valueEquals = (this.value == null && other.value == null)
|| (this.value != null && this.value.equals(other.value));
boolean storeEquals = (this.store == null && other.store == null)

View File

@ -13,15 +13,25 @@ public class MoneyUnitTest {
Money expenses = new Money(55, "USD");
assertTrue(income.equals(expenses));
assertTrue(expenses.equals(income));
}
@Test
public void givenMoneyAndWrongVoucherInstances_whenEquals_thenReturnValuesArentSymmetric() {
Money money = new Money(42, "USD");
WrongVoucher voucher = new WrongVoucher(42, "USD", "Amazon");
assertFalse(voucher.equals(money));
assertTrue(money.equals(voucher));
}
@Test
public void givenMoneyAndVoucherInstances_whenEquals_thenReturnValuesArentSymmetric() {
Money cash = new Money(42, "USD");
WrongVoucher voucher = new WrongVoucher(42, "USD", "Amazon");
Money money = new Money(42, "USD");
Voucher voucher = new Voucher(42, "USD", "Amazon");
assertFalse(voucher.equals(cash));
assertTrue(cash.equals(voucher));
assertFalse(voucher.equals(money));
assertFalse(money.equals(voucher));
}
}

View File

@ -11,6 +11,6 @@ This module contains articles about types in Java
- [Iterating over Enum Values in Java](https://www.baeldung.com/java-enum-iteration)
- [Attaching Values to Java Enum](https://www.baeldung.com/java-enum-values)
- [A Guide to Java Enums](https://www.baeldung.com/a-guide-to-java-enums)
- [Determine if an Object is of Primitive Type](https://www.baeldung.com/java-object-primitive-type)
- [Determine if an Object Is of Primitive Type](https://www.baeldung.com/java-object-primitive-type)
- [Extending Enums in Java](https://www.baeldung.com/java-extending-enums)
- [Java Class File Naming Conventions](https://www.baeldung.com/java-class-file-naming)

View File

@ -13,5 +13,5 @@ This module contains articles about core Java non-blocking input and output (IO)
- [Java Path vs File](https://www.baeldung.com/java-path-vs-file)
- [What Is the Difference Between NIO and NIO.2?](https://www.baeldung.com/java-nio-vs-nio-2)
- [Guide to ByteBuffer](https://www.baeldung.com/java-bytebuffer)
- [Find Files that Match Wildcard Strings in Java](https://www.baeldung.com/java-files-match-wildcard-strings)
- [Find Files That Match Wildcard Strings in Java](https://www.baeldung.com/java-files-match-wildcard-strings)
- [[<-- Prev]](/core-java-modules/core-java-nio)

View File

@ -7,5 +7,5 @@
- [Make Division of Two Integers Result in a Float](https://www.baeldung.com/java-integer-division-float-result)
- [Creating Random Numbers With No Duplicates in Java](https://www.baeldung.com/java-unique-random-numbers)
- [Multiply a BigDecimal by an Integer in Java](https://www.baeldung.com/java-bigdecimal-multiply-integer)
- [Check if an Integer Value is null or Zero in Java](https://www.baeldung.com/java-check-integer-null-or-zero)
- [Check if an Integer Value Is Null or Zero in Java](https://www.baeldung.com/java-check-integer-null-or-zero)
- [Return Absolute Difference of Two Integers in Java](https://www.baeldung.com/java-absolute-difference-of-two-integers)

View File

@ -1,4 +1,4 @@
### Relevant Articles:
- [Java Program to Calculate Pi](https://www.baeldung.com/java-monte-carlo-compute-pi)
- [Java Program to Estimate Pi](https://www.baeldung.com/java-monte-carlo-compute-pi)
- [Convert Integer to Hexadecimal in Java](https://www.baeldung.com/java-convert-int-to-hex)
- More articles: [[<-- prev]](../core-java-numbers-5)

View File

@ -2,8 +2,8 @@
- [Reading the Value of private Fields from a Different Class in Java](https://www.baeldung.com/java-reflection-read-private-field-value)
- [Set Field Value With Reflection](https://www.baeldung.com/java-set-private-field-value)
- [Checking If a Method is Static Using Reflection in Java](https://www.baeldung.com/java-check-method-is-static)
- [Checking if a Java Class is abstract Using Reflection](https://www.baeldung.com/java-reflection-is-class-abstract)
- [Checking if a Method Is Static Using Reflection in Java](https://www.baeldung.com/java-check-method-is-static)
- [Checking if a Java Class Is Abstract Using Reflection](https://www.baeldung.com/java-reflection-is-class-abstract)
- [Invoking a Private Method in Java](https://www.baeldung.com/java-call-private-method)
- [Finding All Classes in a Java Package](https://www.baeldung.com/java-find-all-classes-in-package)
- [Invoke a Static Method Using Java Reflection API](https://www.baeldung.com/java-invoke-static-method-reflection)

View File

@ -12,4 +12,5 @@ This module contains articles about core Java Security
- [Computing an X509 Certificates Thumbprint in Java](https://www.baeldung.com/java-x509-certificate-thumbprint)
- [Error: “trustAnchors parameter must be non-empty”](https://www.baeldung.com/java-trustanchors-parameter-must-be-non-empty)
- [Common Exceptions of Crypto APIs in Java](https://www.baeldung.com/java-crypto-apis-exceptions)
- [Hashing With Argon2 in Java](https://www.baeldung.com/java-argon2-hashing)
- More articles: [[<-- prev]](/core-java-modules/core-java-security-2)

View File

@ -0,0 +1,21 @@
package com.baeldung.readresolvevsreadobject;
import java.io.ObjectStreamException;
import java.io.Serializable;
public class Singleton implements Serializable {
private static final long serialVersionUID = 1L;
private static Singleton INSTANCE = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return INSTANCE;
}
private Object readResolve() throws ObjectStreamException {
return INSTANCE;
}
}

View File

@ -0,0 +1,59 @@
package com.baeldung.readresolvevsreadobject;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class User implements Serializable {
private static final long serialVersionUID = 3659932210257138726L;
private String userName;
private String password;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [userName=" + userName + ", password=" + password + "]";
}
public User() {
}
public User(String userName, String password) {
super();
this.userName = userName;
this.password = password;
}
private void writeObject(ObjectOutputStream oos) throws IOException {
this.password = "xyz" + password;
oos.defaultWriteObject();
}
private void readObject(ObjectInputStream aInputStream)
throws ClassNotFoundException, IOException {
aInputStream.defaultReadObject();
this.password = password.substring(3);
}
private Object readResolve() {
return this;
}
}

View File

@ -0,0 +1,47 @@
package com.baeldung.readresolvevsreadobject;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
public class SingletonUnitTest {
@Test
public void testSingletonObj_withNoReadResolve() throws ClassNotFoundException, IOException {
// Serialization
FileOutputStream fos = new FileOutputStream("singleton.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
Singleton actualSingletonObject = Singleton.getInstance();
oos.writeObject(actualSingletonObject);
// Deserialization
Singleton deserializedSingletonObject = null;
FileInputStream fis = new FileInputStream("singleton.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
deserializedSingletonObject = (Singleton) ois.readObject();
// remove readResolve() from Singleton class and uncomment this to test.
//assertNotEquals(actualSingletonObject.hashCode(), deserializedSingletonObject.hashCode());
}
@Test
public void testSingletonObj_withCustomReadResolve()
throws ClassNotFoundException, IOException {
// Serialization
FileOutputStream fos = new FileOutputStream("singleton.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
Singleton actualSingletonObject = Singleton.getInstance();
oos.writeObject(actualSingletonObject);
// Deserialization
Singleton deserializedSingletonObject = null;
FileInputStream fis = new FileInputStream("singleton.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
deserializedSingletonObject = (Singleton) ois.readObject();
assertEquals(actualSingletonObject.hashCode(), deserializedSingletonObject.hashCode());
}
}

View File

@ -0,0 +1,52 @@
package com.baeldung.readresolvevsreadobject;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
public class UserUnitTest {
@Test
public void testDeserializeObj_withOverriddenReadObject()
throws ClassNotFoundException, IOException {
// Serialization
FileOutputStream fos = new FileOutputStream("user.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
User acutalObject = new User("Sachin", "Kumar");
oos.writeObject(acutalObject);
// Deserialization
User deserializedUser = null;
FileInputStream fis = new FileInputStream("user.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
deserializedUser = (User) ois.readObject();
assertNotEquals(deserializedUser.hashCode(), acutalObject.hashCode());
assertEquals(deserializedUser.getUserName(), "Sachin");
assertEquals(deserializedUser.getPassword(), "Kumar");
}
@Test
public void testDeserializeObj_withDefaultReadObject()
throws ClassNotFoundException, IOException {
// Serialization
FileOutputStream fos = new FileOutputStream("user.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
User acutalObject = new User("Sachin", "Kumar");
oos.writeObject(acutalObject);
// Deserialization
User deserializedUser = null;
FileInputStream fis = new FileInputStream("user.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
deserializedUser = (User) ois.readObject();
assertNotEquals(deserializedUser.hashCode(), acutalObject.hashCode());
assertEquals(deserializedUser.getUserName(), "Sachin");
// remove readObject() from User class and uncomment this to test.
//assertEquals(deserializedUser.getPassword(), "xyzKumar");
}
}

View File

@ -1 +1,3 @@
## Relevant Articles
- [Difference Between parallelStream() and stream().parallel() in Java](https://www.baeldung.com/java-parallelstream-vs-stream-parallel)
- [Working With Empty Stream in Java](https://www.baeldung.com/java-empty-stream)

View File

@ -7,7 +7,7 @@ This module contains articles about string-related algorithms.
- [Generating a Java String of N Repeated Characters](https://www.baeldung.com/java-string-of-repeated-characters)
- [Check if Two Strings are Anagrams in Java](https://www.baeldung.com/java-strings-anagrams)
- [Email Validation in Java](https://www.baeldung.com/java-email-validation-regex)
- [Check if the First Letter of a String is Uppercase](https://www.baeldung.com/java-check-first-letter-uppercase)
- [Check if the First Letter of a String Is Uppercase](https://www.baeldung.com/java-check-first-letter-uppercase)
- [Find the First Non Repeating Character in a String in Java](https://www.baeldung.com/java-find-the-first-non-repeating-character)
- [Find the First Embedded Occurrence of an Integer in a Java String](https://www.baeldung.com/java-string-find-embedded-integer)
- [Find the Most Frequent Characters in a String](https://www.baeldung.com/java-string-find-most-frequent-characters)

View File

@ -0,0 +1,3 @@
## Relevant Articles
- [Object.toString() vs String.valueOf()](https://www.baeldung.com/java-object-tostring-vs-string-valueof)
- [Convert String to Int Using Encapsulation](https://www.baeldung.com/java-encapsulation-convert-string-to-int)

View File

@ -6,7 +6,7 @@
- [Split a String Every n Characters in Java](https://www.baeldung.com/java-string-split-every-n-characters)
- [String equals() Vs contentEquals() in Java](https://www.baeldung.com/java-string-equals-vs-contentequals)
- [Check if a String Ends with a Certain Pattern in Java](https://www.baeldung.com/java-string-ends-pattern)
- [Check if a Character is a Vowel in Java](https://www.baeldung.com/java-check-character-vowel)
- [Check if a Character Is a Vowel in Java](https://www.baeldung.com/java-check-character-vowel)
- [How to Truncate a String in Java](https://www.baeldung.com/java-truncating-strings)
- [Remove Whitespace From a String in Java](https://www.baeldung.com/java-string-remove-whitespace)
- [Named Placeholders in String Formatting](https://www.baeldung.com/java-string-formatting-named-placeholders)

View File

@ -12,5 +12,5 @@ This module contains articles about data structures in Java
- [Guide to AVL Trees in Java](https://www.baeldung.com/java-avl-trees)
- [Graphs in Java](https://www.baeldung.com/java-graphs)
- [Implementing a Ring Buffer in Java](https://www.baeldung.com/java-ring-buffer)
- [How to Implement Min-Max Heap In Java](https://www.baeldung.com/java-min-max-heap)
- [How to Implement Min-Max Heap in Java](https://www.baeldung.com/java-min-max-heap)
- [How to Implement LRU Cache in Java](https://www.baeldung.com/java-lru-cache)

View File

@ -3,3 +3,5 @@
- [How to Configure Conditional Dependencies in Gradle](https://www.baeldung.com/gradle-conditional-dependencies)
- [Working With Multiple Repositories in Gradle](https://www.baeldung.com/java-gradle-multiple-repositories)
- [Different Dependency Version Declarations in Gradle](https://www.baeldung.com/gradle-different-dependency-version-declarations)
- [Generating Javadoc With Gradle](https://www.baeldung.com/java-gradle-javadoc)

View File

@ -0,0 +1,42 @@
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

View File

@ -0,0 +1,25 @@
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
javadoc {
destinationDir = file("${buildDir}/docs/javadoc")
include 'com/baeldung/addition/**'
exclude 'com/baeldung/subtraction/**'
}
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}
test {
useJUnitPlatform()
}

View File

@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

240
gradle-modules/gradle-7/gradle-javadoc/gradlew vendored Executable file
View File

@ -0,0 +1,240 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

View File

@ -0,0 +1,91 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@ -0,0 +1,2 @@
rootProject.name = 'gradle-javadoc'

View File

@ -0,0 +1,17 @@
package com.baeldung.addition;
/**
* This is a sample class that demonstrates Javadoc comments.
*/
public class Sum {
/**
* This method returns the sum of two integers.
*
* @param a the first integer
* @param b the second integer
* @return the sum of a and b
*/
public int add(int a, int b) {
return a + b;
}
}

View File

@ -0,0 +1,17 @@
package com.baeldung.subtraction;
/**
* This is a sample class that demonstrates Javadoc comments.
*/
public class Difference {
/**
* This method returns the difference between the two integers.
*
* @param a the first integer
* @param b the second integer
* @return the difference between a and b
*/
public int subtract(int a, int b) {
return a - b;
}
}

View File

@ -8,4 +8,4 @@ This module contains articles about image processing.
- [Optical Character Recognition with Tesseract](https://www.baeldung.com/java-ocr-tesseract)
- [How Can I Resize an Image Using Java?](https://www.baeldung.com/java-resize-image)
- [Adding Text to an Image in Java](https://www.baeldung.com/java-add-text-to-image)
- [Capturing Image From Webcam In Java](https://www.baeldung.com/java-capture-image-from-webcam)
- [Capturing Image From Webcam in Java](https://www.baeldung.com/java-capture-image-from-webcam)

View File

@ -0,0 +1,45 @@
package com.baeldung.jackson.objectmapper;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.util.TimeZone;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
public class ObjectMapperBuilder {
private boolean enableIndentation;
private boolean preserveOrder;
private DateFormat dateFormat;
public ObjectMapperBuilder enableIndentation() {
this.enableIndentation = true;
return this;
}
public ObjectMapperBuilder dateFormat() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm a z");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone(ZoneId.of("Asia/Kolkata")));
this.dateFormat = simpleDateFormat;
return this;
}
public ObjectMapperBuilder preserveOrder(boolean order) {
this.preserveOrder = order;
return this;
}
public ObjectMapper build() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.INDENT_OUTPUT, this.enableIndentation);
objectMapper.setDateFormat(this.dateFormat);
if (this.preserveOrder) {
objectMapper.enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS);
}
return objectMapper;
}
}

View File

@ -0,0 +1,44 @@
package com.baeldung.jackson.objectmapper;
import java.util.Date;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import com.baeldung.jackson.objectmapper.dto.Car;
import com.baeldung.jackson.objectmapper.dto.Request;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ObjectMapperBuilderUnitTest {
ObjectMapper mapper = new ObjectMapperBuilder()
.enableIndentation()
.dateFormat()
.preserveOrder(true)
.build();
Car givenCar = new Car("White", "Sedan");
String givenCarJsonStr = "{ \"color\" : \"White\", \"type\" : \"Sedan\" }";
@Test
public void whenReadCarJsonStr_thenReturnCarObjectCorrectly() throws JsonProcessingException {
Car actual = mapper.readValue(givenCarJsonStr, Car.class);
Assertions.assertEquals("White", actual.getColor());
Assertions.assertEquals("Sedan", actual.getType());
}
@Test
public void whenWriteRequestObject_thenReturnRequestJsonStrCorrectly() throws JsonProcessingException {
Request request = new Request();
request.setCar(givenCar);
Date date = new Date(1684909857000L);
request.setDatePurchased(date);
String actual = mapper.writeValueAsString(request);
String expected = "{\n" + " \"car\" : {\n" + " \"color\" : \"White\",\n" +
" \"type\" : \"Sedan\"\n" + " },\n" + " \"datePurchased\" : \"2023-05-24 12:00 PM IST\"\n" +
"}";
Assertions.assertEquals(expected, actual);
}
}

View File

@ -5,3 +5,4 @@
- [How to Stop a Zombie Job on Jenkins Without Restarting the Server?](https://www.baeldung.com/ops/stop-zombie-job-on-jenkins-without-restarting-the-server)
- [Running Stages in Parallel With Jenkins Workflow / Pipeline](https://www.baeldung.com/ops/running-stages-in-parallel-jenkins-workflow-pipeline)
- [Skip a Stage in a Jenkins Pipeline](https://www.baeldung.com/ops/jenkins-pipeline-skip-stage)
- [Prevent Jenkins Build From Failing When Execute Shell Step Fails](https://www.baeldung.com/linux/jenkins-build-execute-shell-step-fails)

View File

@ -73,3 +73,5 @@ To configure CI for your project, run the ci-cd sub-generator (`yo jhipster:ci-c
[Setting up Continuous Integration]: https://jhipster.github.io/documentation-archive/v4.0.8/setting-up-ci/
## Relevant Articles:
- [Use Liquibase to Safely Evolve Your Database Schema](https://www.baeldung.com/liquibase-refactor-schema-of-java-app)

View File

@ -0,0 +1,7 @@
## GSON
This module contains articles about Gson
### Relevant Articles:

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>gson-2</artifactId>
<name>gson-2</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>json-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
</dependencies>
<properties>
<gson.version>2.10.1</gson.version>
</properties>
</project>

View File

@ -0,0 +1,15 @@
package com.baeldung.gson.parsingerrors;
public class Person {
public String name;
public String getName() {
return name;
}
public Person(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,55 @@
package com.baeldung.gson.parsingerror;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.lang.reflect.Type;
import java.util.Collection;
import org.junit.jupiter.api.Test;
import com.baeldung.gson.parsingerrors.Person;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
class GsonErrorDemoUnitTest {
@Test
void givenAJsonArray_WhenTellingGsonToExpectAnObject_ThenThrows() {
assertThrows(JsonSyntaxException.class, () -> {
Person person = new Gson().fromJson("[{\"name\":\"John\"},{\"name\":\"James\"}]", Person.class);
});
}
@Test
void givenAJsonArray_WhenParsingIntoAnArray_ThenOK() {
Person[] personArray = new Gson().fromJson("[{\"name\":\"John\"},{\"name\":\"James\"}]", Person[].class);
assertThat(personArray).extracting(Person::getName)
.containsExactly("John", "James");
}
@Test
void givenAJsonArray_WhenParsingIntoACollection_ThenOK() {
Type collectionType = new TypeToken<Collection<Person>>() {
}.getType();
Collection<Person> personCollection = new Gson().fromJson("[{\"name\":\"John\"},{\"name\":\"James\"}]", collectionType);
assertThat(personCollection).extracting(Person::getName)
.containsExactly("John", "James");
}
@Test
void givenAJsonObject_WhenTellingGsonToExpectAnArray_ThenThrows() {
assertThrows(JsonSyntaxException.class, () -> {
Person[] personArray = new Gson().fromJson("{\"name\":\"John\"}", Person[].class);
});
}
@Test
void givenAJsonObject_WhenParsingIntoAnObject_ThenOK() {
Person person = new Gson().fromJson("{\"name\":\"John\"}", Person.class);
assertEquals("John", person.getName());
}
}

View File

@ -9,8 +9,7 @@ This module contains articles about JSON.
- [Hypermedia Serialization With JSON-LD](https://www.baeldung.com/json-linked-data)
- [Generate a Java Class From JSON](https://www.baeldung.com/java-generate-class-from-json)
- [A Guide to FastJson](https://www.baeldung.com/fastjson)
- [Check Whether a String is Valid JSON in Java](https://www.baeldung.com/java-validate-json-string)
- [Check Whether a String Is Valid JSON in Java](https://www.baeldung.com/java-validate-json-string)
- [Getting a Value in JSONObject](https://www.baeldung.com/java-jsonobject-get-value)
- More Articles: [[<-- prev]](/json-modules/json)

View File

@ -18,6 +18,7 @@
<module>json-2</module>
<module>json-path</module>
<module>gson</module>
<module>gson-2</module>
</modules>
<build>

View File

@ -1,3 +1,3 @@
## Parent Spring 5
## Parent Spring 6
This is a parent module for all projects using Spring 5
This is a parent module for all projects using Spring 6

View File

@ -23,8 +23,7 @@ public class UserUtility {
for (Event event : events) {
if (event instanceof UserCreatedEvent) {
UserCreatedEvent e = (UserCreatedEvent) event;
user = new User(UUID.randomUUID()
.toString(), e.getFirstName(), e.getLastName());
user = new User(e.getUserId(), e.getFirstName(), e.getLastName());
}
if (event instanceof UserAddressAddedEvent) {
UserAddressAddedEvent e = (UserAddressAddedEvent) event;

View File

@ -1 +1,2 @@
### Relevant Articles:
- [Introduction to Interface Driven Development (IDD)](https://www.baeldung.com/java-idd)

View File

@ -1,7 +1,7 @@
### Relevant Articles:
- [Getting Database URL From JDBC Connection Object](https://www.baeldung.com/jdbc-get-url-from-connection)
- [JDBC URL Format For Different Databases](https://www.baeldung.com/java-jdbc-url-format)
- [Jdbc URL Format for Different Databases](https://www.baeldung.com/java-jdbc-url-format)
- [How to Check if a Database Table Exists with JDBC](https://www.baeldung.com/jdbc-check-table-exists)
- [Inserting Null Into an Integer Column Using JDBC](https://www.baeldung.com/jdbc-insert-null-into-integer-column)
- [A Guide to Auto-Commit in JDBC](https://www.baeldung.com/java-jdbc-auto-commit)

View File

@ -1,4 +1,4 @@
### Relevant Articles:
- [Building a web app Using Fauna and Spring for Your First web Agency Client](https://www.baeldung.com/faunadb-spring-web-app)
- [Building a Web App Using Fauna and Spring for Your First Web Agency Client](https://www.baeldung.com/faunadb-spring-web-app)
- [Building IoT Applications Using Fauna and Spring](https://www.baeldung.com/fauna-spring-building-iot-applications)

View File

@ -0,0 +1,42 @@
package com.baeldung.associations.biredirectional;
import jakarta.persistence.*;
import java.util.List;
@Entity
public class Course {
@Id
private Long id;
private String name;
@ManyToMany
@JoinTable(name = "course_student",
joinColumns = @JoinColumn(name = "course_id"),
inverseJoinColumns = @JoinColumn(name = "student_id"))
private List<Student> students;
public List<Student> getStudents() {
return students;
}
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 void setStudents(List<Student> students) {
this.students = students;
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.associations.biredirectional;
import java.util.List;
import jakarta.persistence.*;
@Entity
public class Department {
@Id
private Long id;
@OneToMany(mappedBy = "department")
private List<Employee> employees;
public List<Employee> getEmployees() {
return employees;
}
}

View File

@ -0,0 +1,42 @@
package com.baeldung.associations.biredirectional;
import jakarta.persistence.*;
@Entity
public class Employee {
@Id
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "department_id")
private Department department;
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 Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
}

View File

@ -0,0 +1,43 @@
package com.baeldung.associations.biredirectional;
import java.util.List;
import jakarta.persistence.*;
@Entity
public class Student {
@Id
private Long id;
private String name;
@ManyToMany(mappedBy = "students")
private List<Course> courses;
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 List<Course> getCourses() {
return courses;
}
public void setCourses(List<Course> courses) {
this.courses = courses;
}
}

View File

@ -0,0 +1,40 @@
package com.baeldung.associations.unidirectional;
import jakarta.persistence.*;
import java.util.Set;
@Entity
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "authors")
private Set<Book> books;
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 Set<Book> getBooks() {
return books;
}
public void setBooks(Set<Book> books) {
this.books = books;
}
}

View File

@ -0,0 +1,44 @@
package com.baeldung.associations.unidirectional;
import jakarta.persistence.*;
import java.util.Set;
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "book_author",
joinColumns = @JoinColumn(name = "book_id"),
inverseJoinColumns = @JoinColumn(name = "author_id"))
private Set<Author> authors;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Set<Author> getAuthors() {
return authors;
}
public void setAuthors(Set<Author> authors) {
this.authors = authors;
}
}

View File

@ -0,0 +1,33 @@
package com.baeldung.associations.unidirectional;
import jakarta.persistence.*;
import java.util.List;
@Entity
public class Department {
@Id
private Long id;
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "department_id")
private List<Employee> employees;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
}

View File

@ -0,0 +1,42 @@
package com.baeldung.associations.unidirectional;
import jakarta.persistence.*;
@Entity
public class Employee {
@Id
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parking_spot_id")
private ParkingSpot parkingSpot;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "department_id")
private Department department;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public ParkingSpot getParkingSpot() {
return parkingSpot;
}
public void setParkingSpot(ParkingSpot parkingSpot) {
this.parkingSpot = parkingSpot;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
}

View File

@ -0,0 +1,11 @@
package com.baeldung.associations.unidirectional;
import jakarta.persistence.*;
@Entity
public class ParkingSpot {
@Id
private Long id;
}

View File

@ -11,6 +11,6 @@ This module contains articles about the Java Persistence API (JPA) in Java.
- [A Guide to MultipleBagFetchException in Hibernate](https://www.baeldung.com/java-hibernate-multiplebagfetchexception)
- [How to Convert a Hibernate Proxy to a Real Entity Object](https://www.baeldung.com/hibernate-proxy-to-real-entity-object)
- [Returning an Auto-Generated Id with JPA](https://www.baeldung.com/jpa-get-auto-generated-id)
- [How to Return Multiple Entities In JPA Query](https://www.baeldung.com/jpa-return-multiple-entities)
- [How to Return Multiple Entities in JPA Query](https://www.baeldung.com/jpa-return-multiple-entities)
- [Defining Unique Constraints in JPA](https://www.baeldung.com/jpa-unique-constraints)
- [Connecting to a Specific Schema in JDBC](https://www.baeldung.com/jdbc-connect-to-schema)

View File

@ -97,7 +97,7 @@
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="jakarta.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="jakarta.persistence.jdbc.url" value="jdbc:h2:mem:test" />
<property name="jakarta.persistence.jdbc.url" value="jdbc:h2:mem:test;MODE=LEGACY" />
<property name="jakarta.persistence.jdbc.user" value="sa" />
<property name="jakarta.persistence.jdbc.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />

View File

@ -31,7 +31,13 @@ import dev.morphia.query.FindOptions;
import dev.morphia.query.Query;
import dev.morphia.query.experimental.updates.UpdateOperators;
public class MorphiaIntegrationTest {
/**
* 1. Firstly you have to install a docker service where you can run a docker container. For Windows you can use Docker desktop (where you can have pretty
* much the seme functionality as on linux)
* 2. Secondly run a mongodb instance: with this command: docker run -d --rm -p 27017:27017 --name mongo2 mongo:5
* 3. Thirdly run this test
*/
public class MorphiaManualTest {
private static Datastore datastore;
private static ObjectId id = new ObjectId();

View File

@ -0,0 +1,11 @@
package com.baeldung.countrows;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AccountStatsApplication {
public static void main(String[] args) {
SpringApplication.run(AccountStatsApplication.class, args);
}
}

View File

@ -0,0 +1,68 @@
package com.baeldung.countrows.entity;
import javax.persistence.*;
import java.security.PrivateKey;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.Date;
@Entity
@Table(name = "ACCOUNTS")
public class Account {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "accounts_seq")
@SequenceGenerator(name = "accounts_seq", sequenceName = "accounts_seq", allocationSize = 1)
@Column(name = "user_id")
private int userId;
private String username;
private String password;
private String email;
private Timestamp createdOn;
private Timestamp lastLogin;
@OneToOne
@JoinColumn(name = "permissions_id")
private Permission permission;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setEmail(String email) {
this.email = email;
}
public Timestamp getCreatedOn() {
return createdOn;
}
public void setCreatedOn(Timestamp createdOn) {
this.createdOn = createdOn;
}
public void setLastLogin(Timestamp lastLogin) {
this.lastLogin = lastLogin;
}
public Permission getPermission() {
return permission;
}
public void setPermission(Permission permission) {
this.permission = permission;
}
@Override
public String toString() {
return "Account{" + "userId=" + userId + ", username='" + username + '\'' + ", password='" + password + '\'' + ", email='" + email + '\'' + ", createdOn=" + createdOn + ", lastLogin=" + lastLogin + ", permission=" + permission + '}';
}
}

View File

@ -0,0 +1,24 @@
package com.baeldung.countrows.entity;
import javax.persistence.*;
@Entity
@Table(name = "PERMISSIONS")
public class Permission {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "permissions_id_sq")
@SequenceGenerator(name = "permissions_id_sq", sequenceName = "permissions_id_sq", allocationSize = 1)
private int id;
private String type;
public void setType(String type) {
this.type = type;
}
@Override
public String toString() {
return "Permission{" + "id=" + id + ", type='" + type + '\'' + '}';
}
}

View File

@ -0,0 +1,23 @@
package com.baeldung.countrows.repository;
import com.baeldung.countrows.entity.Account;
import com.baeldung.countrows.entity.Permission;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
@Repository
public interface AccountRepository extends JpaRepository<Account, Integer> {
long countByUsername(String username);
long countByPermission(Permission permission);
long countByPermissionAndCreatedOnGreaterThan(Permission permission, Timestamp ts);
}

View File

@ -0,0 +1,12 @@
package com.baeldung.countrows.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.baeldung.countrows.entity.Permission;
@Repository
public interface PermissionRepository extends JpaRepository<Permission, Integer> {
Permission findByType(String type);
}

View File

@ -0,0 +1,116 @@
package com.baeldung.countrows.service;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.criteria.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baeldung.countrows.entity.Account;
import com.baeldung.countrows.entity.Permission;
import com.baeldung.countrows.repository.AccountRepository;
import com.baeldung.countrows.repository.PermissionRepository;
@Service
public class AccountStatsLogic {
@Autowired
private AccountRepository accountRepository;
@PersistenceContext
private EntityManager entityManager;
@Autowired
private PermissionRepository permissionRepository;
public long getAccountCount() {
return accountRepository.count();
}
public long getAccountCountByUsername(String username) {
return accountRepository.countByUsername(username);
}
public long getAccountCountByPermission(Permission permission) {
return accountRepository.countByPermission(permission);
}
public long getAccountCountByPermissionAndCreatedOn(Permission permission, Date date) throws ParseException {
return accountRepository.countByPermissionAndCreatedOnGreaterThan(permission, new Timestamp(date.getTime()));
}
public long getAccountsUsingCQ() throws ParseException {
// creating criteria builder and query
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> criteriaQuery = builder.createQuery(Long.class);
Root<Account> accountRoot = criteriaQuery.from(Account.class);
// select query
criteriaQuery.select(builder.count(accountRoot));
// execute and get the result
return entityManager.createQuery(criteriaQuery)
.getSingleResult();
}
public long getAccountsByPermissionUsingCQ(Permission permission) throws ParseException {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> criteriaQuery = builder.createQuery(Long.class);
Root<Account> accountRoot = criteriaQuery.from(Account.class);
List<Predicate> predicateList = new ArrayList<>(); // list of predicates that will go in where clause
predicateList.add(builder.equal(accountRoot.get("permission"), permission));
criteriaQuery.select(builder.count(accountRoot))
.where(builder.and(predicateList.toArray(new Predicate[0])));
return entityManager.createQuery(criteriaQuery)
.getSingleResult();
}
public long getAccountsByPermissionAndCreateOnUsingCQ(Permission permission, Date date) throws ParseException {
// creating criteria builder and query
CriteriaBuilder builder = entityManager.getCriteriaBuilder(); // create builder
CriteriaQuery<Long> criteriaQuery = builder.createQuery(Long.class);// query instance
Root<Account> accountRoot = criteriaQuery.from(Account.class); // root instance
// list of predicates that will go in where clause
List<Predicate> predicateList = new ArrayList<>();
predicateList.add(builder.equal(accountRoot.get("permission"), permission));
predicateList.add(builder.greaterThan(accountRoot.get("createdOn"), new Timestamp(date.getTime())));
// select query
criteriaQuery.select(builder.count(accountRoot))
.where(builder.and(predicateList.toArray(new Predicate[0])));
// execute and get the result
return entityManager.createQuery(criteriaQuery)
.getSingleResult();
}
public long getAccountsUsingJPQL() throws ParseException {
Query query = entityManager.createQuery("SELECT COUNT(*) FROM Account a");
return (long) query.getSingleResult();
}
public long getAccountsByPermissionUsingJPQL(Permission permission) throws ParseException {
Query query = entityManager.createQuery("SELECT COUNT(*) FROM Account a WHERE a.permission = ?1");
query.setParameter(1, permission);
return (long) query.getSingleResult();
}
public long getAccountsByPermissionAndCreatedOnUsingJPQL(Permission permission, Date date) throws ParseException {
Query query = entityManager.createQuery("SELECT COUNT(*) FROM Account a WHERE a.permission = ?1 and a.createdOn > ?2");
query.setParameter(1, permission);
query.setParameter(2, new Timestamp(date.getTime()));
return (long) query.getSingleResult();
}
}

View File

@ -0,0 +1,141 @@
package com.baeldung.boot.countrows.accountstatslogic;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.Date;
import java.util.UUID;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import com.baeldung.countrows.AccountStatsApplication;
import com.baeldung.countrows.entity.Account;
import com.baeldung.countrows.entity.Permission;
import com.baeldung.countrows.repository.AccountRepository;
import com.baeldung.countrows.repository.PermissionRepository;
import com.baeldung.countrows.service.AccountStatsLogic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest(classes = AccountStatsApplication.class)
class AccountStatsUnitTest {
@Autowired
private PermissionRepository permissionRepository;
@Autowired
private AccountRepository accountRepository;
@Autowired
private AccountStatsLogic accountStatsLogic;
@AfterEach
public void afterEach() {
accountRepository.deleteAll();
permissionRepository.deleteAll();
}
@Test
public void givenAccountInTable_whenPerformCount_returnsAppropriateCount() {
savePermissions();
saveAccount();
assertThat(accountStatsLogic.getAccountCount()).isEqualTo(1);
}
@Test
public void givenAccountInTable_whenPerformCountByUsernameOrPermission_returnsAppropriateCount() {
savePermissions();
Account account = saveAccount();
assertThat(accountStatsLogic.getAccountCountByUsername(account.getUsername())).isEqualTo(1);
assertThat(accountStatsLogic.getAccountCountByPermission(account.getPermission())).isEqualTo(1);
}
@Test
public void givenAccountInTable_whenPerformCountByPermissionAndCreatedOn_returnsAppropriateCount() throws ParseException {
savePermissions();
Account account = saveAccount();
long count = accountStatsLogic.getAccountCountByPermissionAndCreatedOn(account.getPermission(), account.getCreatedOn());
assertThat(count).isEqualTo(1);
}
@Test
public void givenAccountInTable_whenPerformCountUsingCQ_returnsAppropriateCount() throws ParseException {
savePermissions();
saveAccount();
long count = accountStatsLogic.getAccountsUsingCQ();
assertThat(count).isEqualTo(1);
}
@Test
public void givenAccountInTable_whenPerformCountByPermissionUsingCQ_returnsAppropriateCount() throws ParseException {
savePermissions();
Account account = saveAccount();
long count = accountStatsLogic.getAccountsByPermissionUsingCQ(account.getPermission());
assertThat(count).isEqualTo(1);
}
@Test
public void givenAccountInTable_whenPerformCountByPermissionAndCreatedOnUsingCQ_returnsAppropriateCount() throws ParseException {
savePermissions();
Account account = saveAccount();
long count = accountStatsLogic.getAccountsByPermissionAndCreateOnUsingCQ(account.getPermission(), account.getCreatedOn());
assertThat(count).isEqualTo(1);
}
@Test
public void givenAccountInTable_whenPerformCountUsingJPQL_returnsAppropriateCount() throws ParseException {
savePermissions();
saveAccount();
long count = accountStatsLogic.getAccountsUsingJPQL();
assertThat(count).isEqualTo(1);
}
@Test
public void givenAccountInTable_whenPerformCountByPermissionUsingJPQL_returnsAppropriateCount() throws ParseException {
savePermissions();
Account account = saveAccount();
long count = accountStatsLogic.getAccountsByPermissionUsingJPQL(account.getPermission());
assertThat(count).isEqualTo(1);
}
@Test
public void givenAccountInTable_whenPerformCountByPermissionAndCreatedOnUsingJPQL_returnsAppropriateCount() throws ParseException {
savePermissions();
Account account = saveAccount();
long count = accountStatsLogic.getAccountsByPermissionAndCreatedOnUsingJPQL(account.getPermission(), account.getCreatedOn());
assertThat(count).isEqualTo(1);
}
private Account saveAccount() {
return accountRepository.save(getAccount());
}
private void savePermissions() {
Permission editor = new Permission();
editor.setType("editor");
permissionRepository.save(editor);
Permission admin = new Permission();
admin.setType("admin");
permissionRepository.save(admin);
}
private Account getAccount() {
Permission permission = permissionRepository.findByType("admin");
Account account = new Account();
String seed = UUID.randomUUID()
.toString();
account.setUsername("username_" + seed);
account.setEmail("username_" + seed + "@gmail.com");
account.setPermission(permission);
account.setPassword("password_q1234");
account.setCreatedOn(Timestamp.from(Instant.now()));
account.setLastLogin(Timestamp.from(Instant.now()));
return account;
}
}

View File

@ -8,6 +8,7 @@ This module contains articles about querying data using Spring Data JPA.
- [Joining Tables With Spring Data JPA Specifications](https://www.baeldung.com/spring-jpa-joining-tables)
- [NonUniqueResultException in Spring Data JPA](https://www.baeldung.com/spring-jpa-non-unique-result-exception)
- [Spring Data Repositories Collections vs. Stream](https://www.baeldung.com/spring-data-collections-vs-stream)
- [Converting List to Page Using Spring Data JPA](https://www.baeldung.com/spring-data-jpa-convert-list-page)
- More articles: [[<-- prev]](../spring-data-jpa-query-2)
### Eclipse Config

View File

@ -5,4 +5,5 @@ This module contains articles about Spring Data JPA.
### Relevant Articles:
- [New CRUD Repository Interfaces in Spring Data 3](https://www.baeldung.com/spring-data-3-crud-repository-interfaces)
- [How to Persist a List of String in JPA?](https://www.baeldung.com/java-jpa-persist-string-list)
- [Hibernate Natural IDs in Spring Boot](https://www.baeldung.com/spring-boot-hibernate-natural-ids)
- More articles: [[<-- prev]](../spring-data-jpa-repo-2)

View File

@ -0,0 +1,49 @@
package com.baeldung.flush;
import java.util.Properties;
import javax.sql.DataSource;
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;
@Configuration
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.flush");
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;
}
}

View File

@ -0,0 +1,52 @@
package com.baeldung.flush;
import java.util.Objects;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class Customer {
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Customer customer = (Customer) o;
return age == customer.age && name.equals(customer.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
private String name;
private int age;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}

View File

@ -0,0 +1,47 @@
package com.baeldung.flush;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class CustomerAddress {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String street;
private String city;
private long customer_id;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Long getId() {
return id;
}
public long getCustomer_id() {
return customer_id;
}
public void setCustomer_id(long customer_id) {
this.customer_id = customer_id;
}
}

View File

@ -0,0 +1,199 @@
package com.baeldung.spring.data.jpa.flush;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import com.baeldung.flush.AppConfig;
import com.baeldung.flush.Customer;
import com.baeldung.flush.CustomerAddress;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.EntityTransaction;
import jakarta.persistence.FlushModeType;
import jakarta.persistence.PersistenceUnit;
import jakarta.persistence.TypedQuery;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = { AppConfig.class })
public class FlushIntegrationTest {
private static final Customer EXPECTED_CUSTOMER = aCustomer();
@PersistenceUnit
private EntityManagerFactory entityManagerFactory;
private EntityManager entityManager;
@BeforeEach
void setup() {
entityManager = entityManagerFactory.createEntityManager();
}
@Test
void givenANewCustomer_whenPersistAndNoFlush_thenDatabaseNotSynchronizedWithPersistentContextUsingCommitFlushMode() {
entityManager.setFlushMode(FlushModeType.COMMIT);
EntityTransaction transaction = getTransaction();
Customer customer = saveCustomerInPersistentContext("Alice", 30);
Customer customerInContext = entityManager.find(Customer.class, customer.getId());
assertDataInPersitentContext(customerInContext);
TypedQuery<Customer> retrievedCustomer = entityManager.createQuery("SELECT c FROM Customer c WHERE c.name = 'Alice'", Customer.class);
List<Customer> resultList = retrievedCustomer.getResultList();
assertThat(resultList).isEmpty();
transaction.rollback();
}
@Test
void givenANewCustomer_whenPersistAndFlush_thenDatabaseSynchronizedWithPersistentContextUsingCommitFlushMode() {
entityManager.setFlushMode(FlushModeType.COMMIT);
EntityTransaction transaction = getTransaction();
Customer customer = saveCustomerInPersistentContext("Alice", 30);
entityManager.flush();
Long generatedCustomerID = customer.getId();
Customer customerInContext = entityManager.find(Customer.class, generatedCustomerID);
assertDataInPersitentContext(customerInContext);
TypedQuery<Customer> retrievedCustomer = entityManager.createQuery("SELECT c FROM Customer c WHERE c.name = 'Alice'", Customer.class);
Customer result = retrievedCustomer.getSingleResult();
assertThat(result).isEqualTo(EXPECTED_CUSTOMER);
transaction.rollback();
}
@Test
public void givenANewCustomer_whenPersistAndFlush_thenCustomerIdGeneratedToBeAddedInAddress() {
entityManager.setFlushMode(FlushModeType.COMMIT);
EntityTransaction transaction = getTransaction();
saveCustomerInPersistentContext("John", 25);
entityManager.flush();
Customer retrievedCustomer = entityManager.createQuery("SELECT c FROM Customer c WHERE c.name = 'John'", Customer.class)
.getSingleResult();
Long customerId = retrievedCustomer.getId();
CustomerAddress address = new CustomerAddress();
address.setCustomer_id(customerId);
entityManager.persist(address);
entityManager.flush();
CustomerAddress customerAddress = entityManager.createQuery("SELECT a FROM CustomerAddress a WHERE a.customer_id = :customerID", CustomerAddress.class)
.setParameter("customerID", customerId)
.getSingleResult();
assertThat(customerAddress).isNotNull();
transaction.rollback();
}
@Test
void givenANewCustomer_whenPersistAndNoFlush_thenDBIsSynchronizedWithThePersistentContextWithAutoFlushMode() {
entityManager.setFlushMode(FlushModeType.AUTO);
EntityTransaction transaction = getTransaction();
Customer customer = saveCustomerInPersistentContext("Alice", 30);
Customer customerInContext = entityManager.find(Customer.class, customer.getId());
assertDataInPersitentContext(customerInContext);
TypedQuery<Customer> retrievedCustomer = entityManager.createQuery("SELECT c FROM Customer c WHERE c.name = 'Alice'", Customer.class);
Customer result = retrievedCustomer.getSingleResult();
assertThat(result).isEqualTo(EXPECTED_CUSTOMER);
transaction.rollback();
}
@Test
public void givenFlushModeAutoAndNewCustomer_whenPersistAndNoFlush_thenCustomerIdGeneratedToBeAddedInAddress() {
entityManager.setFlushMode(FlushModeType.AUTO);
EntityTransaction transaction = getTransaction();
saveCustomerInPersistentContext("John", 25);
Customer singleResult = entityManager.createQuery("SELECT c FROM Customer c WHERE c.name = 'John'", Customer.class)
.getSingleResult();
Long customerId = singleResult.getId();
CustomerAddress address = new CustomerAddress();
address.setCustomer_id(customerId);
entityManager.persist(address);
CustomerAddress customerAddress = entityManager.createQuery("SELECT a FROM CustomerAddress a WHERE a.customer_id = :customerID", CustomerAddress.class)
.setParameter("customerID", customerId)
.getSingleResult();
assertThat(customerAddress).isNotNull();
transaction.rollback();
}
@Test
public void givenFlushModeAutoAndNewCustomer_whenPersistAndFlush_thenCustomerIdGeneratedToBeAddedInAddress() {
entityManager.setFlushMode(FlushModeType.AUTO);
EntityTransaction transaction = getTransaction();
saveCustomerInPersistentContext("John", 25);
Customer singleResult = entityManager.createQuery("SELECT c FROM Customer c WHERE c.name = 'John'", Customer.class)
.getSingleResult();
Long customerId = singleResult.getId();
CustomerAddress address = new CustomerAddress();
address.setCustomer_id(customerId);
entityManager.persist(address);
entityManager.flush();
CustomerAddress customerAddress = entityManager.createQuery("SELECT a FROM CustomerAddress a WHERE a.customer_id = :customerID", CustomerAddress.class)
.setParameter("customerID", customerId)
.getSingleResult();
assertThat(customerAddress).isNotNull();
transaction.rollback();
}
private static void assertDataInPersitentContext(Customer customerInContext) {
assertThat(customerInContext).isNotNull();
assertThat(customerInContext.getName()).isEqualTo("Alice");
}
private Customer saveCustomerInPersistentContext(String name, int age) {
Customer customer = new Customer();
customer.setName(name);
customer.setAge(age);
entityManager.persist(customer);
return customer;
}
@AfterEach
public void cleanup() {
entityManager.clear();
}
private static Customer aCustomer() {
Customer customer = new Customer();
customer.setName("Alice");
customer.setAge(30);
return customer;
}
private EntityTransaction getTransaction() {
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
return transaction;
}
}

View File

@ -10,6 +10,7 @@ This module contains articles about repositories in Spring Data JPA
- [Spring Data Composable Repositories](https://www.baeldung.com/spring-data-composable-repositories)
- [Spring Data JPA Repository Populators](https://www.baeldung.com/spring-data-jpa-repository-populators)
- [Calling Stored Procedures from Spring Data JPA Repositories](https://www.baeldung.com/spring-data-jpa-stored-procedures)
- [TRUNCATE TABLE in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-truncate-table)
- More articles: [[--> next]](../spring-data-jpa-repo-2)
### Eclipse Config

22
pom.xml
View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--suppress PyInterpreter -->
<project xmlns="http://maven.apache.org/POM/4.0.0"
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">
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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
@ -418,7 +418,12 @@
<module>spring-cloud-modules</module>
<!-- <module>spring-cloud-cli</module> --> <!-- Not a maven project -->
<!-- <module>spring-roo</module> --> <!-- JAVA-17327 -->
<module>spring-exceptions</module>
<module>spring-integration</module>
<module>spring-jenkins-pipeline</module>
<!-- <module>spring-roo</module> --> <!-- Not supported JAVA-17327 -->
<module>spring-security-modules</module>
<module>spring-soap</module>
@ -586,7 +591,12 @@
<module>spring-cloud-modules</module>
<!-- <module>spring-cloud-cli</module> --> <!-- Not a maven project -->
<!-- <module>spring-roo</module> --> <!-- JAVA-17327 -->
<module>spring-exceptions</module>
<module>spring-integration</module>
<module>spring-jenkins-pipeline</module>
<!-- <module>spring-roo</module> --> <!-- Not supported JAVA-17327 -->
<module>spring-security-modules</module>
<module>spring-soap</module>
@ -831,7 +841,7 @@
<module>disruptor</module>
<module>dozer</module>
<module>dubbo</module>
<!-- <module>feign</module> --> <!-- JAVA-19475 -->
<!-- <module>feign</module> --> <!-- JAVA-20337 -->
<module>google-cloud</module>
<module>graphql-modules</module>
<module>grpc</module>
@ -1093,7 +1103,7 @@
<module>dozer</module>
<module>dubbo</module>
<!-- <module>feign</module> -->
<!-- <module>feign</module> --> <!-- JAVA-20337 -->
<module>google-cloud</module>
<module>graphql-modules</module>
<module>grpc</module>

View File

@ -45,7 +45,7 @@
<argument>-Xmx300m</argument>
<argument>-XX:+UseParallelGC</argument>
<argument>-classpath</argument>
<classpath />
<classpath/>
<argument>com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed</argument>
</arguments>
</configuration>

View File

@ -11,40 +11,40 @@
<artifactId>sentry-servlet</artifactId>
<name>sentry-servlet</name>
<packaging>war</packaging>
<properties>
<sentry.version>6.11.0</sentry.version>
<cargo.version>1.10.4</cargo.version>
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>io.sentry</groupId>
<artifactId>sentry-servlet</artifactId>
<version>${sentry.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<properties>
<sentry.version>6.11.0</sentry.version>
<cargo.version>1.10.4</cargo.version>
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>io.sentry</groupId>
<artifactId>sentry-servlet</artifactId>
<version>${sentry.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven3-plugin</artifactId>
<version>${cargo.version}</version>
<configuration>
<container>
<containerId>tomcat9x</containerId>
<type>embedded</type>
</container>
</configuration>
</plugin>
</plugins>
<plugins>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven3-plugin</artifactId>
<version>${cargo.version}</version>
<configuration>
<container>
<containerId>tomcat9x</containerId>
<type>embedded</type>
</container>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,2 @@
## Relevant Articles
- [Spring Boot Actuator Without Spring Boot](https://www.baeldung.com/spring-boot-actuator-without-spring-boot)

View File

@ -80,7 +80,7 @@
<module>spring-boot-data-2</module>
<module>spring-boot-validation</module>
<module>spring-boot-data-3</module>
<module>spring-caching</module>
<module>spring-caching</module>
<module>spring-caching-2</module>
<module>spring-boot-redis</module>
<module>spring-boot-cassandre</module>

View File

@ -66,12 +66,12 @@
</execution>
</executions>
</plugin> -->
</plugins>
</pluginManagement>
</build>
</plugins>
</pluginManagement>
</build>
<profiles>
<!-- The native profile is already defined by the parent POM. -->
<profiles>
<!-- The native profile is already defined by the parent POM. -->
<!-- To use this plugin, we need GraalVM (located under $GRAALVM_HOME) and -->
<!-- native-builder (located in the $PATH) -->
<profile>

Some files were not shown because too many files have changed in this diff Show More