Merge branch 'master' into BAEL-16646-2

This commit is contained in:
Alessio Stalla
2019-10-24 13:20:08 +02:00
138 changed files with 3689 additions and 290 deletions

View File

@@ -0,0 +1,36 @@
package com.baeldung.algorithms.knapsack;
public class Knapsack {
public int knapsackRec(int[] w, int[] v, int n, int W) {
if (n <= 0) {
return 0;
} else if (w[n - 1] > W) {
return knapsackRec(w, v, n - 1, W);
} else {
return Math.max(knapsackRec(w, v, n - 1, W), v[n - 1] + knapsackRec(w, v, n - 1, W - w[n - 1]));
}
}
public int knapsackDP(int[] w, int[] v, int n, int W) {
if (n <= 0 || W <= 0) {
return 0;
}
int[][] m = new int[n + 1][W + 1];
for (int j = 0; j <= W; j++) {
m[0][j] = 0;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= W; j++) {
if (w[i - 1] > j) {
m[i][j] = m[i - 1][j];
} else {
m[i][j] = Math.max(m[i - 1][j], m[i - 1][j - w[i - 1]] + v[i - 1]);
}
}
}
return m[n][W];
}
}

View File

@@ -0,0 +1,44 @@
package com.baeldung.algorithms.knapsack;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
public class KnapsackUnitTest {
@Test
public void givenWeightsandValues_whenCalculateMax_thenOutputCorrectResult() {
final int[] w = new int[] { 23, 26, 20, 18, 32, 27, 29, 26, 30, 27 };
final int[] v = new int[] { 505, 352, 458, 220, 354, 414, 498, 545, 473, 543 };
final int n = 10;
final int W = 67;
final Knapsack knapsack = new Knapsack();
assertEquals(1270, knapsack.knapsackRec(w, v, n, W));
assertEquals(1270, knapsack.knapsackDP(w, v, n, W));
}
@Test
public void givenZeroItems_whenCalculateMax_thenOutputZero() {
final int[] w = new int[] {};
final int[] v = new int[] {};
final int n = 0;
final int W = 67;
final Knapsack knapsack = new Knapsack();
assertEquals(0, knapsack.knapsackRec(w, v, n, W));
assertEquals(0, knapsack.knapsackDP(w, v, n, W));
}
@Test
public void givenZeroWeightLimit_whenCalculateMax_thenOutputZero() {
final int[] w = new int[] { 23, 26, 20, 18, 32, 27, 29, 26, 30, 27 };
final int[] v = new int[] { 505, 352, 458, 220, 354, 414, 498, 545, 473, 543 };
final int n = 10;
final int W = 0;
final Knapsack knapsack = new Knapsack();
assertEquals(0, knapsack.knapsackRec(w, v, n, W));
assertEquals(0, knapsack.knapsackDP(w, v, n, W));
}
}

View File

@@ -1,12 +1,12 @@
package com.baeldung.java_8_features.groupingby;
public class Tuple {
import java.util.Objects;
public class Tuple {
private final BlogPostType type;
private final String author;
private BlogPostType type;
private String author;
public Tuple(BlogPostType type, String author) {
super();
this.type = type;
this.author = author;
}
@@ -15,20 +15,27 @@ public class Tuple {
return type;
}
public void setType(BlogPostType type) {
this.type = type;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Tuple tuple = (Tuple) o;
return type == tuple.type && author.equals(tuple.author);
}
@Override
public int hashCode() {
return Objects.hash(type, author);
}
@Override
public String toString() {
return "Tuple [type=" + type + ", author=" + author + ", getType()=" + getType() + ", getAuthor()=" + getAuthor() + ", getClass()=" + getClass() + ", hashCode()=" + hashCode() + ", toString()=" + super.toString() + "]";
return "Tuple{" + "type=" + type + ", author='" + author + '\'' + '}';
}
}

View File

@@ -1,15 +1,32 @@
package com.baeldung.java_8_features.groupingby;
import com.baeldung.java_8_features.groupingby.BlogPost;
import com.baeldung.java_8_features.groupingby.BlogPostType;
import org.junit.Test;
import static java.util.Comparator.comparingInt;
import static java.util.stream.Collectors.averagingInt;
import static java.util.stream.Collectors.counting;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.groupingByConcurrent;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.maxBy;
import static java.util.stream.Collectors.summarizingInt;
import static java.util.stream.Collectors.summingInt;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.*;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import static java.util.Comparator.comparingInt;
import static java.util.stream.Collectors.*;
import static org.junit.Assert.*;
import org.junit.Test;
public class Java8GroupingByCollectorUnitTest {
@@ -180,4 +197,19 @@ public class Java8GroupingByCollectorUnitTest {
assertEquals(15, newsLikeStatistics.getMin());
}
@Test
public void givenAListOfPosts_whenGroupedByComplexMapKeyType_thenGetAMapBetweenTupleAndList() {
Map<Tuple, List<BlogPost>> postsPerTypeAndAuthor = posts.stream()
.collect(groupingBy(post -> new Tuple(post.getType(), post.getAuthor())));
List<BlogPost> result = postsPerTypeAndAuthor.get(new Tuple(BlogPostType.GUIDE, "Author 1"));
assertThat(result.size()).isEqualTo(1);
BlogPost blogPost = result.get(0);
assertThat(blogPost.getTitle()).isEqualTo("Programming guide");
assertThat(blogPost.getType()).isEqualTo(BlogPostType.GUIDE);
assertThat(blogPost.getAuthor()).isEqualTo("Author 1");
}
}

View File

@@ -192,15 +192,48 @@ public class ArrayOperations {
return array[new Random().nextInt(array.length)];
}
public static Integer[] intersectionSimple(final Integer[] a, final Integer[] b){
return Stream.of(a).filter(Arrays.asList(b)::contains).toArray(Integer[]::new);
public static Integer[] intersectionSimple(final Integer[] a, final Integer[] b) {
return Stream.of(a)
.filter(Arrays.asList(b)::contains)
.toArray(Integer[]::new);
}
public static Integer[] intersectionSet(final Integer[] a, final Integer[] b){
return Stream.of(a).filter(Arrays.asList(b)::contains).distinct().toArray(Integer[]::new);
public static Integer[] intersectionSet(final Integer[] a, final Integer[] b) {
return Stream.of(a)
.filter(Arrays.asList(b)::contains)
.distinct()
.toArray(Integer[]::new);
}
public static Integer[] intersectionMultiSet(final Integer[] a, final Integer[] b){
return Stream.of(a).filter(new LinkedList<>(Arrays.asList(b))::remove).toArray(Integer[]::new);
public static Integer[] intersectionMultiSet(final Integer[] a, final Integer[] b) {
return Stream.of(a)
.filter(new LinkedList<>(Arrays.asList(b))::remove)
.toArray(Integer[]::new);
}
public static Integer[] addElementUsingPureJava(Integer[] srcArray, int elementToAdd) {
Integer[] destArray = new Integer[srcArray.length + 1];
for (int i = 0; i < srcArray.length; i++) {
destArray[i] = srcArray[i];
}
destArray[destArray.length - 1] = elementToAdd;
return destArray;
}
public static int[] insertAnElementAtAGivenIndex(final int[] srcArray, int index, int newElement) {
int[] destArray = new int[srcArray.length + 1];
int j = 0;
for (int i = 0; i < destArray.length - 1; i++) {
if (i == index) {
destArray[i] = newElement;
} else {
destArray[i] = srcArray[j];
j++;
}
}
return destArray;
}
}

View File

@@ -0,0 +1,23 @@
package com.baeldung.arraylist.operations;
import java.util.ArrayList;
public class ArrayListOperations {
public static Integer getAnIntegerElement(ArrayList<Integer> anArrayList, int index) {
return anArrayList.get(index);
}
public static void modifyAnIntegerElement(ArrayList<Integer> anArrayList, int index, Integer newElement) {
anArrayList.set(index, newElement);
}
public static void appendAnIntegerElement(ArrayList<Integer> anArrayList, Integer newElement) {
anArrayList.add(newElement);
}
public static void insertAnIntegerElementAtIndex(ArrayList<Integer> anArrayList, int index, Integer newElement) {
anArrayList.add(index, newElement);
}
}

View File

@@ -1,12 +1,11 @@
package com.baeldung.array.operations;
import java.util.Arrays;
import org.assertj.core.api.Condition;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertArrayEquals;
public class ArrayOperationsUnitTest {
@@ -262,8 +261,7 @@ public class ArrayOperationsUnitTest {
@Test
public void whenMapIntArrayToString_thenReturnArray() {
String[] expectedArray = new String[] { "Value: 3", "Value: 5", "Value: 2", "Value: 5", "Value: 14",
"Value: 4" };
String[] expectedArray = new String[] { "Value: 3", "Value: 5", "Value: 2", "Value: 5", "Value: 14", "Value: 4" };
String[] output = ArrayOperations.mapIntArrayToString(defaultIntArray);
assertThat(output).containsExactly(expectedArray);
@@ -313,13 +311,10 @@ public class ArrayOperationsUnitTest {
int[] output5 = ArrayOperations.shuffleIntArray(defaultIntArray);
int[] output6 = ArrayOperations.shuffleIntArray(defaultIntArray);
Condition<int[]> atLeastOneArraysIsNotEqual = new Condition<int[]>(
"at least one output should be different (order-wise)") {
Condition<int[]> atLeastOneArraysIsNotEqual = new Condition<int[]>("at least one output should be different (order-wise)") {
@Override
public boolean matches(int[] value) {
return !Arrays.equals(value, output) || !Arrays.equals(value, output2) || !Arrays.equals(value, output3)
|| !Arrays.equals(value, output4) || !Arrays.equals(value, output5)
|| !Arrays.equals(value, output6);
return !Arrays.equals(value, output) || !Arrays.equals(value, output2) || !Arrays.equals(value, output3) || !Arrays.equals(value, output4) || !Arrays.equals(value, output5) || !Arrays.equals(value, output6);
}
};
@@ -335,13 +330,10 @@ public class ArrayOperationsUnitTest {
Integer[] output5 = ArrayOperations.shuffleObjectArray(defaultObjectArray);
Integer[] output6 = ArrayOperations.shuffleObjectArray(defaultObjectArray);
Condition<Integer[]> atLeastOneArraysIsNotEqual = new Condition<Integer[]>(
"at least one output should be different (order-wise)") {
Condition<Integer[]> atLeastOneArraysIsNotEqual = new Condition<Integer[]>("at least one output should be different (order-wise)") {
@Override
public boolean matches(Integer[] value) {
return !Arrays.equals(value, output) || !Arrays.equals(value, output2) || !Arrays.equals(value, output3)
|| !Arrays.equals(value, output4) || !Arrays.equals(value, output5)
|| !Arrays.equals(value, output6);
return !Arrays.equals(value, output) || !Arrays.equals(value, output2) || !Arrays.equals(value, output3) || !Arrays.equals(value, output4) || !Arrays.equals(value, output5) || !Arrays.equals(value, output6);
}
};
@@ -362,4 +354,27 @@ public class ArrayOperationsUnitTest {
assertThat(defaultObjectArray).contains(output);
}
@Test
public void givenSourceArrayAndElement_whenAddElementUsingPureJavaIsInvoked_thenNewElementMustBeAdded() {
Integer[] sourceArray = { 1, 2, 3, 4 };
int elementToAdd = 5;
Integer[] destArray = ArrayOperations.addElementUsingPureJava(sourceArray, elementToAdd);
Integer[] expectedArray = { 1, 2, 3, 4, 5 };
assertArrayEquals(expectedArray, destArray);
}
@Test
public void whenInsertAnElementAtAGivenIndexCalled_thenShiftTheFollowingElementsAndInsertTheElementInArray() {
int[] expectedArray = { 1, 4, 2, 3, 0 };
int[] anArray = new int[4];
anArray[0] = 1;
anArray[1] = 2;
anArray[2] = 3;
int[] outputArray = ArrayOperations.insertAnElementAtAGivenIndex(anArray, 1, 4);
assertThat(outputArray).containsExactly(expectedArray);
}
}

View File

@@ -0,0 +1,50 @@
package com.baeldung.arraylist.operations;
import java.util.ArrayList;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class ArrayListOperationsUnitTest {
private ArrayList<Integer> anArrayList;
@BeforeEach
public void setupDefaults() {
anArrayList = new ArrayList<>();
anArrayList.add(2);
anArrayList.add(3);
anArrayList.add(4);
}
@Test
public void whenGetAnIntegerElementCalled_thenReturnTheIntegerElement() {
Integer output = ArrayListOperations.getAnIntegerElement(anArrayList, 1);
assertThat(output).isEqualTo(3);
}
@Test
public void whenModifyAnIntegerElementCalled_thenModifyTheIntegerElement() {
ArrayListOperations.modifyAnIntegerElement(anArrayList, 2, 5);
Integer output = ArrayListOperations.getAnIntegerElement(anArrayList, 2);
assertThat(output).isEqualTo(5);
}
@Test
public void whenAppendAnIntegerElementCalled_thenTheIntegerElementIsAppendedToArrayList() {
ArrayListOperations.appendAnIntegerElement(anArrayList, 6);
Integer output = ArrayListOperations.getAnIntegerElement(anArrayList, anArrayList.size() - 1);
assertThat(output).isEqualTo(6);
}
@Test
public void whenInsertAnIntegerAtIndexCalled_thenTheIntegerElementIsInseredToArrayList() {
ArrayListOperations.insertAnIntegerElementAtIndex(anArrayList, 1, 10);
Integer output = ArrayListOperations.getAnIntegerElement(anArrayList, 1);
assertThat(output).isEqualTo(10);
}
}

View File

@@ -0,0 +1,42 @@
package com.baeldung.list;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* Demo different approaches to get count of duplicated elements in an
* arrayList
*/
public class DuplicatesCounter {
public static <T> Map<T, Long> countByClassicalLoop(List<T> inputList) {
Map<T, Long> resultMap = new HashMap<>();
for (T element : inputList) {
if (resultMap.containsKey(element)) {
resultMap.put(element, resultMap.get(element) + 1L);
} else {
resultMap.put(element, 1L);
}
}
return resultMap;
}
public static <T> Map<T, Long> countByClassicalLoopWithMapCompute(List<T> inputList) {
Map<T, Long> resultMap = new HashMap<>();
for (T element : inputList) {
resultMap.compute(element, (k, v) -> v == null ? 1 : v + 1);
}
return resultMap;
}
public static <T> Map<T, Long> countByStreamToMap(List<T> inputList) {
return inputList.stream().collect(Collectors.toMap(Function.identity(), v -> 1L, Long::sum));
}
public static <T> Map<T, Long> countByStreamGroupBy(List<T> inputList) {
return inputList.stream().collect(Collectors.groupingBy(k -> k, Collectors.counting()));
}
}

View File

@@ -0,0 +1,55 @@
package com.baeldung.list;
import org.assertj.core.util.Lists;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.MapEntry.entry;
class DuplicatesCounterUnitTest {
private static List<String> INPUT_LIST = Lists.list(
"expect1",
"expect2", "expect2",
"expect3", "expect3", "expect3",
"expect4", "expect4", "expect4", "expect4");
@Test
void givenInput_whenCountByClassicalLoop_thenGetResultMap() {
Map<String, Long> result = DuplicatesCounter.countByClassicalLoop(INPUT_LIST);
verifyResult(result);
}
@Test
void givenInput_whenCountByClassicalLoopWithMapCompute_thenGetResultMap() {
Map<String, Long> result = DuplicatesCounter.countByClassicalLoopWithMapCompute(INPUT_LIST);
verifyResult(result);
}
@Test
void givenInput_whenCountByStreamToMap_thenGetResultMap() {
Map<String, Long> result = DuplicatesCounter.countByStreamToMap(INPUT_LIST);
verifyResult(result);
}
@Test
void givenInput_whenCountByStreamGroupBy_thenGetResultMap() {
Map<String, Long> result = DuplicatesCounter.countByStreamGroupBy(INPUT_LIST);
verifyResult(result);
}
private void verifyResult(Map<String, Long> resultMap) {
assertThat(resultMap)
.isNotEmpty().hasSize(4)
.containsExactly(
entry("expect1", 1L),
entry("expect2", 2L),
entry("expect3", 3L),
entry("expect4", 4L));
}
}

View File

@@ -1,6 +1,6 @@
package com.baeldung.date;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -16,7 +16,7 @@ import java.util.Locale;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class DateDiffUnitTest {
@@ -31,14 +31,14 @@ public class DateDiffUnitTest {
assertEquals(diff, 6);
}
@Test
public void givenTwoDatesInJava8_whenDifferentiating_thenWeGetSix() {
LocalDate now = LocalDate.now();
LocalDate sixDaysBehind = now.minusDays(6);
Period period = Period.between(now, sixDaysBehind);
int diff = period.getDays();
int diff = Math.abs(period.getDays());
assertEquals(diff, 6);
}
@@ -68,7 +68,8 @@ public class DateDiffUnitTest {
public void givenTwoZonedDateTimesInJava8_whenDifferentiating_thenWeGetSix() {
LocalDateTime ldt = LocalDateTime.now();
ZonedDateTime now = ldt.atZone(ZoneId.of("America/Montreal"));
ZonedDateTime sixDaysBehind = now.withZoneSameInstant(ZoneId.of("Asia/Singapore")).minusDays(6);
ZonedDateTime sixDaysBehind = now.withZoneSameInstant(ZoneId.of("Asia/Singapore"))
.minusDays(6);
long diff = ChronoUnit.DAYS.between(sixDaysBehind, now);
assertEquals(diff, 6);
}

View File

@@ -36,10 +36,15 @@ class UseLocalDate {
}
LocalDate getFirstDayOfMonth() {
LocalDate firstDayOfMonth = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
LocalDate firstDayOfMonth = LocalDate.now()
.with(TemporalAdjusters.firstDayOfMonth());
return firstDayOfMonth;
}
boolean isLeapYear(LocalDate localDate) {
return localDate.isLeapYear();
}
LocalDateTime getStartOfDay(LocalDate localDate) {
LocalDateTime startofDay = localDate.atStartOfDay();
return startofDay;

View File

@@ -2,6 +2,7 @@ package com.baeldung.datetime;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.temporal.ChronoField;
public class UseLocalDateTime {
@@ -21,4 +22,7 @@ public class UseLocalDateTime {
return endOfDate;
}
LocalDateTime ofEpochSecond(int epochSecond, ZoneOffset zoneOffset) {
return LocalDateTime.ofEpochSecond(epochSecond, 0, zoneOffset);
}
}

View File

@@ -9,6 +9,10 @@ public class UseLocalTime {
return LocalTime.of(hour, min, seconds);
}
LocalTime getLocalTimeUsingFactoryOfMethod(int hour, int min) {
return LocalTime.of(hour, min);
}
LocalTime getLocalTimeUsingParseMethod(String timeRepresentation) {
return LocalTime.parse(timeRepresentation);
}

View File

@@ -12,31 +12,35 @@ class UseZonedDateTime {
return ZonedDateTime.of(localDateTime, zoneId);
}
ZonedDateTime getZonedDateTimeUsingParseMethod(String parsableString) {
return ZonedDateTime.parse(parsableString);
}
ZonedDateTime getStartOfDay(LocalDate localDate, ZoneId zone) {
ZonedDateTime startofDay = localDate.atStartOfDay()
ZonedDateTime startOfDay = localDate.atStartOfDay()
.atZone(zone);
return startofDay;
return startOfDay;
}
ZonedDateTime getStartOfDayShorthand(LocalDate localDate, ZoneId zone) {
ZonedDateTime startofDay = localDate.atStartOfDay(zone);
return startofDay;
ZonedDateTime startOfDay = localDate.atStartOfDay(zone);
return startOfDay;
}
ZonedDateTime getStartOfDayFromZonedDateTime(ZonedDateTime zonedDateTime) {
ZonedDateTime startofDay = zonedDateTime.toLocalDateTime()
ZonedDateTime startOfDay = zonedDateTime.toLocalDateTime()
.toLocalDate()
.atStartOfDay(zonedDateTime.getZone());
return startofDay;
return startOfDay;
}
ZonedDateTime getStartOfDayAtMinTime(ZonedDateTime zonedDateTime) {
ZonedDateTime startofDay = zonedDateTime.with(ChronoField.HOUR_OF_DAY, 0);
return startofDay;
ZonedDateTime startOfDay = zonedDateTime.with(ChronoField.HOUR_OF_DAY, 0);
return startOfDay;
}
ZonedDateTime getStartOfDayAtMidnightTime(ZonedDateTime zonedDateTime) {
ZonedDateTime startofDay = zonedDateTime.with(ChronoField.NANO_OF_DAY, 0);
return startofDay;
ZonedDateTime startOfDay = zonedDateTime.with(ChronoField.NANO_OF_DAY, 0);
return startOfDay;
}
}

View File

@@ -1,12 +1,16 @@
package com.baeldung.date.comparison;
import org.junit.Test;
import java.time.*;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import org.junit.Test;
public class Java8DateTimeApiGeneralComparisonsUnitTest {
@Test
@@ -54,10 +58,8 @@ public class Java8DateTimeApiGeneralComparisonsUnitTest {
@Test
public void givenZonedDateTimes_whenComparing_thenAssertsPass() {
ZonedDateTime timeInNewYork = ZonedDateTime.of(2019, 8, 10, 8, 0, 0, 0,
ZoneId.of("America/New_York"));
ZonedDateTime timeInBerlin = ZonedDateTime.of(2019, 8, 10, 14, 0, 0, 0,
ZoneId.of("Europe/Berlin"));
ZonedDateTime timeInNewYork = ZonedDateTime.of(2019, 8, 10, 8, 0, 0, 0, ZoneId.of("America/New_York"));
ZonedDateTime timeInBerlin = ZonedDateTime.of(2019, 8, 10, 14, 0, 0, 0, ZoneId.of("Europe/Berlin"));
assertThat(timeInNewYork.isAfter(timeInBerlin), is(false));
assertThat(timeInNewYork.isBefore(timeInBerlin), is(false));
@@ -80,4 +82,14 @@ public class Java8DateTimeApiGeneralComparisonsUnitTest {
assertThat(firstTime.compareTo(secondTime), is(-1));
}
@Test
public void givenMinMaxLocalTimes_whenComparing_thenAssertsPass() {
LocalTime minTime = LocalTime.MIN;
LocalTime time = LocalTime.of(8, 30);
LocalTime maxTime = LocalTime.MAX;
assertThat(minTime.isBefore(time), is(true));
assertThat(time.isBefore(maxTime), is(true));
}
}

View File

@@ -1,16 +1,39 @@
package com.baeldung.dateapi;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import org.junit.Test;
public class JavaDurationUnitTest {
@Test
public void givenATimePlus30Seconds_whenRequestingDuration_thenExpect30() {
LocalTime initialTime = LocalTime.of(6, 30, 0);
LocalTime finalTime = initialTime.plus(Duration.ofSeconds(30));
long seconds = Duration.between(initialTime, finalTime)
.getSeconds();
assertThat(seconds).isEqualTo(30);
}
@Test
public void givenATimePlus30Seconds_whenRequestingSecondsBetween_thenExpect30() {
LocalTime initialTime = LocalTime.of(6, 30, 0);
LocalTime finalTime = initialTime.plus(Duration.ofSeconds(30));
long seconds = ChronoUnit.SECONDS.between(initialTime, finalTime);
assertThat(seconds).isEqualTo(30);
}
@Test
public void test2() {
Instant start = Instant.parse("2017-10-03T10:15:30.00Z");
@@ -29,11 +52,15 @@ public class JavaDurationUnitTest {
Duration fromMinutes = Duration.ofMinutes(60);
assertEquals(1, fromMinutes.toHours());
assertEquals(120, duration.plusSeconds(60).getSeconds());
assertEquals(30, duration.minusSeconds(30).getSeconds());
assertEquals(120, duration.plusSeconds(60)
.getSeconds());
assertEquals(30, duration.minusSeconds(30)
.getSeconds());
assertEquals(120, duration.plus(60, ChronoUnit.SECONDS).getSeconds());
assertEquals(30, duration.minus(30, ChronoUnit.SECONDS).getSeconds());
assertEquals(120, duration.plus(60, ChronoUnit.SECONDS)
.getSeconds());
assertEquals(30, duration.minus(30, ChronoUnit.SECONDS)
.getSeconds());
Duration fromChar1 = Duration.parse("P1DT1H10M10.5S");
Duration fromChar2 = Duration.parse("PT10M");

View File

@@ -1,18 +1,41 @@
package com.baeldung.dateapi;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import java.time.LocalDate;
import java.time.Period;
import java.time.temporal.ChronoUnit;
import org.apache.log4j.Logger;
import org.junit.Test;
import java.time.LocalDate;
import java.time.Period;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
public class JavaPeriodUnitTest {
private static final Logger LOG = Logger.getLogger(JavaPeriodUnitTest.class);
@Test
public void givenADatePlus5Days_whenRequestingPeriod_thenExpectFive() {
LocalDate initialDate = LocalDate.parse("2007-05-10");
LocalDate finalDate = initialDate.plus(Period.ofDays(5));
int days = Period.between(initialDate, finalDate)
.getDays();
assertThat(days).isEqualTo(5);
}
@Test
public void givenADatePlus5Days_whenRequestingDaysBetween_thenExpectFive() {
LocalDate initialDate = LocalDate.parse("2007-05-10");
LocalDate finalDate = initialDate.plus(Period.ofDays(5));
long days = ChronoUnit.DAYS.between(initialDate, finalDate);
assertThat(days).isEqualTo(5);
}
@Test
public void whenTestPeriod_thenOk() {
@@ -24,8 +47,10 @@ public class JavaPeriodUnitTest {
LOG.info(String.format("Years:%d months:%d days:%d", period.getYears(), period.getMonths(), period.getDays()));
assertFalse(period.isNegative());
assertEquals(56, period.plusDays(50).getDays());
assertEquals(9, period.minusMonths(2).getMonths());
assertEquals(56, period.plusDays(50)
.getDays());
assertEquals(9, period.minusMonths(2)
.getMonths());
Period fromUnits = Period.of(3, 10, 10);
Period fromDays = Period.ofDays(50);

View File

@@ -7,12 +7,13 @@ import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.ZoneOffset;
import org.junit.Test;
public class UseLocalDateTimeUnitTest {
UseLocalDateTime useLocalDateTime = new UseLocalDateTime();
private UseLocalDateTime useLocalDateTime = new UseLocalDateTime();
@Test
public void givenString_whenUsingParse_thenLocalDateTime() {
@@ -33,4 +34,28 @@ public class UseLocalDateTimeUnitTest {
assertThat(endOfDayFromGivenDirectly.toLocalTime()).isEqualTo(LocalTime.MAX);
assertThat(endOfDayFromGivenDirectly.toString()).isEqualTo("2018-06-23T23:59:59.999999999");
}
@Test
public void givenLocalDateTimeInFebruary_whenRequestingMonth_thenMonthIsFebruary() {
LocalDateTime givenLocalDateTime = LocalDateTime.of(2015, Month.FEBRUARY, 20, 6, 30);
assertThat(givenLocalDateTime.getMonth()).isEqualTo(Month.FEBRUARY);
}
@Test
public void givenLocalDateTime_whenManipulating_thenResultIsAsExpected() {
LocalDateTime givenLocalDateTime = LocalDateTime.parse("2015-02-20T06:30:00");
LocalDateTime manipulatedLocalDateTime = givenLocalDateTime.plusDays(1);
manipulatedLocalDateTime = manipulatedLocalDateTime.minusHours(2);
assertThat(manipulatedLocalDateTime).isEqualTo(LocalDateTime.of(2015, Month.FEBRUARY, 21, 4, 30));
}
@Test
public void whenRequestTimeFromEpoch_thenResultIsAsExpected() {
LocalDateTime result = useLocalDateTime.ofEpochSecond(1465817690, ZoneOffset.UTC);
assertThat(result.toString()).isEqualTo("2016-06-13T11:34:50");
}
}

View File

@@ -12,7 +12,7 @@ import org.junit.Test;
public class UseLocalDateUnitTest {
UseLocalDate useLocalDate = new UseLocalDate();
private UseLocalDate useLocalDate = new UseLocalDate();
@Test
public void givenValues_whenUsingFactoryOf_thenLocalDate() {
@@ -88,4 +88,31 @@ public class UseLocalDateUnitTest {
assertThat(endOfDayWithMax.toString()).isEqualTo("2018-06-23T23:59:59.999999999");
}
@Test
public void givenTheYear2000_whenCheckingForLeapYear_thenReturnTrue() {
LocalDate given = LocalDate.parse("2000-06-23");
boolean leapYear = useLocalDate.isLeapYear(given);
assertThat(leapYear).isEqualTo(true);
}
@Test
public void givenTheYear2004_whenCheckingForLeapYear_thenReturnTrue() {
LocalDate given = LocalDate.parse("2004-06-23");
boolean leapYear = useLocalDate.isLeapYear(given);
assertThat(leapYear).isEqualTo(true);
}
@Test
public void givenTheYear2019_whenCheckingForLeapYear_thenReturnFalse() {
LocalDate given = LocalDate.parse("2019-06-23");
boolean leapYear = useLocalDate.isLeapYear(given);
assertThat(leapYear).isEqualTo(false);
}
}

View File

@@ -7,21 +7,30 @@ import org.junit.Test;
public class UseLocalTimeUnitTest {
UseLocalTime useLocalTime = new UseLocalTime();
private UseLocalTime useLocalTime = new UseLocalTime();
@Test
public void givenValues_whenUsingFactoryOf_thenLocalTime() {
Assert.assertEquals("07:07:07", useLocalTime.getLocalTimeUsingFactoryOfMethod(7, 7, 7).toString());
Assert.assertEquals("07:07:07", useLocalTime.getLocalTimeUsingFactoryOfMethod(7, 7, 7)
.toString());
}
@Test
public void givenValues_whenUsingFactoryOfWithoutSeconds_thenLocalTime() {
Assert.assertEquals("07:07", useLocalTime.getLocalTimeUsingFactoryOfMethod(7, 7)
.toString());
}
@Test
public void givenString_whenUsingParse_thenLocalTime() {
Assert.assertEquals("06:30", useLocalTime.getLocalTimeUsingParseMethod("06:30").toString());
Assert.assertEquals("06:30", useLocalTime.getLocalTimeUsingParseMethod("06:30")
.toString());
}
@Test
public void givenTime_whenAddHour_thenLocalTime() {
Assert.assertEquals("07:30", useLocalTime.addAnHour(LocalTime.of(6, 30)).toString());
Assert.assertEquals("07:30", useLocalTime.addAnHour(LocalTime.of(6, 30))
.toString());
}
@Test

View File

@@ -7,13 +7,14 @@ import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Set;
import org.junit.Assert;
import org.junit.Test;
public class UseZonedDateTimeUnitTest {
UseZonedDateTime zonedDateTime = new UseZonedDateTime();
private UseZonedDateTime zonedDateTime = new UseZonedDateTime();
@Test
public void givenZoneId_thenZonedDateTime() {
@@ -22,6 +23,13 @@ public class UseZonedDateTimeUnitTest {
Assert.assertEquals(zoneId, ZoneId.from(zonedDatetime));
}
@Test
public void whenRequestingZones_thenAtLeastOneIsReturned() {
Set<String> allZoneIds = ZoneId.getAvailableZoneIds();
assertThat(allZoneIds.size()).isGreaterThan(1);
}
@Test
public void givenLocalDateOrZoned_whenSettingStartOfDay_thenReturnMidnightInAllCases() {
LocalDate given = LocalDate.parse("2018-06-23");
@@ -42,4 +50,15 @@ public class UseZonedDateTimeUnitTest {
assertThat(startOfOfDayWithMethod.toLocalTime()
.toString()).isEqualTo("00:00");
}
@Test
public void givenAStringWithTimeZone_whenParsing_thenEqualsExpected() {
ZonedDateTime resultFromString = zonedDateTime.getZonedDateTimeUsingParseMethod("2015-05-03T10:15:30+01:00[Europe/Paris]");
ZonedDateTime resultFromLocalDateTime = ZonedDateTime.of(2015, 5, 3, 11, 15, 30, 0, ZoneId.of("Europe/Paris"));
assertThat(resultFromString.getZone()).isEqualTo(ZoneId.of("Europe/Paris"));
assertThat(resultFromLocalDateTime.getZone()).isEqualTo(ZoneId.of("Europe/Paris"));
assertThat(resultFromString).isEqualTo(resultFromLocalDateTime);
}
}

View File

@@ -0,0 +1,18 @@
package com.baeldung.core.modifiers;
public class FirstClass {
protected String name;
protected FirstClass(String name) {
this.name = name;
}
protected String getName() {
return name;
}
protected static class InnerClass {
public InnerClass() {}
}
}

View File

@@ -0,0 +1,15 @@
package com.baeldung.core.modifiers;
public class GenericClass {
public static void main(String[] args) {
// accessing protected constructor
FirstClass first = new FirstClass("random name");
// using protected method
System.out.println("FirstClass name is " + first.getName());
// accessing a protected field
first.name = "new name";
// instantiating protected inner class
FirstClass.InnerClass innerClass = new FirstClass.InnerClass();
}
}

View File

@@ -0,0 +1,18 @@
package com.baeldung.core.modifiers.otherpackage;
import com.baeldung.core.modifiers.FirstClass;
public class SecondClass extends FirstClass {
public SecondClass(String name) {
// accessing protected constructor
super(name);
// using protected method
System.out.println("SecondClass name is " + this.getName());
// accessing a protected field
this.name = "new name";
// instantiating protected inner class -> add public constructor to InnerClass
FirstClass.InnerClass innerClass = new FirstClass.InnerClass();
}
}

View File

@@ -0,0 +1,20 @@
package com.baeldung.core.modifiers.otherpackage;
import com.baeldung.core.modifiers.FirstClass;
//import com.baeldung.core.modifiers.FirstClass.InnerClass;
public class SecondGenericClass {
// uncomment the following lines to see the errors
public static void main(String[] args) {
// accessing protected constructor
// FirstClass first = new FirstClass("random name");
// using protected method
// System.out.println("FirstClass name is " + first.getName());
// accessing a protected field
// first.name = "new name";
// instantiating protected inner class
// FirstClass.InnerClass innerClass = new FirstClass.InnerClass();
}
}

View File

@@ -3,7 +3,6 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung.ddd</groupId>
<artifactId>ddd</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ddd</name>
<packaging>jar</packaging>
<description>DDD series examples</description>
@@ -35,7 +34,6 @@
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>${junit-platform.version}</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -85,8 +83,6 @@
<properties>
<joda-money.version>1.0.1</joda-money.version>
<maven-surefire-plugin.version>2.22.0</maven-surefire-plugin.version>
<spring-boot.version>2.0.6.RELEASE</spring-boot.version>
</properties>
</project>

View File

@@ -1,7 +1,6 @@
<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>
<groupId>com.baeldung</groupId>
<artifactId>disruptor</artifactId>
<version>0.1.0-SNAPSHOT</version>
<name>disruptor</name>
@@ -116,10 +115,7 @@
<properties>
<!-- util -->
<disruptor.version>3.3.6</disruptor.version>
<!-- testing -->
<testng.version>6.10</testng.version>
<assertj.version>3.6.1</assertj.version>
<!-- testing -->
<maven-shade-plugin.version>2.4.3</maven-shade-plugin.version>
<maven-jar-plugin.version>3.0.2</maven-jar-plugin.version>
<onejar-maven-plugin.version>1.4.4</onejar-maven-plugin.version>

View File

@@ -1,7 +1,6 @@
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>dozer</artifactId>
<version>1.0</version>
<name>dozer</name>

View File

@@ -32,7 +32,6 @@
<dubbo.version>2.5.7</dubbo.version>
<zookeeper.version>3.4.11</zookeeper.version>
<zkclient.version>0.10</zkclient.version>
<surefire.version>2.19.1</surefire.version>
</properties>
</project>

View File

@@ -3,7 +3,6 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung.ethereum</groupId>
<artifactId>ethereum</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ethereum</name>
<parent>
@@ -207,8 +206,6 @@
</repositories>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<tomcat.version>8.5.4</tomcat.version>
<ethereumj-core.version>1.5.0-RELEASE</ethereumj-core.version>
<web3j.core.version>3.3.1</web3j.core.version>
<spring.boot.version>1.5.6.RELEASE</spring.boot.version>

View File

@@ -3,7 +3,6 @@
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>flyway-cdi-extension</artifactId>
<version>1.0-SNAPSHOT</version>
<name>flyway-cdi-extension</name>
@@ -51,8 +50,6 @@
</dependencies>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<cdi-api.version>2.0.SP1</cdi-api.version>
<weld-se-core.version>3.0.5.Final</weld-se-core.version>
<flyway-core.version>5.1.4</flyway-core.version>

View File

@@ -5,7 +5,6 @@
<!-- POM file generated with GWT webAppCreator -->
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>google-web-toolkit</artifactId>
<version>1.0-SNAPSHOT</version>
<name>google-web-toolkit</name>

View File

@@ -2,7 +2,6 @@
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>gson</artifactId>
<version>0.1-SNAPSHOT</version>
<name>gson</name>

View File

@@ -13,9 +13,6 @@
<relativePath>../parent-java</relativePath>
</parent>
<dependencies>
</dependencies>
<build>
<finalName>guava-collections-map</finalName>
<resources>
@@ -26,7 +23,4 @@
</resources>
</build>
<properties>
</properties>
</project>

View File

@@ -1,7 +1,6 @@
<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>
<groupId>com.baeldung</groupId>
<artifactId>guava-collections-set</artifactId>
<version>0.1.0-SNAPSHOT</version>
<name>guava-collections-set</name>
@@ -28,8 +27,6 @@
</build>
<properties>
<!-- util -->
<guava.version>27.1-jre</guava.version>
<!-- testing -->
<assertj.version>3.6.1</assertj.version>
</properties>

View File

@@ -1,7 +1,6 @@
<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>
<groupId>com.baeldung</groupId>
<artifactId>guava-collections</artifactId>
<version>0.1.0-SNAPSHOT</version>
<name>guava-collections</name>
@@ -54,7 +53,6 @@
<properties>
<!-- util -->
<guava.version>24.0-jre</guava.version>
<commons-collections4.version>4.1</commons-collections4.version>
<!-- testing -->

View File

@@ -1,7 +1,6 @@
<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>
<groupId>com.baeldung</groupId>
<artifactId>guava-io</artifactId>
<version>0.1.0-SNAPSHOT</version>
<name>guava-io</name>

View File

@@ -1,7 +1,6 @@
<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>
<groupId>com.baeldung</groupId>
<artifactId>guava</artifactId>
<version>0.1.0-SNAPSHOT</version>
<name>guava</name>
@@ -39,9 +38,6 @@
</build>
<properties>
<!-- util -->
<guava.version>24.0-jre</guava.version>
<!-- testing -->
<assertj.version>3.6.1</assertj.version>
</properties>

View File

@@ -1,7 +1,6 @@
<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>
<groupId>com.baeldung</groupId>
<artifactId>hazelcast</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hazelcast</name>

View File

@@ -1,7 +1,6 @@
<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>
<groupId>com.baeldung</groupId>
<artifactId>httpclient-simple</artifactId>
<version>0.1-SNAPSHOT</version>
<name>httpclient-simple</name>

View File

@@ -1,7 +1,6 @@
<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>
<groupId>com.baeldung</groupId>
<artifactId>httpclient</artifactId>
<version>0.1-SNAPSHOT</version>
<name>httpclient</name>
@@ -48,11 +47,6 @@
<artifactId>httpmime</artifactId>
<version>${httpclient.version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons-codec.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId>
@@ -82,51 +76,12 @@
</resources>
</build>
<profiles>
<profile>
<id>live</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<excludes>
<exclude>**/*ManualTest.java</exclude>
</excludes>
<includes>
<include>**/*LiveTest.java</include>
</includes>
</configuration>
</execution>
</executions>
<configuration>
<systemPropertyVariables>
<test.mime>json</test.mime>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<properties>
<!-- util -->
<guava.version>19.0</guava.version>
<commons-codec.version>1.10</commons-codec.version>
<httpasyncclient.version>4.1.4</httpasyncclient.version>
<!-- testing -->
<wiremock.version>2.5.1</wiremock.version>
<httpclient.version>4.5.8</httpclient.version> <!-- 4.3.6 --> <!-- 4.4-beta1 -->
<!-- maven plugins -->
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
</properties>
</project>

View File

@@ -41,23 +41,11 @@
<artifactId>hystrix-metrics-event-stream</artifactId>
<version>${hystrix-metrics-event-stream.version}</version>
</dependency>
<!--<dependency> <groupId>com.netflix.hystrix</groupId> <artifactId>hystrix-dashboard</artifactId> <version>${hystrix-dashboard.version}</version> </dependency> -->
<dependency>
<groupId>com.netflix.rxjava</groupId>
<artifactId>rxjava-core</artifactId>
<version>${rxjava-core.version}</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>${hamcrest-all.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
@@ -65,9 +53,7 @@
<hystrix-core.version>1.5.8</hystrix-core.version>
<rxjava-core.version>0.20.7</rxjava-core.version>
<!-- maven plugins -->
<maven-resources-plugin.version>2.7</maven-resources-plugin.version>
<hystrix-metrics-event-stream.version>1.5.8</hystrix-metrics-event-stream.version>
<hystrix-dashboard.version>1.5.8</hystrix-dashboard.version>
</properties>
</project>

View File

@@ -2,7 +2,8 @@
This module contains articles about Jackson that are also part of the Jackson Ebook.
###The Course
### The Course
The "REST With Spring" Classes: http://bit.ly/restwithspring
### Relevant Articles:

View File

@@ -1,20 +1,29 @@
package com.baeldung.jackson.objectmapper;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import java.io.File;
import java.net.URL;
import java.util.List;
import java.util.Map;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import com.baeldung.jackson.objectmapper.dto.Car;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import java.util.List;
import java.util.Map;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
public class JavaReadWriteJsonExampleUnitTest {
@Rule
public TemporaryFolder folder = new TemporaryFolder();
final String EXAMPLE_JSON = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }";
final String LOCAL_JSON = "[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"BMW\" }]";
@@ -27,6 +36,19 @@ public class JavaReadWriteJsonExampleUnitTest {
assertThat(carAsString, containsString("renault"));
}
@Test
public void whenWriteToFile_thanCorrect() throws Exception {
File resultFile = folder.newFile("car.json");
ObjectMapper objectMapper = new ObjectMapper();
Car car = new Car("yellow", "renault");
objectMapper.writeValue(resultFile, car);
Car fromFile = objectMapper.readValue(resultFile, Car.class);
assertEquals(car.getType(), fromFile.getType());
assertEquals(car.getColor(), fromFile.getColor());
}
@Test
public void whenReadJsonToJava_thanCorrect() throws Exception {
final ObjectMapper objectMapper = new ObjectMapper();
@@ -66,4 +88,26 @@ public class JavaReadWriteJsonExampleUnitTest {
assertNotNull(key);
}
}
@Test
public void wheReadFromFile_thanCorrect() throws Exception {
File resource = new File("src/test/resources/json_car.json");
ObjectMapper objectMapper = new ObjectMapper();
Car fromFile = objectMapper.readValue(resource, Car.class);
assertEquals("BMW", fromFile.getType());
assertEquals("Black", fromFile.getColor());
}
@Test
public void wheReadFromUrl_thanCorrect() throws Exception {
URL resource = new URL("file:src/test/resources/json_car.json");
ObjectMapper objectMapper = new ObjectMapper();
Car fromFile = objectMapper.readValue(resource, Car.class);
assertEquals("BMW", fromFile.getType());
assertEquals("Black", fromFile.getColor());
}
}

View File

@@ -1,13 +0,0 @@
*.class
#folders#
/target
/neoDb*
/data
/src/main/webapp/WEB-INF/classes
*/META-INF/*
# Packaged files #
*.jar
*.war
*.ear

View File

@@ -0,0 +1,4 @@
{
"color": "Black",
"type": "BMW"
}

View File

@@ -0,0 +1,15 @@
package com.baeldung.jackson.deserialization.enums;
public class City {
private Distance distance;
public Distance getDistance() {
return distance;
}
public void setDistance(Distance distance) {
this.distance = distance;
}
}

View File

@@ -0,0 +1,31 @@
package com.baeldung.jackson.deserialization.enums;
public enum Distance {
KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001);
private String unit;
private double meters;
private Distance(String unit, double meters) {
this.unit = unit;
this.meters = meters;
}
public void setMeters(double meters) {
this.meters = meters;
}
public double getMeters() {
return meters;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
}

View File

@@ -0,0 +1,15 @@
package com.baeldung.jackson.deserialization.enums.customdeserializer;
public class City {
private Distance distance;
public Distance getDistance() {
return distance;
}
public void setDistance(Distance distance) {
this.distance = distance;
}
}

View File

@@ -0,0 +1,42 @@
package com.baeldung.jackson.deserialization.enums.customdeserializer;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
public class CustomEnumDeserializer extends StdDeserializer<Distance> {
private static final long serialVersionUID = -1166032307856492833L;
public CustomEnumDeserializer() {
this(null);
}
public CustomEnumDeserializer(Class<?> c) {
super(c);
}
@Override
public Distance deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonNode node = jsonParser.getCodec().readTree(jsonParser);
String unit = node.get("unit").asText();
double meters = node.get("meters").asDouble();
for (Distance distance : Distance.values()) {
if (distance.getUnit().equals(unit) &&
Double.compare(distance.getMeters(), meters) == 0) {
return distance;
}
}
return null;
}
}

View File

@@ -0,0 +1,33 @@
package com.baeldung.jackson.deserialization.enums.customdeserializer;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
@JsonDeserialize(using = CustomEnumDeserializer.class)
public enum Distance {
KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001);
private String unit;
private double meters;
private Distance(String unit, double meters) {
this.unit = unit;
this.meters = meters;
}
public double getMeters() {
return meters;
}
public void setMeters(double meters) {
this.meters = meters;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
}

View File

@@ -0,0 +1,15 @@
package com.baeldung.jackson.deserialization.enums.jsoncreator;
public class City {
private Distance distance;
public Distance getDistance() {
return distance;
}
public void setDistance(Distance distance) {
this.distance = distance;
}
}

View File

@@ -0,0 +1,48 @@
package com.baeldung.jackson.deserialization.enums.jsoncreator;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public enum Distance {
KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001);
private String unit;
private double meters;
private Distance(String unit, double meters) {
this.unit = unit;
this.meters = meters;
}
public void setMeters(double meters) {
this.meters = meters;
}
public double getMeters() {
return meters;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
@JsonCreator
public static Distance forValues(@JsonProperty("unit") String unit, @JsonProperty("meters") double meters) {
for (Distance distance : Distance.values()) {
if (distance.unit.equals(unit) && Double.compare(distance.meters, meters) == 0) {
return distance;
}
}
return null;
}
}

View File

@@ -0,0 +1,15 @@
package com.baeldung.jackson.deserialization.enums.jsonproperty;
public class City {
private Distance distance;
public Distance getDistance() {
return distance;
}
public void setDistance(Distance distance) {
this.distance = distance;
}
}

View File

@@ -0,0 +1,51 @@
package com.baeldung.jackson.deserialization.enums.jsonproperty;
import com.fasterxml.jackson.annotation.JsonProperty;
public enum Distance {
@JsonProperty("distance-in-km")
KILOMETER("km", 1000),
@JsonProperty("distance-in-miles")
MILE("miles", 1609.34),
@JsonProperty("distance-in-meters")
METER("meters", 1),
@JsonProperty("distance-in-inches")
INCH("inches", 0.0254),
@JsonProperty("distance-in-cm")
CENTIMETER("cm", 0.01),
@JsonProperty("distance-in-mm")
MILLIMETER("mm", 0.001);
private String unit;
private double meters;
private Distance(String unit, double meters) {
this.unit = unit;
this.meters = meters;
}
public void setMeters(double meters) {
this.meters = meters;
}
public double getMeters() {
return meters;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
}

View File

@@ -0,0 +1,15 @@
package com.baeldung.jackson.deserialization.enums.jsonvalue;
public class City {
private Distance distance;
public Distance getDistance() {
return distance;
}
public void setDistance(Distance distance) {
this.distance = distance;
}
}

View File

@@ -0,0 +1,35 @@
package com.baeldung.jackson.deserialization.enums.jsonvalue;
import com.fasterxml.jackson.annotation.JsonValue;
public enum Distance {
KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001);
private String unit;
private double meters;
private Distance(String unit, double meters) {
this.unit = unit;
this.meters = meters;
}
public void setMeters(double meters) {
this.meters = meters;
}
@JsonValue
public double getMeters() {
return meters;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
}

View File

@@ -0,0 +1,19 @@
package com.baeldung.jackson.deserialization.enums;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.IOException;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class DefaultEnumDeserializationUnitTest {
@Test
public void givenEnum_whenDeserializingJson_thenCorrectRepresentation() throws JsonParseException, IOException {
String json = "{\"distance\":\"KILOMETER\"}";
City city = new ObjectMapper().readValue(json, City.class);
assertEquals(Distance.KILOMETER, city.getDistance());
}
}

View File

@@ -0,0 +1,18 @@
package com.baeldung.jackson.deserialization.enums.customdeserializer;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.IOException;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class EnumCustomDeserializationUnitTest {
@Test
public void givenEnumWithCustomDeserializer_whenDeserializingJson_thenCorrectRepresentation() throws JsonParseException, IOException {
String json = "{\"distance\": {\"unit\":\"miles\",\"meters\":1609.34}}";
City city = new ObjectMapper().readValue(json, City.class);
assertEquals(Distance.MILE, city.getDistance());
}
}

View File

@@ -0,0 +1,19 @@
package com.baeldung.jackson.deserialization.enums.jsoncreator;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.IOException;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class EnumDeserializationUsingJsonCreatorUnitTest {
@Test
public void givenEnumWithJsonCreator_whenDeserializingJson_thenCorrectRepresentation() throws JsonParseException, IOException {
String json = "{\"distance\": {\"unit\":\"miles\",\"meters\":1609.34}}";
City city = new ObjectMapper().readValue(json, City.class);
assertEquals(Distance.MILE, city.getDistance());
}
}

View File

@@ -0,0 +1,20 @@
package com.baeldung.jackson.deserialization.enums.jsonproperty;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.IOException;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class EnumDeserializationUsingJsonPropertyUnitTest {
@Test
public void givenEnumWithJsonProperty_whenDeserializingJson_thenCorrectRepresentation() throws JsonParseException, IOException {
String json = "{\"distance\": \"distance-in-km\"}";
City city = new ObjectMapper().readValue(json, City.class);
assertEquals(Distance.KILOMETER, city.getDistance());
}
}

View File

@@ -0,0 +1,19 @@
package com.baeldung.jackson.deserialization.enums.jsonvalue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.IOException;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class EnumDeserializationUsingJsonValueUnitTest {
@Test
public void givenEnumWithJsonValue_whenDeserializingJson_thenCorrectRepresentation() throws JsonParseException, IOException {
String json = "{\"distance\": \"0.0254\"}";
City city = new ObjectMapper().readValue(json, City.class);
assertEquals(Distance.INCH, city.getDistance());
}
}

View File

@@ -2,11 +2,8 @@ package com.baeldung.jackson.enums;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertThat;
import java.io.IOException;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -18,5 +15,5 @@ public class JacksonEnumSerializationUnitTest {
assertThat(dtoAsString, containsString("1609.34"));
}
}

View File

@@ -0,0 +1,21 @@
package com.baeldung.datetime;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Locale;
public class UseDateTimeFormatter {
public String formatAsIsoDate(LocalDateTime localDateTime) {
return localDateTime.format(DateTimeFormatter.ISO_DATE);
}
public String formatCustom(LocalDateTime localDateTime, String pattern) {
return localDateTime.format(DateTimeFormatter.ofPattern(pattern));
}
public String formatWithStyleAndLocale(LocalDateTime localDateTime, FormatStyle formatStyle, Locale locale) {
return localDateTime.format(DateTimeFormatter.ofLocalizedDateTime(formatStyle)
.withLocale(locale));
}
}

View File

@@ -0,0 +1,11 @@
package com.baeldung.datetime;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
public class UseOffsetDateTime {
public OffsetDateTime offsetOfLocalDateTimeAndOffset(LocalDateTime localDateTime, ZoneOffset offset) {
return OffsetDateTime.of(localDateTime, offset);
}
}

View File

@@ -0,0 +1,36 @@
package com.baeldung.datetime;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.format.FormatStyle;
import java.util.Locale;
import org.junit.Test;
public class UseDateTimeFormatterUnitTest {
private final UseDateTimeFormatter subject = new UseDateTimeFormatter();
private final LocalDateTime localDateTime = LocalDateTime.of(2015, Month.JANUARY, 25, 6, 30);
@Test
public void givenALocalDate_whenFormattingAsIso_thenPass() {
String result = subject.formatAsIsoDate(localDateTime);
assertThat(result).isEqualTo("2015-01-25");
}
@Test
public void givenALocalDate_whenFormattingWithPattern_thenPass() {
String result = subject.formatCustom(localDateTime, "yyyy/MM/dd");
assertThat(result).isEqualTo("2015/01/25");
}
@Test
public void givenALocalDate_whenFormattingWithStyleAndLocale_thenPass() {
String result = subject.formatWithStyleAndLocale(localDateTime, FormatStyle.MEDIUM, Locale.UK);
assertThat(result).isEqualTo("25 Jan 2015, 06:30:00");
}
}

View File

@@ -0,0 +1,24 @@
package com.baeldung.datetime;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import org.junit.Test;
public class UseOffsetDateTimeUnitTest {
private final UseOffsetDateTime subject = new UseOffsetDateTime();
@Test
public void givenAZoneOffSetAndLocalDateTime_whenCombing_thenValidResult() {
ZoneOffset offset = ZoneOffset.of("+02:00");
LocalDateTime localDateTime = LocalDateTime.of(2015, Month.FEBRUARY, 20, 6, 30);
OffsetDateTime result = subject.offsetOfLocalDateTimeAndOffset(localDateTime, offset);
assertThat(result.toString()).isEqualTo("2015-02-20T06:30+02:00");
}
}

View File

@@ -0,0 +1,33 @@
package com.baeldung.datetime;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.LocalDateTime;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import org.junit.Test;
public class UseToInstantUnitTest {
private UseToInstant subject = new UseToInstant();
@Test
public void givenAGregorianCalenderDate_whenConvertingToLocalDate_thenAsExpected() {
GregorianCalendar givenCalender = new GregorianCalendar(2018, Calendar.JULY, 28);
LocalDateTime localDateTime = subject.convertDateToLocalDate(givenCalender);
assertThat(localDateTime).isEqualTo("2018-07-28T00:00:00");
}
@Test
public void givenADate_whenConvertingToLocalDate_thenAsExpected() {
Date givenDate = new Date(1465817690000L);
LocalDateTime localDateTime = subject.convertDateToLocalDate(givenDate);
assertThat(localDateTime).isEqualTo("2016-06-13T13:34:50");
}
}

View File

@@ -0,0 +1,51 @@
package com.baeldung.prototype;
public final class Position {
private final int x;
private final int y;
public Position(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Position other = (Position) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
@Override
public String toString() {
return "Position [x=" + x + ", y=" + y + "]";
}
}

View File

@@ -0,0 +1,54 @@
package com.baeldung.prototype;
public class Tree implements Cloneable {
private double mass;
private double height;
private Position position;
public Tree(double mass, double height) {
this.mass = mass;
this.height = height;
}
public void setMass(double mass) {
this.mass = mass;
}
public void setHeight(double height) {
this.height = height;
}
public void setPosition(Position position) {
this.position = position;
}
public double getMass() {
return mass;
}
public double getHeight() {
return height;
}
public Position getPosition() {
return position;
}
@Override
public Tree clone() {
Tree tree = null;
try {
tree = (Tree) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return tree;
}
@Override
public String toString() {
return "Tree [mass=" + mass + ", height=" + height + ", position=" + position + "]";
}
}

View File

@@ -0,0 +1,24 @@
package com.baeldung.prototype;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
public class TreePrototypeUnitTest {
@Test
public void givenATreePrototypeWhenClonedThenCreateA_Clone() {
double mass = 10.0;
double height = 3.7;
Position position = new Position(3, 7);
Position otherPosition = new Position(4, 8);
Tree tree = new Tree(mass, height);
tree.setPosition(position);
Tree anotherTree = tree.clone();
anotherTree.setPosition(otherPosition);
assertEquals(position, tree.getPosition());
assertEquals(otherPosition, anotherTree.getPosition());
}
}

View File

@@ -0,0 +1,37 @@
<?xml version="1.0"?>
<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>
<groupId>com.baeldung</groupId>
<artifactId>hibernate5-2</artifactId>
<version>0.1-SNAPSHOT</version>
<name>hibernate5-2</name>
<packaging>jar</packaging>
<description>Hibernate tutorial illustrating the use of named parameters</description>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.7.Final</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.200</version>
</dependency>
</dependencies>
<properties>
<maven.deploy.skip>true</maven.deploy.skip>
</properties>
</project>

View File

@@ -0,0 +1,30 @@
package com.baeldung.hibernateparameters;
public class Event {
private Long id;
private String title;
public Event() {
}
public Event(String title) {
this.title = title;
}
public Long getId() {
return id;
}
private void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}

View File

@@ -0,0 +1,15 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.baeldung.hibernateparameters">
<class name="Event" table="EVENTS">
<id name="id" column="EVENT_ID">
<generator class="increment"/>
</id>
<property name="title"/>
</class>
</hibernate-mapping>

View File

@@ -0,0 +1,28 @@
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">org.h2.Driver</property>
<property name="connection.url">jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1</property>
<property name="connection.username">sa</property>
<property name="connection.password"/>
<property name="connection.pool_size">1</property>
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">create</property>
<mapping resource="com/baeldung/hibernateparameters/Event.hbm.xml"/>
</session-factory>
</hibernate-configuration>

View File

@@ -0,0 +1,73 @@
package com.baeldung.hibernateparameters;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.query.Query;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
public class NamedParameterUnitTest {
private SessionFactory sessionFactory;
@Before
public void setUp() throws Exception {
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.configure()
.build();
try {
sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(new Event("Event 1"));
session.save(new Event("Event 2"));
session.getTransaction().commit();
session.close();
} catch (Exception e) {
fail(e);
StandardServiceRegistryBuilder.destroy(registry);
}
}
@After
public void tearDown() throws Exception {
if (sessionFactory != null) {
sessionFactory.close();
}
}
@Test
public void whenNamedParameterProvided_thenCorrect() {
Session session = sessionFactory.openSession();
session.beginTransaction();
Query<Event> query = session.createQuery("from Event E WHERE E.title = :eventTitle", Event.class);
// This binds the value "Event1" to the parameter :eventTitle
query.setParameter("eventTitle", "Event 1");
assertEquals(1, query.list().size());
session.getTransaction().commit();
session.close();
}
@Test(expected = org.hibernate.QueryException.class)
public void whenNamedParameterMissing_thenThrowsQueryException() {
Session session = sessionFactory.openSession();
session.beginTransaction();
Query<Event> query = session.createQuery("from Event E WHERE E.title = :eventTitle", Event.class);
try {
query.list();
fail("We are expecting an exception!");
} finally {
session.getTransaction().commit();
session.close();
}
}
}

View File

@@ -1,5 +1,4 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<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-jpa-2</artifactId>
@@ -49,6 +48,13 @@
<version>${postgres.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@@ -108,6 +114,7 @@
<eclipselink.version>2.7.4-RC1</eclipselink.version>
<postgres.version>42.2.5</postgres.version>
<javax.persistence-api.version>2.2</javax.persistence-api.version>
<assertj.version>3.11.1</assertj.version>
</properties>
</project>

View File

@@ -0,0 +1,73 @@
package com.baeldung.jpa.multipletables.multipleentities;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import com.baeldung.jpa.multipletables.secondarytable.MealAsSingleEntity;
@Entity
@Table(name = "allergens")
public class AllergensAsEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "meal_id")
private Long mealId;
@OneToOne
@PrimaryKeyJoinColumn(name = "meal_id")
private MealAsSingleEntity meal;
@Column(name = "peanuts")
private boolean peanuts;
@Column(name = "celery")
private boolean celery;
@Column(name = "sesame_seeds")
private boolean sesameSeeds;
public MealAsSingleEntity getMeal() {
return meal;
}
public void setMeal(MealAsSingleEntity meal) {
this.meal = meal;
}
public boolean isPeanuts() {
return peanuts;
}
public void setPeanuts(boolean peanuts) {
this.peanuts = peanuts;
}
public boolean isCelery() {
return celery;
}
public void setCelery(boolean celery) {
this.celery = celery;
}
public boolean isSesameSeeds() {
return sesameSeeds;
}
public void setSesameSeeds(boolean sesameSeeds) {
this.sesameSeeds = sesameSeeds;
}
@Override
public String toString() {
return "AllergensAsEntity [peanuts=" + peanuts + ", celery=" + celery + ", sesameSeeds=" + sesameSeeds + "]";
}
}

View File

@@ -0,0 +1,75 @@
package com.baeldung.jpa.multipletables.multipleentities;
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table(name = "meal")
public class MealWithMultipleEntities {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@Column(name = "description")
private String description;
@Column(name = "price")
private BigDecimal price;
@OneToOne(mappedBy = "meal")
private AllergensAsEntity allergens;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public AllergensAsEntity getAllergens() {
return allergens;
}
public void setAllergens(AllergensAsEntity allergens) {
this.allergens = allergens;
}
public Long getId() {
return id;
}
@Override
public String toString() {
return "MealWithMultipleEntities [id=" + id + ", name=" + name + ", description=" + description + ", price=" + price + ", allergens=" + allergens + "]";
}
}

View File

@@ -0,0 +1,99 @@
package com.baeldung.jpa.multipletables.secondarytable;
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.SecondaryTable;
import javax.persistence.Table;
@Entity
@Table(name = "meal")
@SecondaryTable(name = "allergens", pkJoinColumns = @PrimaryKeyJoinColumn(name = "meal_id"))
public class MealAsSingleEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@Column(name = "description")
private String description;
@Column(name = "price")
private BigDecimal price;
@Column(name = "peanuts", table = "allergens")
private boolean peanuts;
@Column(name = "celery", table = "allergens")
private boolean celery;
@Column(name = "sesame_seeds", table = "allergens")
private boolean sesameSeeds;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public boolean isPeanuts() {
return peanuts;
}
public void setPeanuts(boolean peanuts) {
this.peanuts = peanuts;
}
public boolean isCelery() {
return celery;
}
public void setCelery(boolean celery) {
this.celery = celery;
}
public boolean isSesameSeeds() {
return sesameSeeds;
}
public void setSesameSeeds(boolean sesameSeeds) {
this.sesameSeeds = sesameSeeds;
}
public Long getId() {
return id;
}
@Override
public String toString() {
return "MealAsSingleEntity [id=" + id + ", name=" + name + ", description=" + description + ", price=" + price + ", peanuts=" + peanuts + ", celery=" + celery + ", sesameSeeds=" + sesameSeeds + "]";
}
}

View File

@@ -0,0 +1,47 @@
package com.baeldung.jpa.multipletables.secondarytable.embeddable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
@Embeddable
public class AllergensAsEmbeddable {
@Column(name = "peanuts", table = "allergens")
private boolean peanuts;
@Column(name = "celery", table = "allergens")
private boolean celery;
@Column(name = "sesame_seeds", table = "allergens")
private boolean sesameSeeds;
public boolean isPeanuts() {
return peanuts;
}
public void setPeanuts(boolean peanuts) {
this.peanuts = peanuts;
}
public boolean isCelery() {
return celery;
}
public void setCelery(boolean celery) {
this.celery = celery;
}
public boolean isSesameSeeds() {
return sesameSeeds;
}
public void setSesameSeeds(boolean sesameSeeds) {
this.sesameSeeds = sesameSeeds;
}
@Override
public String toString() {
return "AllergensAsEmbeddable [peanuts=" + peanuts + ", celery=" + celery + ", sesameSeeds=" + sesameSeeds + "]";
}
}

View File

@@ -0,0 +1,78 @@
package com.baeldung.jpa.multipletables.secondarytable.embeddable;
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.SecondaryTable;
import javax.persistence.Table;
@Entity
@Table(name = "meal")
@SecondaryTable(name = "allergens", pkJoinColumns = @PrimaryKeyJoinColumn(name = "meal_id"))
public class MealWithEmbeddedAllergens {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@Column(name = "description")
private String description;
@Column(name = "price")
private BigDecimal price;
@Embedded
private AllergensAsEmbeddable allergens;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public AllergensAsEmbeddable getAllergens() {
return allergens;
}
public void setAllergens(AllergensAsEmbeddable allergens) {
this.allergens = allergens;
}
public Long getId() {
return id;
}
@Override
public String toString() {
return "MealWithEmbeddedAllergens [id=" + id + ", name=" + name + ", description=" + description + ", price=" + price + ", allergens=" + allergens + "]";
}
}

View File

@@ -135,4 +135,32 @@
</properties>
</persistence-unit>
<persistence-unit name="jpa-h2-multipltables">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.baeldung.jpa.multipletables.multipleentities.MealWithMultipleEntities</class>
<class>com.baeldung.jpa.multipletables.multipleentities.AllergensAsEntity</class>
<class>com.baeldung.jpa.multipletables.secondarytable.MealAsSingleEntity</class>
<class>com.baeldung.jpa.multipletables.secondarytable.embeddable.MealWithEmbeddedAllergens</class>
<class>com.baeldung.jpa.multipletables.secondarytable.embeddable.AllergensAsEmbeddable</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver"
value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:h2:mem:test" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="hibernate.dialect"
value="org.hibernate.dialect.H2Dialect" />
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.hbm2ddl.import_files" value="multipletables.sql" />
<property name="show_sql" value="true" />
<property name="hibernate.temp.use_jdbc_metadata_defaults"
value="false" />
</properties>
</persistence-unit>
</persistence>

View File

@@ -0,0 +1,79 @@
package com.baeldung.jpa.multipletables;
import static org.assertj.core.api.Assertions.*;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import com.baeldung.jpa.multipletables.multipleentities.MealWithMultipleEntities;
import com.baeldung.jpa.multipletables.secondarytable.MealAsSingleEntity;
import com.baeldung.jpa.multipletables.secondarytable.embeddable.MealWithEmbeddedAllergens;
public class MultipleTablesIntegrationTest {
private static EntityManagerFactory emf;
private static EntityManager em;
@BeforeClass
public static void setup() {
emf = Persistence.createEntityManagerFactory("jpa-h2-multipltables");
em = emf.createEntityManager();
}
@Test
public void entityManager_shouldLoadMealAsSingleEntity() {
// given
// when
MealAsSingleEntity meal = em.find(MealAsSingleEntity.class, 1L);
// then
assertThat(meal).isNotNull();
assertThat(meal.getId()).isEqualTo(1L);
assertThat(meal.isPeanuts()).isFalse();
assertThat(meal.isCelery()).isTrue();
}
@Test
public void entityManager_shouldLoadMealWithEmbeddedAllergens() {
// given
// when
MealWithEmbeddedAllergens meal = em.find(MealWithEmbeddedAllergens.class, 1L);
// then
assertThat(meal).isNotNull();
assertThat(meal.getId()).isEqualTo(1L);
assertThat(meal.getAllergens()).isNotNull();
assertThat(meal.getAllergens().isPeanuts()).isFalse();
assertThat(meal.getAllergens().isCelery()).isTrue();
}
@Test
public void entityManager_shouldLoadMealWithAllergensEntity() {
// given
// when
MealWithMultipleEntities meal = em.find(MealWithMultipleEntities.class, 1L);
// then
assertThat(meal).isNotNull();
assertThat(meal.getId()).isEqualTo(1L);
assertThat(meal.getAllergens()).isNotNull();
assertThat(meal.getAllergens().isPeanuts()).isFalse();
assertThat(meal.getAllergens().isCelery()).isTrue();
}
@AfterClass
public static void teardown() {
if (emf != null) {
emf.close();
}
}
}

View File

@@ -0,0 +1,8 @@
drop table if exists allergens;
drop table if exists meal;
create table meal (id bigint auto_increment, name varchar(255) not null, description varchar(255) not null, price decimal(19, 2) not null, primary key (id));
create table allergens (meal_id bigint auto_increment, peanuts number(1) not null, celery number(1) not null, sesame_seeds number(1) not null, primary key (meal_id));
insert into meal (id, name, description, price) values (1, 'Pizza', 'Delicious', 5);
insert into allergens (meal_id, peanuts, celery, sesame_seeds) values (1, 0, 1, 0);

View File

@@ -23,7 +23,7 @@
<module>hibernate5</module>
<module>hibernate-ogm</module>
<module>hibernate-mapping</module>
<module>hibernate-parameters</module>
<module>hibernate5-2</module>
<module>influxdb</module>
<module>java-cassandra</module>
<module>java-cockroachdb</module>
@@ -49,6 +49,7 @@
<module>spring-data-elasticsearch</module>
<module>spring-data-gemfire</module>
<module>spring-data-jpa</module>
<module>spring-data-jpa-3</module>
<module>spring-data-keyvalue</module>
<module>spring-data-mongodb</module> <!-- long -->
<module>spring-data-neo4j</module>
@@ -60,7 +61,7 @@
<module>spring-jpa</module>
<module>spring-persistence-simple</module>
<module>jpa-hibernate-cascade-type</module>
<module>r2dbc</module>
<module>r2dbc</module>
<module>spring-boot-jdbi</module>
</modules>
</project>

View File

@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<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>spring-data-jpa-3</artifactId>
<name>spring-data-jpa-3</name>
<parent>
<artifactId>parent-boot-2</artifactId>
<groupId>com.baeldung</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-2</relativePath>
</parent>
<dependencies>
<!-- Prod Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
</dependency>
<!-- Test Dependencies -->
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${testcontainers.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<version>${testcontainers.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>${junit-platform.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<testcontainers.version>1.12.2</testcontainers.version>
<postgresql.version>42.2.8</postgresql.version>
</properties>
</project>

View File

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

View File

@@ -0,0 +1,55 @@
package com.baeldung.tx;
import javax.persistence.*;
@Entity
public class Payment {
@Id
@GeneratedValue
private Long id;
private Long amount;
@Column(unique = true)
private String referenceNumber;
@Enumerated(EnumType.STRING)
private State state;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getAmount() {
return amount;
}
public void setAmount(Long amount) {
this.amount = amount;
}
public String getReferenceNumber() {
return referenceNumber;
}
public void setReferenceNumber(String referenceNumber) {
this.referenceNumber = referenceNumber;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public enum State {
STARTED, FAILED, SUCCESSFUL
}
}

View File

@@ -0,0 +1,171 @@
package com.baeldung.tx;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import javax.persistence.EntityManager;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace.NONE;
import static org.springframework.transaction.annotation.Propagation.NOT_SUPPORTED;
@DataJpaTest
@Testcontainers
@ActiveProfiles("test")
@AutoConfigureTestDatabase(replace = NONE)
@Transactional(propagation = NOT_SUPPORTED)
class ManualTransactionIntegrationTest {
@Container
private static PostgreSQLContainer<?> pg = initPostgres();
@Autowired
private PlatformTransactionManager transactionManager;
@Autowired
private EntityManager entityManager;
private TransactionTemplate transactionTemplate;
@BeforeEach
void setUp() {
transactionTemplate = new TransactionTemplate(transactionManager);
}
@AfterEach
void flushDb() {
transactionTemplate.execute(status -> entityManager
.createQuery("delete from Payment")
.executeUpdate());
}
@Test
void givenAPayment_WhenNotDuplicate_ThenShouldCommit() {
Long id = transactionTemplate.execute(status -> {
Payment payment = new Payment();
payment.setAmount(1000L);
payment.setReferenceNumber("Ref-1");
payment.setState(Payment.State.SUCCESSFUL);
entityManager.persist(payment);
return payment.getId();
});
Payment payment = entityManager.find(Payment.class, id);
assertThat(payment).isNotNull();
}
@Test
void givenAPayment_WhenMarkAsRollback_ThenShouldRollback() {
transactionTemplate.execute(status -> {
Payment payment = new Payment();
payment.setAmount(1000L);
payment.setReferenceNumber("Ref-1");
payment.setState(Payment.State.SUCCESSFUL);
entityManager.persist(payment);
status.setRollbackOnly();
return payment.getId();
});
assertThat(entityManager
.createQuery("select p from Payment p")
.getResultList()).isEmpty();
}
@Test
void givenTwoPayments_WhenRefIsDuplicate_ThenShouldRollback() {
try {
transactionTemplate.execute(s -> {
Payment first = new Payment();
first.setAmount(1000L);
first.setReferenceNumber("Ref-1");
first.setState(Payment.State.SUCCESSFUL);
Payment second = new Payment();
second.setAmount(2000L);
second.setReferenceNumber("Ref-1");
second.setState(Payment.State.SUCCESSFUL);
entityManager.persist(first);
entityManager.persist(second);
return "Ref-1";
});
} catch (Exception ignored) {
}
assertThat(entityManager
.createQuery("select p from Payment p")
.getResultList()).isEmpty();
}
@Test
void givenAPayment_WhenNotExpectingAnyResult_ThenShouldCommit() {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
Payment payment = new Payment();
payment.setReferenceNumber("Ref-1");
payment.setState(Payment.State.SUCCESSFUL);
entityManager.persist(payment);
}
});
assertThat(entityManager
.createQuery("select p from Payment p")
.getResultList()).hasSize(1);
}
@Test
void givenAPayment_WhenUsingTxManager_ThenShouldCommit() {
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
definition.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ);
definition.setTimeout(3);
TransactionStatus status = transactionManager.getTransaction(definition);
try {
Payment payment = new Payment();
payment.setReferenceNumber("Ref-1");
payment.setState(Payment.State.SUCCESSFUL);
entityManager.persist(payment);
transactionManager.commit(status);
} catch (Exception ex) {
transactionManager.rollback(status);
}
assertThat(entityManager
.createQuery("select p from Payment p")
.getResultList()).hasSize(1);
}
private static PostgreSQLContainer<?> initPostgres() {
PostgreSQLContainer<?> pg = new PostgreSQLContainer<>("postgres:11.1")
.withDatabaseName("baeldung")
.withUsername("test")
.withPassword("test");
pg.setPortBindings(singletonList("54320:5432"));
return pg;
}
}

View File

@@ -0,0 +1,4 @@
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:postgresql://localhost:54320/baeldung
spring.datasource.username=test
spring.datasource.password=test

View File

@@ -0,0 +1,250 @@
package com.baeldung.persistence.service.transactional;
import com.baeldung.persistence.model.Foo;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import org.springframework.transaction.IllegalTransactionStateException;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { PersistenceTransactionalTestConfig.class }, loader = AnnotationConfigContextLoader.class)
@DirtiesContext
public class FooTransactionalUnitTest {
static abstract class BasicFooDao {
@PersistenceContext private EntityManager entityManager;
public Foo findOne(final long id) {
return entityManager.find(Foo.class, id);
}
public Foo create(final Foo entity) {
entityManager.persist(entity);
return entity;
}
}
@Repository
static class RequiredTransactionalFooDao extends BasicFooDao {
@Override
@Transactional(propagation = Propagation.REQUIRED)
public Foo create(Foo entity) {
return super.create(entity);
}
}
@Repository
static class RequiresNewTransactionalFooDao extends BasicFooDao {
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public Foo create(Foo entity) {
return super.create(entity);
}
}
@Repository
static class SupportTransactionalFooDao extends BasicFooDao {
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public Foo create(Foo entity) {
return super.create(entity);
}
}
@Repository
static class MandatoryTransactionalFooDao extends BasicFooDao {
@Override
@Transactional(propagation = Propagation.MANDATORY)
public Foo create(Foo entity) {
return super.create(entity);
}
}
@Repository
static class SupportTransactionalFooService {
@Transactional(propagation = Propagation.SUPPORTS)
public Foo identity(Foo entity) {
return entity;
}
}
@Service
static class MandatoryTransactionalFooService {
@Transactional(propagation = Propagation.MANDATORY)
public Foo identity(Foo entity) {
return entity;
}
}
@Service
static class NotSupportedTransactionalFooService {
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public Foo identity(Foo entity) {
return entity;
}
}
@Service
static class NeverTransactionalFooService {
@Transactional(propagation = Propagation.NEVER)
public Foo identity(Foo entity) {
return entity;
}
}
@Autowired private TransactionTemplate transactionTemplate;
@Autowired private RequiredTransactionalFooDao requiredTransactionalFooDao;
@Autowired private RequiresNewTransactionalFooDao requiresNewTransactionalFooDao;
@Autowired private SupportTransactionalFooDao supportTransactionalFooDao;
@Autowired private MandatoryTransactionalFooDao mandatoryTransactionalFooDao;
@Autowired private MandatoryTransactionalFooService mandatoryTransactionalFooService;
@Autowired private NeverTransactionalFooService neverTransactionalFooService;
@Autowired private NotSupportedTransactionalFooService notSupportedTransactionalFooService;
@Autowired private SupportTransactionalFooService supportTransactionalFooService;
@After
public void tearDown(){
PersistenceTransactionalTestConfig.clearSpy();
}
@Test
public void givenRequiredWithNoActiveTransaction_whenCallCreate_thenExpect1NewAnd0Suspend() {
requiredTransactionalFooDao.create(new Foo("baeldung"));
PersistenceTransactionalTestConfig.TransactionSynchronizationAdapterSpy transactionSpy = PersistenceTransactionalTestConfig.getSpy();
Assert.assertEquals(0, transactionSpy.getSuspend());
Assert.assertEquals(1, transactionSpy.getCreate());
}
@Test
public void givenRequiresNewWithNoActiveTransaction_whenCallCreate_thenExpect1NewAnd0Suspend() {
requiresNewTransactionalFooDao.create(new Foo("baeldung"));
PersistenceTransactionalTestConfig.TransactionSynchronizationAdapterSpy transactionSpy = PersistenceTransactionalTestConfig.getSpy();
Assert.assertEquals(0, transactionSpy.getSuspend());
Assert.assertEquals(1, transactionSpy.getCreate());
}
@Test
public void givenSupportWithNoActiveTransaction_whenCallService_thenExpect0NewAnd0Suspend() {
supportTransactionalFooService.identity(new Foo("baeldung"));
PersistenceTransactionalTestConfig.TransactionSynchronizationAdapterSpy transactionSpy = PersistenceTransactionalTestConfig.getSpy();
Assert.assertEquals(0, transactionSpy.getSuspend());
Assert.assertEquals(0, transactionSpy.getCreate());
}
@Test(expected = IllegalTransactionStateException.class)
public void givenMandatoryWithNoActiveTransaction_whenCallService_thenExpectIllegalTransactionStateExceptionWith0NewAnd0Suspend() {
mandatoryTransactionalFooService.identity(new Foo("baeldung"));
PersistenceTransactionalTestConfig.TransactionSynchronizationAdapterSpy transactionSpy = PersistenceTransactionalTestConfig.getSpy();
Assert.assertEquals(0, transactionSpy.getSuspend());
Assert.assertEquals(0, transactionSpy.getCreate());
}
@Test
public void givenNotSupportWithNoActiveTransaction_whenCallService_thenExpect0NewAnd0Suspend() {
notSupportedTransactionalFooService.identity(new Foo("baeldung"));
PersistenceTransactionalTestConfig.TransactionSynchronizationAdapterSpy transactionSpy = PersistenceTransactionalTestConfig.getSpy();
Assert.assertEquals(0, transactionSpy.getSuspend());
Assert.assertEquals(0, transactionSpy.getCreate());
}
@Test
public void givenNeverWithNoActiveTransaction_whenCallService_thenExpect0NewAnd0Suspend() {
neverTransactionalFooService.identity(new Foo("baeldung"));
PersistenceTransactionalTestConfig.TransactionSynchronizationAdapterSpy transactionSpy = PersistenceTransactionalTestConfig.getSpy();
Assert.assertEquals(0, transactionSpy.getSuspend());
Assert.assertEquals(0, transactionSpy.getCreate());
}
@Test
public void givenRequiredWithActiveTransaction_whenCallCreate_thenExpect0NewAnd0Suspend() {
transactionTemplate.execute(status -> {
Foo foo = new Foo("baeldung");
return requiredTransactionalFooDao.create(foo);
});
PersistenceTransactionalTestConfig.TransactionSynchronizationAdapterSpy transactionSpy = PersistenceTransactionalTestConfig.getSpy();
Assert.assertEquals(0, transactionSpy.getSuspend());
Assert.assertEquals(1, transactionSpy.getCreate());
}
@Test
public void givenRequiresNewWithActiveTransaction_whenCallCreate_thenExpect1NewAnd1Suspend() {
transactionTemplate.execute(status -> {
Foo foo = new Foo("baeldung");
return requiresNewTransactionalFooDao.create(foo);
});
PersistenceTransactionalTestConfig.TransactionSynchronizationAdapterSpy transactionSpy = PersistenceTransactionalTestConfig.getSpy();
Assert.assertEquals(1, transactionSpy.getSuspend());
Assert.assertEquals(2, transactionSpy.getCreate());
}
@Test
public void givenSupportWithActiveTransaction_whenCallCreate_thenExpect0NewAnd0Suspend() {
transactionTemplate.execute(status -> {
Foo foo = new Foo("baeldung");
return supportTransactionalFooDao.create(foo);
});
PersistenceTransactionalTestConfig.TransactionSynchronizationAdapterSpy transactionSpy = PersistenceTransactionalTestConfig.getSpy();
Assert.assertEquals(0, transactionSpy.getSuspend());
Assert.assertEquals(1, transactionSpy.getCreate());
}
@Test
public void givenMandatoryWithActiveTransaction_whenCallCreate_thenExpect0NewAnd0Suspend() {
transactionTemplate.execute(status -> {
Foo foo = new Foo("baeldung");
return mandatoryTransactionalFooDao.create(foo);
});
PersistenceTransactionalTestConfig.TransactionSynchronizationAdapterSpy transactionSpy = PersistenceTransactionalTestConfig.getSpy();
Assert.assertEquals(0, transactionSpy.getSuspend());
Assert.assertEquals(1, transactionSpy.getCreate());
}
@Test
public void givenNotSupportWithActiveTransaction_whenCallCreate_thenExpect0NewAnd1Suspend() {
transactionTemplate.execute(status -> {
Foo foo = new Foo("baeldung");
return notSupportedTransactionalFooService.identity(foo);
});
PersistenceTransactionalTestConfig.TransactionSynchronizationAdapterSpy transactionSpy = PersistenceTransactionalTestConfig.getSpy();
Assert.assertEquals(1, transactionSpy.getSuspend());
Assert.assertEquals(1, transactionSpy.getCreate());
}
@Test(expected = IllegalTransactionStateException.class)
public void givenNeverWithActiveTransaction_whenCallCreate_thenExpectIllegalTransactionStateExceptionWith0NewAnd0Suspend() {
transactionTemplate.execute(status -> {
Foo foo = new Foo("baeldung");
return neverTransactionalFooService.identity(foo);
});
PersistenceTransactionalTestConfig.TransactionSynchronizationAdapterSpy transactionSpy = PersistenceTransactionalTestConfig.getSpy();
Assert.assertEquals(0, transactionSpy.getSuspend());
Assert.assertEquals(1, transactionSpy.getCreate());
}
}

View File

@@ -0,0 +1,148 @@
package com.baeldung.persistence.service.transactional;
import com.google.common.base.Preconditions;
import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.support.DefaultTransactionStatus;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionTemplate;
@Configuration
@EnableTransactionManagement
@PropertySource({ "classpath:persistence-h2.properties" })
@ComponentScan({ "com.baeldung.persistence","com.baeldung.jpa.dao" })
@EnableJpaRepositories(basePackages = "com.baeldung.jpa.dao")
public class PersistenceTransactionalTestConfig {
public static class TransactionSynchronizationAdapterSpy extends TransactionSynchronizationAdapter {
private int create, suspend;
public int getSuspend() {
return suspend;
}
public int getCreate() {
return create;
}
public void create() {
create++;
}
@Override
public void suspend() {
suspend++;
super.suspend();
}
}
public static class JpaTransactionManagerSpy extends JpaTransactionManager {
@Override
protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
super.prepareSynchronization(status, definition);
if (status.isNewTransaction()) {
if ( adapterSpyThreadLocal.get() == null ){
TransactionSynchronizationAdapterSpy spy = new TransactionSynchronizationAdapterSpy();
TransactionSynchronizationManager.registerSynchronization(spy);
adapterSpyThreadLocal.set(spy);
}
adapterSpyThreadLocal.get().create();
}
}
}
private static ThreadLocal<TransactionSynchronizationAdapterSpy> adapterSpyThreadLocal = new ThreadLocal<>();
@Autowired
private Environment env;
public PersistenceTransactionalTestConfig() {
super();
}
public static TransactionSynchronizationAdapterSpy getSpy(){
if ( adapterSpyThreadLocal.get() == null )
return new TransactionSynchronizationAdapterSpy();
return adapterSpyThreadLocal.get();
}
public static void clearSpy(){
adapterSpyThreadLocal.set(null);
}
// beans
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "com.baeldung.persistence.model" });
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
@Bean
public DataSource dataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));
return dataSource;
}
@Bean
public PlatformTransactionManager transactionManager(final EntityManagerFactory emf) {
final JpaTransactionManagerSpy transactionManager = new JpaTransactionManagerSpy();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
final Properties additionalProperties() {
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", "false");
return hibernateProperties;
}
@Bean
public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager){
TransactionTemplate template = new TransactionTemplate(transactionManager);
template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
return template;
}
}

View File

@@ -25,7 +25,7 @@
<module>spring-cloud-zookeeper</module>
<module>spring-cloud-gateway</module>
<module>spring-cloud-stream</module>
<module>spring-cloud-stream-starters/twitterhdfs</module>
<module>spring-cloud-stream-starters/twitterhdfs</module>
<module>spring-cloud-connectors-heroku</module>
<module>spring-cloud-aws</module>
<module>spring-cloud-consul</module>
@@ -35,9 +35,10 @@
<module>spring-cloud-archaius</module>
<module>spring-cloud-functions</module>
<module>spring-cloud-vault</module>
<!-- <module>spring-cloud-security</module> --> <!-- Fixing in BAEL-10887 -->
<module>spring-cloud-task</module>
<!-- <module>spring-cloud-security</module> --> <!-- Fixing in BAEL-10887 -->
<module>spring-cloud-task</module>
<module>spring-cloud-zuul</module>
<module>spring-cloud-zuul-fallback</module>
</modules>
<build>

View File

@@ -0,0 +1,2 @@
### Relevant Articles:
- [Fallback for Zuul Route](TODO)

View File

@@ -0,0 +1,43 @@
<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>api-gateway</artifactId>
<name>api-gateway</name>
<description>API Gateway using Zuul</description>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung.spring.cloud</groupId>
<artifactId>spring-cloud-zuul-fallback</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>${spring-cloud-dependencies.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>

View File

@@ -0,0 +1,15 @@
package com.baeldung.spring.cloud.apigateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableZuulProxy
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}

View File

@@ -0,0 +1,69 @@
package com.baeldung.spring.cloud.apigateway.fallback;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
public class GatewayClientResponse implements ClientHttpResponse {
private HttpStatus status;
private String message;
public GatewayClientResponse(HttpStatus status, String message) {
this.status = status;
this.message = message;
}
@Override
public HttpStatus getStatusCode() throws IOException {
return status;
}
@Override
public int getRawStatusCode() throws IOException {
return status.value();
}
@Override
public String getStatusText() throws IOException {
return status.getReasonPhrase();
}
@Override
public void close() {
}
@Override
public InputStream getBody() throws IOException {
return new ByteArrayInputStream(message.getBytes());
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;
}
public HttpStatus getStatus() {
return status;
}
public void setStatus(HttpStatus status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@@ -0,0 +1,29 @@
package com.baeldung.spring.cloud.apigateway.fallback;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
import com.netflix.hystrix.exception.HystrixTimeoutException;
@Component
class GatewayServiceFallback implements FallbackProvider {
private static final String DEFAULT_MESSAGE = "Service not available.";
@Override
public String getRoute() {
return "*"; // or return null;
}
@Override
public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
if (cause instanceof HystrixTimeoutException) {
return new GatewayClientResponse(HttpStatus.GATEWAY_TIMEOUT, DEFAULT_MESSAGE);
} else {
return new GatewayClientResponse(HttpStatus.INTERNAL_SERVER_ERROR, DEFAULT_MESSAGE);
}
}
}

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