Merge remote-tracking branch 'eugenp/master'

This commit is contained in:
DOHA 2018-10-25 14:37:45 +03:00
commit b3d4ed532b
487 changed files with 3563 additions and 1228 deletions

View File

@ -26,3 +26,13 @@ To do the full build, do: `mvn install -Pdefault -Dgib.enabled=false`
Building a single module
====================
To build a specific module run the command: `mvn clean install -Dgib.enabled=false` in the module directory
Running a Spring Boot module
====================
To run a Spring Boot module run the command: `mvn spring-boot:run -Dgib.enabled=false` in the module directory

View File

@ -31,3 +31,6 @@
- [Round Up to the Nearest Hundred](https://www.baeldung.com/java-round-up-nearest-hundred)
- [Merge Sort in Java](https://www.baeldung.com/java-merge-sort)
- [Calculate Percentage in Java](https://www.baeldung.com/java-calculate-percentage)
- [Quicksort Algorithm Implementation in Java](https://www.baeldung.com/java-quicksort)
- [Insertion Sort in Java](https://www.baeldung.com/java-insertion-sort)
- [Converting Between Byte Arrays and Hexadecimal Strings in Java](https://www.baeldung.com/java-byte-arrays-hex-strings)

View File

@ -7,7 +7,7 @@ public class BubbleSort {
void bubbleSort(Integer[] arr) {
int n = arr.length;
IntStream.range(0, n - 1)
.flatMap(i -> IntStream.range(i + 1, n - i))
.flatMap(i -> IntStream.range(1, n - i))
.forEach(j -> {
if (arr[j - 1] > arr[j]) {
int temp = arr[j];

View File

@ -1,8 +1,8 @@
package com.baeldung.algorithms.bubblesort;
import static org.junit.Assert.*;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import org.junit.Test;
import org.junit.jupiter.api.Test;
public class BubbleSortUnitTest {

3
apache-geode/README.md Normal file
View File

@ -0,0 +1,3 @@
### Relevant Articles:
- [A Quick Guide to Apache Geode](https://www.baeldung.com/apache-geode)

8
apache-pulsar/.gitignore vendored Executable file
View File

@ -0,0 +1,8 @@
.classpath
.project
.settings
target
.idea
*.iml
.gradle/
build/

21
apache-pulsar/pom.xml Normal file
View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung.pulsar</groupId>
<artifactId>pulsar-java</artifactId>
<version>0.0.1</version>
<dependencies>
<dependency>
<groupId>org.apache.pulsar</groupId>
<artifactId>pulsar-client</artifactId>
<version>2.1.1-incubating</version>
<scope>compile</scope>
</dependency>
</dependencies>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
</project>

View File

@ -0,0 +1,48 @@
package com.baeldung;
import java.io.IOException;
import org.apache.pulsar.client.api.Consumer;
import org.apache.pulsar.client.api.Message;
import org.apache.pulsar.client.api.PulsarClient;
import org.apache.pulsar.client.api.SubscriptionType;
public class ConsumerTest {
private static final String SERVICE_URL = "pulsar://localhost:6650";
private static final String TOPIC_NAME = "test-topic";
private static final String SUBSCRIPTION_NAME = "test-subscription";
public static void main(String[] args) throws IOException {
// Create a Pulsar client instance. A single instance can be shared across many
// producers and consumer within the same application
PulsarClient client = PulsarClient.builder()
.serviceUrl(SERVICE_URL)
.build();
//Configure consumer specific settings.
Consumer<byte[]> consumer = client.newConsumer()
.topic(TOPIC_NAME)
// Allow multiple consumers to attach to the same subscription
// and get messages dispatched as a queue
.subscriptionType(SubscriptionType.Shared)
.subscriptionName(SUBSCRIPTION_NAME)
.subscribe();
// Once the consumer is created, it can be used for the entire application lifecycle
System.out.println("Created consumer for the topic "+ TOPIC_NAME);
do {
// Wait until a message is available
Message<byte[]> msg = consumer.receive();
// Extract the message as a printable string and then log
String content = new String(msg.getData());
System.out.println("Received message '"+content+"' with ID "+msg.getMessageId());
// Acknowledge processing of the message so that it can be deleted
consumer.acknowledge(msg);
} while (true);
}
}

View File

@ -0,0 +1,58 @@
package com.baeldung;
import org.apache.pulsar.client.api.CompressionType;
import org.apache.pulsar.client.api.Message;
import org.apache.pulsar.client.api.MessageBuilder;
import org.apache.pulsar.client.api.MessageId;
import org.apache.pulsar.client.api.Producer;
import org.apache.pulsar.client.api.PulsarClient;
import org.apache.pulsar.client.api.PulsarClientException;
import java.io.IOException;
import java.util.stream.IntStream;
public class ProducerTest {
private static final String SERVICE_URL = "pulsar://localhost:6650";
private static final String TOPIC_NAME = "test-topic";
public static void main(String[] args) throws IOException {
// Create a Pulsar client instance. A single instance can be shared across many
// producers and consumer within the same application
PulsarClient client = PulsarClient.builder()
.serviceUrl(SERVICE_URL)
.build();
// Configure producer specific settings
Producer<byte[]> producer = client.newProducer()
// Set the topic
.topic(TOPIC_NAME)
// Enable compression
.compressionType(CompressionType.LZ4)
.create();
// Once the producer is created, it can be used for the entire application life-cycle
System.out.println("Created producer for the topic "+TOPIC_NAME);
// Send 5 test messages
IntStream.range(1, 5).forEach(i -> {
String content = String.format("hi-pulsar-%d", i);
// Build a message object
Message<byte[]> msg = MessageBuilder.create()
.setContent(content.getBytes())
.build();
// Send each message and log message content and ID when successfully received
try {
MessageId msgId = producer.send(msg);
System.out.println("Published message '"+content+"' with the ID "+msgId);
} catch (PulsarClientException e) {
System.out.println(e.getMessage());
}
});
client.close();
}
}

View File

@ -0,0 +1,59 @@
package com.baeldung.subscriptions;
import org.apache.pulsar.client.api.ConsumerBuilder;
import org.apache.pulsar.client.api.Message;
import org.apache.pulsar.client.api.MessageBuilder;
import org.apache.pulsar.client.api.Producer;
import org.apache.pulsar.client.api.PulsarClient;
import org.apache.pulsar.client.api.PulsarClientException;
import org.apache.pulsar.client.api.SubscriptionType;
import java.util.stream.IntStream;
public class ExclusiveSubscriptionTest {
private static final String SERVICE_URL = "pulsar://localhost:6650";
private static final String TOPIC_NAME = "test-topic";
private static final String SUBSCRIPTION_NAME = "test-subscription";
private static final SubscriptionType SUBSCRIPTION_TYPE = SubscriptionType.Exclusive;
public static void main(String[] args) throws PulsarClientException {
PulsarClient client = PulsarClient.builder()
.serviceUrl(SERVICE_URL)
.build();
Producer<byte[]> producer = client.newProducer()
.topic(TOPIC_NAME)
.create();
ConsumerBuilder<byte[]> consumer1 = client.newConsumer()
.topic(TOPIC_NAME)
.subscriptionName(SUBSCRIPTION_NAME)
.subscriptionType(SUBSCRIPTION_TYPE);
ConsumerBuilder<byte[]> consumer2 = client.newConsumer()
.topic(TOPIC_NAME)
.subscriptionName(SUBSCRIPTION_NAME)
.subscriptionType(SUBSCRIPTION_TYPE);
IntStream.range(0, 999).forEach(i -> {
Message<byte[]> msg = MessageBuilder.create()
.setContent(String.format("message-%d", i).getBytes())
.build();
try {
producer.send(msg);
} catch (PulsarClientException e) {
System.out.println(e.getMessage());
}
});
// Consumer 1 can subscribe to the topic
consumer1.subscribe();
// Consumer 2 cannot due to the exclusive subscription held by consumer 1
consumer2.subscribeAsync()
.handle((consumer, exception) -> {
System.out.println(exception.getMessage());
return null;
});
}
}

View File

@ -0,0 +1,76 @@
package com.baeldung.subscriptions;
import org.apache.pulsar.client.api.Consumer;
import org.apache.pulsar.client.api.ConsumerBuilder;
import org.apache.pulsar.client.api.Message;
import org.apache.pulsar.client.api.MessageBuilder;
import org.apache.pulsar.client.api.Producer;
import org.apache.pulsar.client.api.PulsarClient;
import org.apache.pulsar.client.api.PulsarClientException;
import org.apache.pulsar.client.api.SubscriptionType;
import java.util.stream.IntStream;
public class FailoverSubscriptionTest {
private static final String SERVICE_URL = "pulsar://localhost:6650";
private static final String TOPIC_NAME = "failover-subscription-test-topic";
private static final String SUBSCRIPTION_NAME = "test-subscription";
private static final SubscriptionType SUBSCRIPTION_TYPE = SubscriptionType.Failover;
private static final int NUM_MSGS = 10;
public static void main(String[] args) throws PulsarClientException {
PulsarClient client = PulsarClient.builder()
.serviceUrl(SERVICE_URL)
.build();
Producer<byte[]> producer = client.newProducer()
.topic(TOPIC_NAME)
.create();
ConsumerBuilder<byte[]> consumerBuilder = client.newConsumer()
.topic(TOPIC_NAME)
.subscriptionName(SUBSCRIPTION_NAME)
.subscriptionType(SUBSCRIPTION_TYPE);
Consumer<byte[]> mainConsumer = consumerBuilder
.consumerName("consumer-a")
.messageListener((consumer, msg) -> {
System.out.println("Message received by main consumer");
try {
consumer.acknowledge(msg);
} catch (PulsarClientException e) {
System.out.println(e.getMessage());
}
})
.subscribe();
Consumer<byte[]> failoverConsumer = consumerBuilder
.consumerName("consumer-b")
.messageListener((consumer, msg) -> {
System.out.println("Message received by failover consumer");
try {
consumer.acknowledge(msg);
} catch (PulsarClientException e) {
System.out.println(e.getMessage());
}
})
.subscribe();
IntStream.range(0, NUM_MSGS).forEach(i -> {
Message<byte[]> msg = MessageBuilder.create()
.setContent(String.format("message-%d", i).getBytes())
.build();
try {
producer.send(msg);
Thread.sleep(100);
if (i > 5) mainConsumer.close();
} catch (InterruptedException | PulsarClientException e) {
System.out.println(e.getMessage());
}
});
}
}

View File

@ -4,37 +4,23 @@
### Relevant Articles:
- [Immutable ArrayList in Java](http://www.baeldung.com/java-immutable-list)
- [Converting between an Array and a List in Java](http://www.baeldung.com/convert-array-to-list-and-list-to-array)
- [Converting between an Array and a Set in Java](http://www.baeldung.com/convert-array-to-set-and-set-to-array)
- [Converting between a List and a Set in Java](http://www.baeldung.com/convert-list-to-set-and-set-to-list)
- [Convert a Map to an Array, List or Set in Java](http://www.baeldung.com/convert-map-values-to-array-list-set)
- [Guide to the Java ArrayList](http://www.baeldung.com/java-arraylist)
- [Random List Element](http://www.baeldung.com/java-random-list-element)
- [Java - Combine Multiple Collections](http://www.baeldung.com/java-combine-multiple-collections)
- [Guide to WeakHashMap in Java](http://www.baeldung.com/java-weakhashmap)
- [Guide to the Guava BiMap](http://www.baeldung.com/guava-bimap)
- [The Java HashMap Under the Hood](http://www.baeldung.com/java-hashmap)
- [A Guide to LinkedHashMap in Java](http://www.baeldung.com/java-linked-hashmap)
- [A Guide to TreeMap in Java](http://www.baeldung.com/java-treemap)
- [Removing all nulls from a List in Java](http://www.baeldung.com/java-remove-nulls-from-list)
- [Removing all duplicates from a List in Java](http://www.baeldung.com/java-remove-duplicates-from-list)
- [Flattening Nested Collections in Java](http://www.baeldung.com/java-flatten-nested-collections)
- [HashSet and TreeSet Comparison](http://www.baeldung.com/java-hashset-vs-treeset)
- [Iterate over a Map in Java](http://www.baeldung.com/java-iterate-map)
- [Collect a Java Stream to an Immutable Collection](http://www.baeldung.com/java-stream-immutable-collection)
- [Converting a List to String in Java](http://www.baeldung.com/java-list-to-string)
- [Introduction to the Java ArrayDeque](http://www.baeldung.com/java-array-deque)
- [A Guide to HashSet in Java](http://www.baeldung.com/java-hashset)
- [A Guide to TreeSet in Java](http://www.baeldung.com/java-tree-set)
- [Java TreeMap vs HashMap](http://www.baeldung.com/java-treemap-vs-hashmap)
- [How to TDD a List Implementation in Java](http://www.baeldung.com/java-test-driven-list)
- [How to Store Duplicate Keys in a Map in Java?](http://www.baeldung.com/java-map-duplicate-keys)
- [Getting the Size of an Iterable in Java](http://www.baeldung.com/java-iterable-size)
- [Iterating Backward Through a List](http://www.baeldung.com/java-list-iterate-backwards)
- [How to Filter a Collection in Java](http://www.baeldung.com/java-collection-filtering)
- [Add Multiple Items to an Java ArrayList](http://www.baeldung.com/java-add-items-array-list)
- [Remove the First Element from a List](http://www.baeldung.com/java-remove-first-element-from-list)
- [How to Convert List to Map in Java](http://www.baeldung.com/java-list-to-map)
- [Initializing HashSet at the Time of Construction](http://www.baeldung.com/java-initialize-hashset)
- [Removing the First Element of an Array](https://www.baeldung.com/java-array-remove-first-element)
- [Fail-Safe Iterator vs Fail-Fast Iterator](http://www.baeldung.com/java-fail-safe-vs-fail-fast-iterator)
@ -47,12 +33,9 @@
- [Remove All Occurrences of a Specific Value from a List](https://www.baeldung.com/java-remove-value-from-list)
- [Thread Safe LIFO Data Structure Implementations](https://www.baeldung.com/java-lifo-thread-safe)
- [Collections.emptyList() vs. New List Instance](https://www.baeldung.com/java-collections-emptylist-new-list)
- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap)
- [Differences Between Collection.clear() and Collection.removeAll()](https://www.baeldung.com/java-collection-clear-vs-removeall)
- [Performance of contains() in a HashSet vs ArrayList](https://www.baeldung.com/java-hashset-arraylist-contains-performance)
- [Get the Key for a Value from a Java Map](https://www.baeldung.com/java-map-key-from-value)
- [Time Complexity of Java Collections](https://www.baeldung.com/java-collections-complexity)
- [Sort a HashMap in Java](https://www.baeldung.com/java-hashmap-sort)
- [Finding the Highest Value in a Java Map](https://www.baeldung.com/java-find-map-max)
- [Operating on and Removing an Item from Stream](https://www.baeldung.com/java-use-remove-item-stream)
- [An Introduction to Synchronized Java Collections](https://www.baeldung.com/java-synchronized-collections)
- [Guide to EnumSet](https://www.baeldung.com/java-enumset)

View File

@ -14,22 +14,11 @@
</parent>
<dependencies>
<dependency>
<groupId>net.sourceforge.collections</groupId>
<artifactId>collections-generic</artifactId>
<version>${collections-generic.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>${commons-collections4.version}</version>
</dependency>
<dependency>
<groupId>com.jayway.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>${avaitility.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
@ -67,12 +56,6 @@
<artifactId>commons-exec</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>one.util</groupId>
<artifactId>streamex</artifactId>
<version>0.6.5</version>
</dependency>
</dependencies>
<properties>

View File

@ -31,4 +31,5 @@
- [Create a Symbolic Link with Java](http://www.baeldung.com/java-symlink)
- [Quick Use of FilenameFilter](http://www.baeldung.com/java-filename-filter)
- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap)
- [ Read a File into an ArrayList](https://www.baeldung.com/java-file-to-arraylist)
- [Read a File into an ArrayList](https://www.baeldung.com/java-file-to-arraylist)
- [Guide to Java OutputStream](https://www.baeldung.com/java-outputstream)

View File

@ -154,6 +154,12 @@
<artifactId>async-http-client</artifactId>
<version>${async-http-client.version}</version>
</dependency>
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>${opencsv.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@ -247,7 +253,7 @@
<protonpack.version>1.13</protonpack.version>
<streamex.version>0.6.5</streamex.version>
<vavr.version>0.9.0</vavr.version>
<opencsv.version>4.1</opencsv.version>
<!-- testing -->
<assertj.version>3.6.1</assertj.version>
<avaitility.version>1.7.0</avaitility.version>

View File

@ -0,0 +1,106 @@
package com.baeldung.csv;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import org.junit.Assert;
import org.junit.Test;
import com.opencsv.CSVReader;
public class ReadCSVInArrayUnitTest {
public static final String COMMA_DELIMITER = ",";
public static final String CSV_FILE = "src/test/resources/book.csv";
public static final List<List<String>> EXPECTED_ARRAY = Collections.unmodifiableList(new ArrayList<List<String>>() {
{
add(new ArrayList<String>() {
{
add("Mary Kom");
add("Unbreakable");
}
});
add(new ArrayList<String>() {
{
add("Kapil Isapuari");
add("Farishta");
}
});
}
});
@Test
public void givenCSVFile_whenBufferedReader_thenContentsAsExpected() throws IOException {
List<List<String>> records = new ArrayList<List<String>>();
try (BufferedReader br = new BufferedReader(new FileReader(CSV_FILE))) {
String line = "";
while ((line = br.readLine()) != null) {
String[] values = line.split(COMMA_DELIMITER);
records.add(Arrays.asList(values));
}
} catch (Exception e) {
e.printStackTrace();
}
for (int i = 0; i < EXPECTED_ARRAY.size(); i++) {
Assert.assertArrayEquals(EXPECTED_ARRAY.get(i)
.toArray(),
records.get(i)
.toArray());
}
}
@Test
public void givenCSVFile_whenScanner_thenContentsAsExpected() throws IOException {
List<List<String>> records = new ArrayList<List<String>>();
try (Scanner scanner = new Scanner(new File(CSV_FILE));) {
while (scanner.hasNextLine()) {
records.add(getRecordFromLine(scanner.nextLine()));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
for (int i = 0; i < EXPECTED_ARRAY.size(); i++) {
Assert.assertArrayEquals(EXPECTED_ARRAY.get(i)
.toArray(),
records.get(i)
.toArray());
}
}
private List<String> getRecordFromLine(String line) {
List<String> values = new ArrayList<String>();
try (Scanner rowScanner = new Scanner(line)) {
rowScanner.useDelimiter(COMMA_DELIMITER);
while (rowScanner.hasNext()) {
values.add(rowScanner.next());
}
}
return values;
}
@Test
public void givenCSVFile_whenOpencsv_thenContentsAsExpected() throws IOException {
List<List<String>> records = new ArrayList<List<String>>();
try (CSVReader csvReader = new CSVReader(new FileReader(CSV_FILE));) {
String[] values = null;
while ((values = csvReader.readNext()) != null) {
records.add(Arrays.asList(values));
}
} catch (Exception e) {
e.printStackTrace();
}
for (int i = 0; i < EXPECTED_ARRAY.size(); i++) {
Assert.assertArrayEquals(EXPECTED_ARRAY.get(i)
.toArray(),
records.get(i)
.toArray());
}
}
}

View File

@ -0,0 +1,2 @@
Mary Kom,Unbreakable
Kapil Isapuari,Farishta
1 Mary Kom Unbreakable
2 Kapil Isapuari Farishta

View File

@ -157,3 +157,4 @@
- [Hashing a Password in Java](https://www.baeldung.com/java-password-hashing)
- [Java Switch Statement](https://www.baeldung.com/java-switch)
- [The Modulo Operator in Java](https://www.baeldung.com/modulo-java)
- [Ternary Operator In Java](https://www.baeldung.com/java-ternary-operator)

View File

@ -0,0 +1,41 @@
package com.baeldung.string;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
public class DoubleToString {
public static String truncateByCast(double d) {
return String.valueOf((int) d);
}
public static String roundWithStringFormat(double d) {
return String.format("%.0f", d);
}
public static String truncateWithNumberFormat(double d) {
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(0);
nf.setRoundingMode(RoundingMode.FLOOR);
return nf.format(d);
}
public static String roundWithNumberFormat(double d) {
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(0);
return nf.format(d);
}
public static String truncateWithDecimalFormat(double d) {
DecimalFormat df = new DecimalFormat("#,###");
df.setRoundingMode(RoundingMode.FLOOR);
return df.format(d);
}
public static String roundWithDecimalFormat(double d) {
DecimalFormat df = new DecimalFormat("#,###");
return df.format(d);
}
}

View File

@ -0,0 +1,59 @@
package com.baeldung;
import org.junit.Test;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import java.util.logging.Logger;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class SimpleDateFormatUnitTest {
private static final Logger logger = Logger.getLogger(SimpleDateFormatUnitTest.class.getName());
@Test
public void givenSpecificDate_whenFormatted_thenCheckFormatCorrect() throws Exception {
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
assertEquals("24-05-1977", formatter.format(new Date(233345223232L)));
}
@Test
public void givenSpecificDate_whenFormattedUsingDateFormat_thenCheckFormatCorrect() throws Exception {
DateFormat formatter = DateFormat.getDateInstance(DateFormat.SHORT);
assertEquals("5/24/77", formatter.format(new Date(233345223232L)));
}
@Test
public void givenStringDate_whenParsed_thenCheckDateCorrect() throws Exception{
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
Date myDate = new Date(233276400000L);
Date parsedDate = formatter.parse("24-05-1977");
assertEquals(myDate.getTime(), parsedDate.getTime());
}
@Test
public void givenFranceLocale_whenFormatted_thenCheckFormatCorrect() throws Exception{
SimpleDateFormat franceDateFormatter = new SimpleDateFormat("EEEEE dd-MMMMMMM-yyyy", Locale.FRANCE);
Date myWednesday = new Date(1539341312904L);
assertTrue(franceDateFormatter.format(myWednesday).startsWith("vendredi"));
}
@Test
public void given2TimeZones_whenFormatted_thenCheckTimeDifference() throws Exception {
Date now = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEEE dd-MMM-yy HH:mm:ssZ");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Europe/London"));
logger.info(simpleDateFormat.format(now));
//change the date format
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("America/New_York"));
logger.info(simpleDateFormat.format(now));
}
}

View File

@ -0,0 +1,45 @@
package com.baeldung.string;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
public class DoubleToStringUnitTest {
private static final double DOUBLE_VALUE = 3.56;
private static final String TRUNCATED_DOUBLE = "3";
private static final String ROUNDED_UP_DOUBLE = "4";
@Test
public void truncateByCastTest() {
assertThat(DoubleToString.truncateByCast(DOUBLE_VALUE)).isEqualTo(TRUNCATED_DOUBLE);
}
@Test
public void roundingWithStringFormatTest() {
assertThat(DoubleToString.roundWithStringFormat(DOUBLE_VALUE)).isEqualTo(ROUNDED_UP_DOUBLE);
}
@Test
public void truncateWithNumberFormatTest() {
assertThat(DoubleToString.truncateWithNumberFormat(DOUBLE_VALUE)).isEqualTo(TRUNCATED_DOUBLE);
}
@Test
public void roundWithNumberFormatTest() {
assertThat(DoubleToString.roundWithNumberFormat(DOUBLE_VALUE)).isEqualTo(ROUNDED_UP_DOUBLE);
}
@Test
public void truncateWithDecimalFormatTest() {
assertThat(DoubleToString.truncateWithDecimalFormat(DOUBLE_VALUE)).isEqualTo(TRUNCATED_DOUBLE);
}
@Test
public void roundWithDecimalFormatTest() {
assertThat(DoubleToString.roundWithDecimalFormat(DOUBLE_VALUE)).isEqualTo(ROUNDED_UP_DOUBLE);
}
}

View File

@ -39,3 +39,4 @@
- [Introduction to Kovenant Library for Kotlin](https://www.baeldung.com/kotlin-kovenant)
- [Converting Kotlin Data Class from JSON using GSON](https://www.baeldung.com/kotlin-json-convert-data-class)
- [Concatenate Strings in Kotlin](https://www.baeldung.com/kotlin-concatenate-strings)
- [Kotlin return, break, continue Keywords](https://www.baeldung.com/kotlin-return-break-continue)

View File

@ -17,3 +17,4 @@
- [Mapping A Hibernate Query to a Custom Class](https://www.baeldung.com/hibernate-query-to-custom-class)
- [@JoinColumn Annotation Explained](https://www.baeldung.com/jpa-join-column)
- [Hibernate 5 Naming Strategy Configuration](https://www.baeldung.com/hibernate-naming-strategy)
- [Proxy in Hibernate load() Method](https://www.baeldung.com/hibernate-proxy-load-method)

View File

@ -44,6 +44,11 @@
<artifactId>mariaDB4j</artifactId>
<version>${mariaDB4j.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-testing</artifactId>
<version>5.2.2.Final</version>
</dependency>
</dependencies>
<build>
@ -57,7 +62,7 @@
</build>
<properties>
<hibernate.version>5.3.2.Final</hibernate.version>
<hibernate.version>5.3.6.Final</hibernate.version>
<mysql.version>6.0.6</mysql.version>
<mariaDB4j.version>2.2.3</mariaDB4j.version>
<h2database.version>1.4.196</h2database.version>

View File

@ -5,6 +5,8 @@ import java.io.IOException;
import java.net.URL;
import java.util.Properties;
import com.baeldung.hibernate.customtypes.LocalDateStringType;
import com.baeldung.hibernate.customtypes.OfficeEmployee;
import com.baeldung.hibernate.entities.DeptEmployee;
import com.baeldung.hibernate.optimisticlocking.OptimisticLockingCourse;
import com.baeldung.hibernate.optimisticlocking.OptimisticLockingStudent;
@ -18,8 +20,10 @@ import com.baeldung.hibernate.pojo.inheritance.*;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataBuilder;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import com.baeldung.hibernate.pojo.Course;
@ -66,6 +70,7 @@ public class HibernateUtil {
private static SessionFactory makeSessionFactory(ServiceRegistry serviceRegistry) {
MetadataSources metadataSources = new MetadataSources(serviceRegistry);
metadataSources.addPackage("com.baeldung.hibernate.pojo");
metadataSources.addAnnotatedClass(Employee.class);
metadataSources.addAnnotatedClass(Phone.class);
@ -102,8 +107,12 @@ public class HibernateUtil {
metadataSources.addAnnotatedClass(com.baeldung.hibernate.entities.Department.class);
metadataSources.addAnnotatedClass(OptimisticLockingCourse.class);
metadataSources.addAnnotatedClass(OptimisticLockingStudent.class);
metadataSources.addAnnotatedClass(OfficeEmployee.class);
Metadata metadata = metadataSources.getMetadataBuilder()
.applyBasicType(LocalDateStringType.INSTANCE)
.build();
Metadata metadata = metadataSources.buildMetadata();
return metadata.getSessionFactoryBuilder()
.build();

View File

@ -0,0 +1,69 @@
package com.baeldung.hibernate.customtypes;
import java.util.Objects;
public class Address {
private String addressLine1;
private String addressLine2;
private String city;
private String country;
private int zipCode;
public String getAddressLine1() {
return addressLine1;
}
public String getAddressLine2() {
return addressLine2;
}
public String getCity() {
return city;
}
public String getCountry() {
return country;
}
public int getZipCode() {
return zipCode;
}
public void setAddressLine1(String addressLine1) {
this.addressLine1 = addressLine1;
}
public void setAddressLine2(String addressLine2) {
this.addressLine2 = addressLine2;
}
public void setCity(String city) {
this.city = city;
}
public void setCountry(String country) {
this.country = country;
}
public void setZipCode(int zipCode) {
this.zipCode = zipCode;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Address address = (Address) o;
return zipCode == address.zipCode &&
Objects.equals(addressLine1, address.addressLine1) &&
Objects.equals(addressLine2, address.addressLine2) &&
Objects.equals(city, address.city) &&
Objects.equals(country, address.country);
}
@Override
public int hashCode() {
return Objects.hash(addressLine1, addressLine2, city, country, zipCode);
}
}

View File

@ -0,0 +1,169 @@
package com.baeldung.hibernate.customtypes;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.IntegerType;
import org.hibernate.type.StringType;
import org.hibernate.type.Type;
import org.hibernate.usertype.CompositeUserType;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Objects;
public class AddressType implements CompositeUserType {
@Override
public String[] getPropertyNames() {
return new String[]{"addressLine1", "addressLine2",
"city", "country", "zipcode"};
}
@Override
public Type[] getPropertyTypes() {
return new Type[]{StringType.INSTANCE, StringType.INSTANCE,
StringType.INSTANCE, StringType.INSTANCE, IntegerType.INSTANCE};
}
@Override
public Object getPropertyValue(Object component, int property) throws HibernateException {
Address empAdd = (Address) component;
switch (property) {
case 0:
return empAdd.getAddressLine1();
case 1:
return empAdd.getAddressLine2();
case 2:
return empAdd.getCity();
case 3:
return empAdd.getCountry();
case 4:
return Integer.valueOf(empAdd.getZipCode());
}
throw new IllegalArgumentException(property +
" is an invalid property index for class type " +
component.getClass().getName());
}
@Override
public void setPropertyValue(Object component, int property, Object value) throws HibernateException {
Address empAdd = (Address) component;
switch (property) {
case 0:
empAdd.setAddressLine1((String) value);
case 1:
empAdd.setAddressLine2((String) value);
case 2:
empAdd.setCity((String) value);
case 3:
empAdd.setCountry((String) value);
case 4:
empAdd.setZipCode((Integer) value);
}
throw new IllegalArgumentException(property +
" is an invalid property index for class type " +
component.getClass().getName());
}
@Override
public Class returnedClass() {
return Address.class;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
if (x == y)
return true;
if (Objects.isNull(x) || Objects.isNull(y))
return false;
return x.equals(y);
}
@Override
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException {
Address empAdd = new Address();
empAdd.setAddressLine1(rs.getString(names[0]));
if (rs.wasNull())
return null;
empAdd.setAddressLine2(rs.getString(names[1]));
empAdd.setCity(rs.getString(names[2]));
empAdd.setCountry(rs.getString(names[3]));
empAdd.setZipCode(rs.getInt(names[4]));
return empAdd;
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException {
if (Objects.isNull(value))
st.setNull(index, Types.VARCHAR);
else {
Address empAdd = (Address) value;
st.setString(index, empAdd.getAddressLine1());
st.setString(index + 1, empAdd.getAddressLine2());
st.setString(index + 2, empAdd.getCity());
st.setString(index + 3, empAdd.getCountry());
st.setInt(index + 4, empAdd.getZipCode());
}
}
@Override
public Object deepCopy(Object value) throws HibernateException {
if (Objects.isNull(value))
return null;
Address oldEmpAdd = (Address) value;
Address newEmpAdd = new Address();
newEmpAdd.setAddressLine1(oldEmpAdd.getAddressLine1());
newEmpAdd.setAddressLine2(oldEmpAdd.getAddressLine2());
newEmpAdd.setCity(oldEmpAdd.getCity());
newEmpAdd.setCountry(oldEmpAdd.getCountry());
newEmpAdd.setZipCode(oldEmpAdd.getZipCode());
return newEmpAdd;
}
@Override
public boolean isMutable() {
return true;
}
@Override
public Serializable disassemble(Object value, SharedSessionContractImplementor session) throws HibernateException {
return (Serializable) deepCopy(value);
}
@Override
public Object assemble(Serializable cached, SharedSessionContractImplementor session, Object owner) throws HibernateException {
return deepCopy(cached);
}
@Override
public Object replace(Object original, Object target, SharedSessionContractImplementor session, Object owner) throws HibernateException {
return original;
}
}

View File

@ -0,0 +1,51 @@
package com.baeldung.hibernate.customtypes;
import org.hibernate.type.LocalDateType;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.AbstractTypeDescriptor;
import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan;
import org.hibernate.type.descriptor.java.MutabilityPlan;
import java.time.LocalDate;
public class LocalDateStringJavaDescriptor extends AbstractTypeDescriptor<LocalDate> {
public static final LocalDateStringJavaDescriptor INSTANCE = new LocalDateStringJavaDescriptor();
public LocalDateStringJavaDescriptor() {
super(LocalDate.class, ImmutableMutabilityPlan.INSTANCE);
}
@Override
public String toString(LocalDate value) {
return LocalDateType.FORMATTER.format(value);
}
@Override
public LocalDate fromString(String string) {
return LocalDate.from(LocalDateType.FORMATTER.parse(string));
}
@Override
public <X> X unwrap(LocalDate value, Class<X> type, WrapperOptions options) {
if (value == null)
return null;
if (String.class.isAssignableFrom(type))
return (X) LocalDateType.FORMATTER.format(value);
throw unknownUnwrap(type);
}
@Override
public <X> LocalDate wrap(X value, WrapperOptions options) {
if (value == null)
return null;
if(String.class.isInstance(value))
return LocalDate.from(LocalDateType.FORMATTER.parse((CharSequence) value));
throw unknownWrap(value.getClass());
}
}

View File

@ -0,0 +1,34 @@
package com.baeldung.hibernate.customtypes;
import org.hibernate.dialect.Dialect;
import org.hibernate.type.AbstractSingleColumnStandardBasicType;
import org.hibernate.type.DiscriminatorType;
import org.hibernate.type.descriptor.java.LocalDateJavaDescriptor;
import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor;
import java.time.LocalDate;
public class LocalDateStringType extends AbstractSingleColumnStandardBasicType<LocalDate> implements DiscriminatorType<LocalDate> {
public static final LocalDateStringType INSTANCE = new LocalDateStringType();
public LocalDateStringType() {
super(VarcharTypeDescriptor.INSTANCE, LocalDateStringJavaDescriptor.INSTANCE);
}
@Override
public String getName() {
return "LocalDateString";
}
@Override
public LocalDate stringToObject(String xml) throws Exception {
return fromString(xml);
}
@Override
public String objectToSQLString(LocalDate value, Dialect dialect) throws Exception {
return '\'' + toString(value) + '\'';
}
}

View File

@ -0,0 +1,88 @@
package com.baeldung.hibernate.customtypes;
import com.baeldung.hibernate.pojo.Phone;
import org.hibernate.annotations.Columns;
import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import java.time.LocalDate;
@TypeDef(name = "PhoneNumber",
typeClass = PhoneNumberType.class,
defaultForType = PhoneNumber.class)
@Entity
@Table(name = "OfficeEmployee")
public class OfficeEmployee {
@Id
@GeneratedValue
private long id;
@Column
@Type(type = "LocalDateString")
private LocalDate dateOfJoining;
@Columns(columns = {@Column(name = "country_code"),
@Column(name = "city_code"),
@Column(name = "number")})
private PhoneNumber employeeNumber;
@Columns(columns = {@Column(name = "address_line_1"),
@Column(name = "address_line_2"),
@Column(name = "city"), @Column(name = "country"),
@Column(name = "zip_code")})
@Type(type = "com.baeldung.hibernate.customtypes.AddressType")
private Address empAddress;
@Type(type = "com.baeldung.hibernate.customtypes.SalaryType",
parameters = {@Parameter(name = "currency", value = "USD")})
@Columns(columns = {@Column(name = "amount"),
@Column(name = "currency")})
private Salary salary;
public Salary getSalary() {
return salary;
}
public void setSalary(Salary salary) {
this.salary = salary;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public LocalDate getDateOfJoining() {
return dateOfJoining;
}
public void setDateOfJoining(LocalDate dateOfJoining) {
this.dateOfJoining = dateOfJoining;
}
public PhoneNumber getEmployeeNumber() {
return employeeNumber;
}
public void setEmployeeNumber(PhoneNumber employeeNumber) {
this.employeeNumber = employeeNumber;
}
public Address getEmpAddress() {
return empAddress;
}
public void setEmpAddress(Address empAddress) {
this.empAddress = empAddress;
}
}

View File

@ -0,0 +1,43 @@
package com.baeldung.hibernate.customtypes;
import java.util.Objects;
public final class PhoneNumber {
private final int countryCode;
private final int cityCode;
private final int number;
public PhoneNumber(int countryCode, int cityCode, int number) {
this.countryCode = countryCode;
this.cityCode = cityCode;
this.number = number;
}
public int getCountryCode() {
return countryCode;
}
public int getCityCode() {
return cityCode;
}
public int getNumber() {
return number;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PhoneNumber that = (PhoneNumber) o;
return countryCode == that.countryCode &&
cityCode == that.cityCode &&
number == that.number;
}
@Override
public int hashCode() {
return Objects.hash(countryCode, cityCode, number);
}
}

View File

@ -0,0 +1,98 @@
package com.baeldung.hibernate.customtypes;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.UserType;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Objects;
public class PhoneNumberType implements UserType {
@Override
public int[] sqlTypes() {
return new int[]{Types.INTEGER, Types.INTEGER, Types.INTEGER};
}
@Override
public Class returnedClass() {
return PhoneNumber.class;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
if (x == y)
return true;
if (Objects.isNull(x) || Objects.isNull(y))
return false;
return x.equals(y);
}
@Override
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException {
int countryCode = rs.getInt(names[0]);
if (rs.wasNull())
return null;
int cityCode = rs.getInt(names[1]);
int number = rs.getInt(names[2]);
PhoneNumber employeeNumber = new PhoneNumber(countryCode, cityCode, number);
return employeeNumber;
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException {
if (Objects.isNull(value)) {
st.setNull(index, Types.INTEGER);
} else {
PhoneNumber employeeNumber = (PhoneNumber) value;
st.setInt(index,employeeNumber.getCountryCode());
st.setInt(index+1,employeeNumber.getCityCode());
st.setInt(index+2,employeeNumber.getNumber());
}
}
@Override
public Object deepCopy(Object value) throws HibernateException {
if (Objects.isNull(value))
return null;
PhoneNumber empNumber = (PhoneNumber) value;
PhoneNumber newEmpNumber = new PhoneNumber(empNumber.getCountryCode(),empNumber.getCityCode(),empNumber.getNumber());
return newEmpNumber;
}
@Override
public boolean isMutable() {
return false;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
}

View File

@ -0,0 +1,39 @@
package com.baeldung.hibernate.customtypes;
import java.util.Objects;
public class Salary {
private Long amount;
private String currency;
public Long getAmount() {
return amount;
}
public void setAmount(Long amount) {
this.amount = amount;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Salary salary = (Salary) o;
return Objects.equals(amount, salary.amount) &&
Objects.equals(currency, salary.currency);
}
@Override
public int hashCode() {
return Objects.hash(amount, currency);
}
}

View File

@ -0,0 +1,15 @@
package com.baeldung.hibernate.customtypes;
public class SalaryCurrencyConvertor {
public static Long convert(Long amount, String oldCurr, String newCurr){
if (newCurr.equalsIgnoreCase(oldCurr))
return amount;
return convertTo();
}
private static Long convertTo() {
return 10L;
}
}

View File

@ -0,0 +1,161 @@
package com.baeldung.hibernate.customtypes;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.LongType;
import org.hibernate.type.StringType;
import org.hibernate.type.Type;
import org.hibernate.usertype.CompositeUserType;
import org.hibernate.usertype.DynamicParameterizedType;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Objects;
import java.util.Properties;
public class SalaryType implements CompositeUserType, DynamicParameterizedType {
private String localCurrency;
@Override
public String[] getPropertyNames() {
return new String[]{"amount", "currency"};
}
@Override
public Type[] getPropertyTypes() {
return new Type[]{LongType.INSTANCE, StringType.INSTANCE};
}
@Override
public Object getPropertyValue(Object component, int property) throws HibernateException {
Salary salary = (Salary) component;
switch (property) {
case 0:
return salary.getAmount();
case 1:
return salary.getCurrency();
}
throw new IllegalArgumentException(property +
" is an invalid property index for class type " +
component.getClass().getName());
}
@Override
public void setPropertyValue(Object component, int property, Object value) throws HibernateException {
Salary salary = (Salary) component;
switch (property) {
case 0:
salary.setAmount((Long) value);
case 1:
salary.setCurrency((String) value);
}
throw new IllegalArgumentException(property +
" is an invalid property index for class type " +
component.getClass().getName());
}
@Override
public Class returnedClass() {
return Salary.class;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
if (x == y)
return true;
if (Objects.isNull(x) || Objects.isNull(y))
return false;
return x.equals(y);
}
@Override
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException {
Salary salary = new Salary();
salary.setAmount(rs.getLong(names[0]));
if (rs.wasNull())
return null;
salary.setCurrency(rs.getString(names[1]));
return salary;
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException {
if (Objects.isNull(value))
st.setNull(index, Types.BIGINT);
else {
Salary salary = (Salary) value;
st.setLong(index, SalaryCurrencyConvertor.convert(salary.getAmount(),
salary.getCurrency(), localCurrency));
st.setString(index + 1, salary.getCurrency());
}
}
@Override
public Object deepCopy(Object value) throws HibernateException {
if (Objects.isNull(value))
return null;
Salary oldSal = (Salary) value;
Salary newSal = new Salary();
newSal.setAmount(oldSal.getAmount());
newSal.setCurrency(oldSal.getCurrency());
return newSal;
}
@Override
public boolean isMutable() {
return true;
}
@Override
public Serializable disassemble(Object value, SharedSessionContractImplementor session) throws HibernateException {
return (Serializable) deepCopy(value);
}
@Override
public Object assemble(Serializable cached, SharedSessionContractImplementor session, Object owner) throws HibernateException {
return deepCopy(cached);
}
@Override
public Object replace(Object original, Object target, SharedSessionContractImplementor session, Object owner) throws HibernateException {
return original;
}
@Override
public void setParameterValues(Properties parameters) {
this.localCurrency = parameters.getProperty("currency");
}
}

View File

@ -0,0 +1,90 @@
package com.baeldung.hibernate.customtypes;
import com.baeldung.hibernate.HibernateUtil;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.junit.Assert;
import org.junit.Test;
import java.io.IOException;
import java.time.LocalDate;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
public class HibernateCustomTypesUnitTest {
@Test
public void givenEmployee_whenSavedWithCustomTypes_thenEntityIsSaved() throws IOException {
final OfficeEmployee e = new OfficeEmployee();
e.setDateOfJoining(LocalDate.now());
PhoneNumber number = new PhoneNumber(1, 222, 8781902);
e.setEmployeeNumber(number);
Address empAdd = new Address();
empAdd.setAddressLine1("Street");
empAdd.setAddressLine2("Area");
empAdd.setCity("City");
empAdd.setCountry("Country");
empAdd.setZipCode(100);
e.setEmpAddress(empAdd);
Salary empSalary = new Salary();
empSalary.setAmount(1000L);
empSalary.setCurrency("USD");
e.setSalary(empSalary);
doInHibernate(this::sessionFactory, session -> {
session.save(e);
boolean contains = session.contains(e);
Assert.assertTrue(contains);
});
}
@Test
public void givenEmployee_whenCustomTypeInQuery_thenReturnEntity() throws IOException {
final OfficeEmployee e = new OfficeEmployee();
e.setDateOfJoining(LocalDate.now());
PhoneNumber number = new PhoneNumber(1, 222, 8781902);
e.setEmployeeNumber(number);
Address empAdd = new Address();
empAdd.setAddressLine1("Street");
empAdd.setAddressLine2("Area");
empAdd.setCity("City");
empAdd.setCountry("Country");
empAdd.setZipCode(100);
e.setEmpAddress(empAdd);
Salary empSalary = new Salary();
empSalary.setAmount(1000L);
empSalary.setCurrency("USD");
e.setSalary(empSalary);
doInHibernate(this::sessionFactory, session -> {
session.save(e);
Query query = session.createQuery("FROM OfficeEmployee OE WHERE OE.empAddress.zipcode = :pinCode");
query.setParameter("pinCode",100);
int size = query.list().size();
Assert.assertEquals(1, size);
});
}
private SessionFactory sessionFactory() {
try {
return HibernateUtil.getSessionFactory("hibernate-customtypes.properties");
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,10 @@
hibernate.connection.driver_class=org.postgresql.Driver
hibernate.connection.url=jdbc:postgresql://localhost:5432/test
hibernate.connection.username=postgres
hibernate.connection.password=thule
hibernate.connection.autocommit=true
jdbc.password=thule
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=create-drop

View File

@ -0,0 +1,11 @@
=========
## Java Collections Cookbooks and Examples
### Relevant Articles:
- [Converting between an Array and a List in Java](http://www.baeldung.com/convert-array-to-list-and-list-to-array)
- [Converting between an Array and a Set in Java](http://www.baeldung.com/convert-array-to-set-and-set-to-array)
- [Converting between a List and a Set in Java](http://www.baeldung.com/convert-list-to-set-and-set-to-list)
- [Convert a Map to an Array, List or Set in Java](http://www.baeldung.com/convert-map-values-to-array-list-set)
- [Converting a List to String in Java](http://www.baeldung.com/java-list-to-string)
- [How to Convert List to Map in Java](http://www.baeldung.com/java-list-to-map)

View File

@ -0,0 +1,40 @@
<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">
<modelVersion>4.0.0</modelVersion>
<artifactId>java-collections-conversions</artifactId>
<version>0.1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>java-collections-conversions</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-java</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-java</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>${commons-collections4.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<commons-lang3.version>3.5</commons-lang3.version>
<commons-collections4.version>4.1</commons-collections4.version>
<assertj.version>3.6.1</assertj.version>
</properties>
</project>

View File

@ -0,0 +1,19 @@
=========
## Java Collections Cookbooks and Examples
### Relevant Articles:
- [Guide to WeakHashMap in Java](http://www.baeldung.com/java-weakhashmap)
- [Guide to the Guava BiMap](http://www.baeldung.com/guava-bimap)
- [The Java HashMap Under the Hood](http://www.baeldung.com/java-hashmap)
- [A Guide to LinkedHashMap in Java](http://www.baeldung.com/java-linked-hashmap)
- [A Guide to TreeMap in Java](http://www.baeldung.com/java-treemap)
- [Iterate over a Map in Java](http://www.baeldung.com/java-iterate-map)
- [Java TreeMap vs HashMap](http://www.baeldung.com/java-treemap-vs-hashmap)
- [How to Store Duplicate Keys in a Map in Java?](http://www.baeldung.com/java-map-duplicate-keys)
- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap)
- [Get the Key for a Value from a Java Map](https://www.baeldung.com/java-map-key-from-value)
- [Sort a HashMap in Java](https://www.baeldung.com/java-hashmap-sort)
- [Finding the Highest Value in a Java Map](https://www.baeldung.com/java-find-map-max)
- [Merging Two Maps with Java 8](https://www.baeldung.com/java-merge-maps)
- [How to Check If a Key Exists in a Map](https://www.baeldung.com/java-map-key-exists)

View File

@ -0,0 +1,54 @@
<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">
<modelVersion>4.0.0</modelVersion>
<artifactId>java-collections-maps</artifactId>
<version>0.1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>java-collections-maps</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-java</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-java</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>${commons-collections4.version}</version>
</dependency>
<dependency>
<groupId>com.jayway.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>${avaitility.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>one.util</groupId>
<artifactId>streamex</artifactId>
<version>0.6.5</version>
</dependency>
</dependencies>
<properties>
<commons-lang3.version>3.5</commons-lang3.version>
<commons-collections4.version>4.1</commons-collections4.version>
<collections-generic.version>4.01</collections-generic.version>
<avaitility.version>1.7.0</avaitility.version>
<assertj.version>3.6.1</assertj.version>
<eclipse.collections.version>7.1.0</eclipse.collections.version>
</properties>
</project>

View File

@ -22,3 +22,4 @@
- [Calculate Age in Java](http://www.baeldung.com/java-get-age)
- [Increment Date in Java](http://www.baeldung.com/java-increment-date)
- [Add Hours To a Date In Java](http://www.baeldung.com/java-add-hours-date)
- [Guide to DateTimeFormatter](https://www.baeldung.com/java-datetimeformatter)

View File

@ -12,3 +12,4 @@
- [BigDecimal and BigInteger in Java](http://www.baeldung.com/java-bigdecimal-biginteger)
- [Find All Pairs of Numbers in an Array That Add Up to a Given Sum](http://www.baeldung.com/java-algorithm-number-pairs-sum)
- [Java Random Long, Float, Integer and Double](http://www.baeldung.com/java-generate-random-long-float-integer-double)
- [Using Math.sin with Degrees](https://www.baeldung.com/java-math-sin-degrees)

View File

@ -259,6 +259,11 @@
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.storm</groupId>
<artifactId>storm-core</artifactId>
<version>${storm.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
@ -432,6 +437,7 @@
</repositories>
<properties>
<storm.version>1.2.2</storm.version>
<kryo.version>4.0.1</kryo.version>
<h2.version>1.4.196</h2.version>
<reladomo.version>16.5.1</reladomo.version>

View File

@ -0,0 +1,34 @@
package com.baeldung.storm;
import com.baeldung.storm.bolt.AggregatingBolt;
import com.baeldung.storm.bolt.FileWritingBolt;
import com.baeldung.storm.bolt.FilteringBolt;
import com.baeldung.storm.bolt.PrintingBolt;
import com.baeldung.storm.spout.RandomNumberSpout;
import org.apache.storm.Config;
import org.apache.storm.LocalCluster;
import org.apache.storm.topology.TopologyBuilder;
import org.apache.storm.topology.base.BaseWindowedBolt;
public class TopologyRunner {
public static void main(String[] args) {
runTopology();
}
public static void runTopology() {
String filePath = "./src/main/resources/operations.txt";
TopologyBuilder builder = new TopologyBuilder();
builder.setSpout("randomNumberSpout", new RandomNumberSpout());
builder.setBolt("filteringBolt", new FilteringBolt()).shuffleGrouping("randomNumberSpout");
builder.setBolt("aggregatingBolt", new AggregatingBolt()
.withTimestampField("timestamp")
.withLag(BaseWindowedBolt.Duration.seconds(1))
.withWindow(BaseWindowedBolt.Duration.seconds(5))).shuffleGrouping("filteringBolt");
builder.setBolt("fileBolt", new FileWritingBolt(filePath)).shuffleGrouping("aggregatingBolt");
Config config = new Config();
config.setDebug(false);
LocalCluster cluster = new LocalCluster();
cluster.submitTopology("Test", config, builder.createTopology());
}
}

View File

@ -0,0 +1,39 @@
package com.baeldung.storm.bolt;
import org.apache.storm.task.OutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.base.BaseWindowedBolt;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Tuple;
import org.apache.storm.tuple.Values;
import org.apache.storm.windowing.TupleWindow;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
public class AggregatingBolt extends BaseWindowedBolt {
private OutputCollector outputCollector;
@Override
public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
this.outputCollector = collector;
}
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("sumOfOperations", "beginningTimestamp", "endTimestamp"));
}
@Override
public void execute(TupleWindow tupleWindow) {
List<Tuple> tuples = tupleWindow.get();
tuples.sort(Comparator.comparing(a -> a.getLongByField("timestamp")));
//This is safe since the window is calculated basing on Tuple's timestamp, thus it can't really be empty
Long beginningTimestamp = tuples.get(0).getLongByField("timestamp");
Long endTimestamp = tuples.get(tuples.size() - 1).getLongByField("timestamp");
int sumOfOperations = tuples.stream().mapToInt(tuple -> tuple.getIntegerByField("operation")).sum();
Values values = new Values(sumOfOperations, beginningTimestamp, endTimestamp);
outputCollector.emit(values);
}
}

View File

@ -0,0 +1,72 @@
package com.baeldung.storm.bolt;
import com.baeldung.storm.model.AggregatedWindow;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.storm.task.OutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.base.BaseRichBolt;
import org.apache.storm.tuple.Tuple;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;
public class FileWritingBolt extends BaseRichBolt {
public static Logger logger = LoggerFactory.getLogger(FileWritingBolt.class);
private BufferedWriter writer;
private String filePath;
private ObjectMapper objectMapper;
@Override
public void prepare(Map map, TopologyContext topologyContext, OutputCollector outputCollector) {
objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
try {
writer = new BufferedWriter(new FileWriter(filePath));
} catch (IOException e) {
logger.error("Failed to open a file for writing.", e);
}
}
@Override
public void execute(Tuple tuple) {
int sumOfOperations = tuple.getIntegerByField("sumOfOperations");
long beginningTimestamp = tuple.getLongByField("beginningTimestamp");
long endTimestamp = tuple.getLongByField("endTimestamp");
if(sumOfOperations > 200) {
AggregatedWindow aggregatedWindow = new AggregatedWindow(sumOfOperations, beginningTimestamp, endTimestamp);
try {
writer.write(objectMapper.writeValueAsString(aggregatedWindow));
writer.write("\n");
writer.flush();
} catch (IOException e) {
logger.error("Failed to write data to file.", e);
}
}
}
public FileWritingBolt(String filePath) {
this.filePath = filePath;
}
@Override
public void cleanup() {
try {
writer.close();
} catch (IOException e) {
logger.error("Failed to close the writer!");
}
}
@Override
public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
}
}

View File

@ -0,0 +1,22 @@
package com.baeldung.storm.bolt;
import org.apache.storm.topology.BasicOutputCollector;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.base.BaseBasicBolt;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Tuple;
public class FilteringBolt extends BaseBasicBolt {
@Override
public void execute(Tuple tuple, BasicOutputCollector basicOutputCollector) {
int operation = tuple.getIntegerByField("operation");
if(operation > 0 ) {
basicOutputCollector.emit(tuple.getValues());
}
}
@Override
public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
outputFieldsDeclarer.declare(new Fields("operation", "timestamp"));
}
}

View File

@ -0,0 +1,18 @@
package com.baeldung.storm.bolt;
import org.apache.storm.topology.BasicOutputCollector;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.base.BaseBasicBolt;
import org.apache.storm.tuple.Tuple;
public class PrintingBolt extends BaseBasicBolt {
@Override
public void execute(Tuple tuple, BasicOutputCollector basicOutputCollector) {
System.out.println(tuple);
}
@Override
public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
}
}

View File

@ -0,0 +1,16 @@
package com.baeldung.storm.model;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
@JsonSerialize
public class AggregatedWindow {
int sumOfOperations;
long beginningTimestamp;
long endTimestamp;
public AggregatedWindow(int sumOfOperations, long beginningTimestamp, long endTimestamp) {
this.sumOfOperations = sumOfOperations;
this.beginningTimestamp = beginningTimestamp;
this.endTimestamp = endTimestamp;
}
}

View File

@ -0,0 +1,40 @@
package com.baeldung.storm.model;
public class User {
private String username;
private String password;
private String email;
private int age;
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;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}

View File

@ -0,0 +1,30 @@
package com.baeldung.storm.serialization;
import com.baeldung.storm.model.User;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
public class UserSerializer extends Serializer<User>{
@Override
public void write(Kryo kryo, Output output, User user) {
output.writeString(user.getEmail());
output.writeString(user.getUsername());
output.write(user.getAge());
}
@Override
public User read(Kryo kryo, Input input, Class<User> aClass) {
User user = new User();
String email = input.readString();
String name = input.readString();
int age = input.read();
user.setAge(age);
user.setEmail(email);
user.setUsername(name);
return user;
}
}

View File

@ -0,0 +1,35 @@
package com.baeldung.storm.spout;
import org.apache.storm.spout.SpoutOutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.base.BaseRichSpout;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Values;
import org.apache.storm.utils.Utils;
import java.util.Map;
import java.util.Random;
public class RandomIntSpout extends BaseRichSpout {
private Random random;
private SpoutOutputCollector outputCollector;
@Override
public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) {
random = new Random();
outputCollector = spoutOutputCollector;
}
@Override
public void nextTuple() {
Utils.sleep(1000);
outputCollector.emit(new Values(random.nextInt(), System.currentTimeMillis()));
}
@Override
public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
outputFieldsDeclarer.declare(new Fields("randomInt", "timestamp"));
}
}

View File

@ -0,0 +1,40 @@
package com.baeldung.storm.spout;
import org.apache.storm.spout.SpoutOutputCollector;
import org.apache.storm.task.OutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.base.BaseRichSpout;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Values;
import org.apache.storm.utils.Utils;
import java.util.Map;
import java.util.Random;
public class RandomNumberSpout extends BaseRichSpout {
private Random random;
private SpoutOutputCollector collector;
@Override
public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) {
random = new Random();
collector = spoutOutputCollector;
}
@Override
public void nextTuple() {
Utils.sleep(1000);
//This will select random int from the range (0, 100)
int operation = random.nextInt(101);
long timestamp = System.currentTimeMillis();
Values values = new Values(operation, timestamp);
collector.emit(values);
}
@Override
public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
outputFieldsDeclarer.declare(new Fields("operation", "timestamp"));
}
}

View File

@ -1,3 +1,4 @@
### Relevant Articles:
- [Guide to ScribeJava](https://www.baeldung.com/scribejava)
- [Guide to Passay](https://www.baeldung.com/java-passay)

View File

@ -1,3 +1,4 @@
To run the maven-polyglot-json-app successfully, you first have to build the maven-polyglot-json-extension module using: mvn clean install.
Related Articles:
### Relevant Articles:
- [Maven Polyglot](https://www.baeldung.com/maven-polyglot)

View File

@ -10,3 +10,6 @@
- [Build a Jar with Maven and Ignore the Test Results](http://www.baeldung.com/maven-ignore-test-results)
- [Maven Project with Multiple Source Directories](https://www.baeldung.com/maven-project-multiple-src-directories)
- [Integration Testing with Maven](https://www.baeldung.com/maven-integration-test)
- [Apache Maven Standard Directory Layout](https://www.baeldung.com/maven-directory-structure)
- [Apache Maven Tutorial](https://www.baeldung.com/maven)
- [Use the Latest Version of a Dependency in Maven](https://www.baeldung.com/maven-dependency-latest-version)

View File

@ -17,7 +17,7 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.16.RELEASE</version>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@ -42,7 +42,7 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.15.RELEASE</version>
<version>${spring-boot.version}</version>
</plugin>
</plugins>
</pluginManagement>
@ -50,6 +50,7 @@
<properties>
<rest-assured.version>3.1.0</rest-assured.version>
<spring-boot.version>1.5.16.RELEASE</spring-boot.version>
</properties>
</project>

View File

@ -17,7 +17,7 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.4.RELEASE</version>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@ -41,7 +41,7 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.0.4.RELEASE</version>
<version>${spring-boot.version}</version>
</plugin>
</plugins>
</pluginManagement>
@ -73,6 +73,6 @@
<rest-assured.version>3.1.0</rest-assured.version>
<!-- plugins -->
<thin.version>1.0.11.RELEASE</thin.version>
<spring-boot.version>2.0.5.RELEASE</spring-boot.version>
</properties>
</project>

View File

@ -29,7 +29,7 @@
</dependencies>
<properties>
<spring.version>4.3.17.RELEASE</spring.version>
<spring.version>4.3.20.RELEASE</spring.version>
<junit.jupiter.version>5.0.2</junit.jupiter.version>
</properties>

View File

@ -10,7 +10,7 @@
<groupId>com.baeldung</groupId>
<artifactId>parent-java</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-java</relativePath>
<relativePath>../../parent-java</relativePath>
</parent>
<dependencies>
<dependency>

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