diff --git a/core-java-collections/pom.xml b/core-java-collections/pom.xml
index 39ddc17684..d3ef953e01 100644
--- a/core-java-collections/pom.xml
+++ b/core-java-collections/pom.xml
@@ -65,7 +65,7 @@
4.1
4.01
1.7.0
- 3.6.1
+ 3.11.1
7.1.0
diff --git a/core-java-collections/src/test/java/com/baeldung/enummap/DummyEnum.java b/core-java-collections/src/test/java/com/baeldung/enummap/DummyEnum.java
new file mode 100644
index 0000000000..906c820fa3
--- /dev/null
+++ b/core-java-collections/src/test/java/com/baeldung/enummap/DummyEnum.java
@@ -0,0 +1,13 @@
+package com.baeldung.enummap;
+
+/**
+ * This enum is used for benchmarking, therefore has many values.
+ */
+public enum DummyEnum {
+ CCC_000,
+ CCC_001,CCC_002,CCC_003,CCC_004,CCC_005,CCC_006,CCC_007,CCC_008,CCC_009,CCC_010,
+ CCC_011,CCC_012,CCC_013,CCC_014,CCC_015,CCC_016,CCC_017,CCC_018,CCC_019,CCC_020,
+ CCC_021,CCC_022,CCC_023,CCC_024,CCC_025,CCC_026,CCC_027,CCC_028,CCC_029,CCC_030,
+ CCC_031,CCC_032,CCC_033,CCC_034,CCC_035,CCC_036,CCC_037,CCC_038,CCC_039,CCC_040,
+ CCC_041,CCC_042,CCC_043,CCC_044,CCC_045,CCC_046,CCC_047,CCC_048,CCC_049,
+}
diff --git a/core-java-collections/src/test/java/com/baeldung/enummap/EnumMapBenchmarkLiveTest.java b/core-java-collections/src/test/java/com/baeldung/enummap/EnumMapBenchmarkLiveTest.java
new file mode 100644
index 0000000000..997a8ba65b
--- /dev/null
+++ b/core-java-collections/src/test/java/com/baeldung/enummap/EnumMapBenchmarkLiveTest.java
@@ -0,0 +1,119 @@
+package com.baeldung.enummap;
+
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode({ Mode.AverageTime })
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+public class EnumMapBenchmarkLiveTest {
+
+ @State(Scope.Thread)
+ public static class BenchmarkState {
+ EnumMap enumMap = new EnumMap<>(DummyEnum.class);
+ HashMap hashMap = new HashMap<>();
+ TreeMap treeMap = new TreeMap<>();
+ int len = DummyEnum.values().length;
+ Random random = new Random();
+ int randomIndex;
+
+ @Setup(Level.Trial)
+ public void setUp() {
+ DummyEnum[] values = DummyEnum.values();
+ for (int i = 0; i < len; i++) {
+ enumMap.put(values[i], values[i].toString());
+ hashMap.put(values[i], values[i].toString());
+ treeMap.put(values[i], values[i].toString());
+ }
+ }
+
+ @Setup(Level.Invocation)
+ public void additionalSetup() {
+ randomIndex = random.nextInt(len);
+ }
+
+ }
+
+ @Benchmark
+ public int benchmark01_EnumMapPut(BenchmarkState s) {
+ s.enumMap.put(DummyEnum.values()[s.randomIndex], DummyEnum.values()[s.randomIndex].toString());
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark01_HashMapPut(BenchmarkState s) {
+ s.hashMap.put(DummyEnum.values()[s.randomIndex], DummyEnum.values()[s.randomIndex].toString());
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark01_TreeMapPut(BenchmarkState s) {
+ s.treeMap.put(DummyEnum.values()[s.randomIndex], DummyEnum.values()[s.randomIndex].toString());
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark02_EnumMapGet(BenchmarkState s) {
+ s.enumMap.get(DummyEnum.values()[s.randomIndex]);
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark02_HashMapGet(BenchmarkState s) {
+ s.hashMap.get(DummyEnum.values()[s.randomIndex]);
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark02_TreeMapGet(BenchmarkState s) {
+ s.treeMap.get(DummyEnum.values()[s.randomIndex]);
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark03_EnumMapContainsKey(BenchmarkState s) {
+ s.enumMap.containsKey(DummyEnum.values()[s.randomIndex]);
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark03_HashMapContainsKey(BenchmarkState s) {
+ s.hashMap.containsKey(DummyEnum.values()[s.randomIndex]);
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark03_TreeMapContainsKey(BenchmarkState s) {
+ s.treeMap.containsKey(DummyEnum.values()[s.randomIndex]);
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark04_EnumMapContainsValue(BenchmarkState s) {
+ s.enumMap.containsValue(DummyEnum.values()[s.randomIndex].toString());
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark04_HashMapContainsValue(BenchmarkState s) {
+ s.hashMap.containsValue(DummyEnum.values()[s.randomIndex].toString());
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark04_TreeMapContainsValue(BenchmarkState s) {
+ s.treeMap.containsValue(DummyEnum.values()[s.randomIndex].toString());
+ return ++s.randomIndex;
+ }
+
+ public static void main(String[] args) throws Exception {
+ Options options = new OptionsBuilder().include(EnumMapBenchmarkLiveTest.class.getSimpleName()).threads(1).forks(0).shouldFailOnError(true).shouldDoGC(false).jvmArgs("-server").build();
+ new Runner(options).run();
+ }
+}
diff --git a/core-java-collections/src/test/java/com/baeldung/enummap/EnumMapUnitTest.java b/core-java-collections/src/test/java/com/baeldung/enummap/EnumMapUnitTest.java
new file mode 100644
index 0000000000..d9d6cf2c39
--- /dev/null
+++ b/core-java-collections/src/test/java/com/baeldung/enummap/EnumMapUnitTest.java
@@ -0,0 +1,144 @@
+package com.baeldung.enummap;
+
+import org.junit.Test;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+import static java.util.AbstractMap.SimpleEntry;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+
+public class EnumMapUnitTest {
+ public enum DayOfWeek {
+ MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
+ }
+
+ @Test
+ public void whenContructedWithEnumType_ThenOnlyAcceptThatAsKey() {
+ Map dayMap = new EnumMap<>(DayOfWeek.class);
+ assertThatCode(
+ () -> dayMap.put(TimeUnit.NANOSECONDS, "NANOSECONDS"))
+ .isInstanceOf(ClassCastException.class);
+ }
+
+ @Test
+ public void whenConstructedWithEnumMap_ThenSameKeyTypeAndInitialMappings() {
+ EnumMap activityMap = new EnumMap<>(DayOfWeek.class);
+ activityMap.put(DayOfWeek.MONDAY, "Soccer");
+ activityMap.put(DayOfWeek.TUESDAY, "Basketball");
+
+ EnumMap activityMapCopy = new EnumMap<>(activityMap);
+ assertThat(activityMapCopy.size()).isEqualTo(2);
+ assertThat(activityMapCopy.get(DayOfWeek.MONDAY))
+ .isEqualTo("Soccer");
+ assertThat(activityMapCopy.get(DayOfWeek.TUESDAY))
+ .isEqualTo("Basketball");
+ }
+
+ @Test
+ public void givenEmptyMap_whenConstructedWithMap_ThenException() {
+ HashMap ordinaryMap = new HashMap();
+ assertThatCode(() -> new EnumMap(ordinaryMap))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("Specified map is empty");
+ }
+
+ @Test
+ public void givenMapWithEntries_whenConstructedWithMap_ThenSucceed() {
+ HashMap ordinaryMap = new HashMap<>();
+ ordinaryMap.put(DayOfWeek.MONDAY, "Soccer");
+ ordinaryMap.put(DayOfWeek.TUESDAY, "Basketball");
+ EnumMap enumMap = new EnumMap<>(ordinaryMap);
+ assertThat(enumMap.size()).isEqualTo(2);
+ assertThat(enumMap.get(DayOfWeek.MONDAY)).isEqualTo("Soccer");
+ assertThat(enumMap.get(DayOfWeek.TUESDAY)).isEqualTo("Basketball");
+ }
+
+ @Test
+ public void givenMapWithMultiTypeEntries_whenConstructedWithMap_ThenException() {
+ HashMap ordinaryMap = new HashMap<>();
+ ordinaryMap.put(DayOfWeek.MONDAY, "Soccer");
+ ordinaryMap.put(TimeUnit.MILLISECONDS, "Other enum type");
+ assertThatCode(() -> new EnumMap(ordinaryMap))
+ .isInstanceOf(ClassCastException.class);
+ }
+
+ @Test
+ public void whenPut_thenGet() {
+ Map activityMap = new EnumMap(DayOfWeek.class);
+ activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
+ activityMap.put(DayOfWeek.THURSDAY, null);
+ assertThat(activityMap.get(DayOfWeek.WEDNESDAY)).isEqualTo("Hiking");
+ assertThat(activityMap.get(DayOfWeek.THURSDAY)).isNull();
+ }
+
+ @Test
+ public void givenMapping_whenContains_thenTrue() {
+ EnumMap activityMap = new EnumMap(DayOfWeek.class);
+ assertThat(activityMap.containsKey(DayOfWeek.WEDNESDAY)).isFalse();
+ assertThat(activityMap.containsValue("Hiking")).isFalse();
+ activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
+ assertThat(activityMap.containsKey(DayOfWeek.WEDNESDAY)).isTrue();
+ assertThat(activityMap.containsValue("Hiking")).isTrue();
+
+ assertThat(activityMap.containsKey(DayOfWeek.SATURDAY)).isFalse();
+ assertThat(activityMap.containsValue(null)).isFalse();
+ activityMap.put(DayOfWeek.SATURDAY, null);
+ assertThat(activityMap.containsKey(DayOfWeek.SATURDAY)).isTrue();
+ assertThat(activityMap.containsValue(null)).isTrue();
+ }
+
+ @Test
+ public void whenRemove_thenRemoved() {
+ EnumMap activityMap = new EnumMap(DayOfWeek.class);
+
+ activityMap.put(DayOfWeek.MONDAY, "Soccer");
+ assertThat(activityMap.remove(DayOfWeek.MONDAY)).isEqualTo("Soccer");
+ assertThat(activityMap.containsKey(DayOfWeek.MONDAY)).isFalse();
+
+ activityMap.put(DayOfWeek.MONDAY, "Soccer");
+ assertThat(activityMap.remove(DayOfWeek.MONDAY, "Hiking")).isEqualTo(false);
+ assertThat(activityMap.remove(DayOfWeek.MONDAY, "Soccer")).isEqualTo(true);
+ }
+
+ @Test
+ public void whenSubView_thenSubViewOrdered() {
+ EnumMap activityMap = new EnumMap(DayOfWeek.class);
+ activityMap.put(DayOfWeek.THURSDAY, "Karate");
+ activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
+ activityMap.put(DayOfWeek.MONDAY, "Soccer");
+
+ Collection values = activityMap.values();
+ assertThat(values).containsExactly("Soccer", "Hiking", "Karate");
+
+ Set keys = activityMap.keySet();
+ assertThat(keys)
+ .containsExactly(DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY,DayOfWeek.THURSDAY);
+
+ assertThat(activityMap.entrySet())
+ .containsExactly(
+ new SimpleEntry(DayOfWeek.MONDAY, "Soccer"),
+ new SimpleEntry(DayOfWeek.WEDNESDAY, "Hiking"),
+ new SimpleEntry(DayOfWeek.THURSDAY, "Karate"));
+ }
+
+ @Test
+ public void givenSubView_whenChange_thenReflected() {
+ EnumMap activityMap = new EnumMap(DayOfWeek.class);
+ activityMap.put(DayOfWeek.THURSDAY, "Karate");
+ activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
+ activityMap.put(DayOfWeek.MONDAY, "Soccer");
+
+ Collection values = activityMap.values();
+ assertThat(values).containsExactly("Soccer", "Hiking", "Karate");
+
+ activityMap.put(DayOfWeek.TUESDAY, "Basketball");
+ assertThat(values)
+ .containsExactly("Soccer", "Basketball", "Hiking", "Karate");
+
+ values.remove("Hiking");
+ assertThat(activityMap.containsKey(DayOfWeek.WEDNESDAY)).isFalse();
+ assertThat(activityMap.size()).isEqualTo(3);
+ }
+}
diff --git a/java-strings/src/main/java/com/baeldung/string/searching/WordIndexer.java b/java-strings/src/main/java/com/baeldung/string/searching/WordIndexer.java
index 5314efb0b4..1bcad6dd32 100644
--- a/java-strings/src/main/java/com/baeldung/string/searching/WordIndexer.java
+++ b/java-strings/src/main/java/com/baeldung/string/searching/WordIndexer.java
@@ -11,11 +11,14 @@ public class WordIndexer {
String lowerCaseTextString = textString.toLowerCase();
String lowerCaseWord = word.toLowerCase();
- while(index != -1){
- index = lowerCaseTextString.indexOf(lowerCaseWord, index + 1);
- if (index != -1) {
- indexes.add(index);
+ while(index != -1) {
+ index = lowerCaseTextString.indexOf(lowerCaseWord, index);
+ if (index == -1) {
+ break;
}
+
+ indexes.add(index);
+ index++;
}
return indexes;
}
diff --git a/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/naming/HibernateConfig.java b/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/naming/HibernateConfig.java
new file mode 100644
index 0000000000..897e34d406
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/naming/HibernateConfig.java
@@ -0,0 +1,19 @@
+package com.baeldung.naming;
+
+import org.hibernate.jpa.boot.spi.IntegratorProvider;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * Custom implementation of the {@link HibernatePropertiesCustomizer HibernatePropertiesCustomizer}.
+ * We can use it to set custom hibernate properties.
+ */
+public class HibernateConfig implements HibernatePropertiesCustomizer {
+
+ @Override
+ public void customize(Map hibernateProperties) {
+ hibernateProperties.put("hibernate.integrator_provider", (IntegratorProvider) () -> Collections.singletonList(MetadataExtractorIntegrator.INSTANCE));
+ }
+}
diff --git a/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/naming/MetadataExtractorIntegrator.java b/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/naming/MetadataExtractorIntegrator.java
new file mode 100644
index 0000000000..24b5cdea64
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/naming/MetadataExtractorIntegrator.java
@@ -0,0 +1,41 @@
+package com.baeldung.naming;
+
+import org.hibernate.boot.Metadata;
+import org.hibernate.boot.model.relational.Database;
+import org.hibernate.engine.spi.SessionFactoryImplementor;
+import org.hibernate.integrator.spi.Integrator;
+import org.hibernate.service.spi.SessionFactoryServiceRegistry;
+
+/**
+ * Custom implementation of the {@link Integrator Integrator} interface.
+ * We can use it to getting access to the binding metadata between entity mappings and database tables.
+ */
+public class MetadataExtractorIntegrator implements Integrator {
+
+ public static final MetadataExtractorIntegrator INSTANCE = new MetadataExtractorIntegrator();
+
+ private Database database;
+
+ private Metadata metadata;
+
+ public Database getDatabase() {
+ return database;
+ }
+
+ public Metadata getMetadata() {
+ return metadata;
+ }
+
+ @Override
+ public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
+
+ this.database = metadata.getDatabase();
+ this.metadata = metadata;
+
+ }
+
+ @Override
+ public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
+
+ }
+}
diff --git a/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/naming/entity/Account.java b/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/naming/entity/Account.java
new file mode 100644
index 0000000000..6145818c5b
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/naming/entity/Account.java
@@ -0,0 +1,19 @@
+package com.baeldung.naming.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import java.util.List;
+
+@Entity
+public class Account {
+
+ @Id private Long id;
+
+ private String defaultEmail;
+
+ @OneToMany List preferences;
+
+ @Column(name = "\"Secondary_Email\"") private String secondaryEmail;
+}
diff --git a/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/naming/entity/Preference.java b/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/naming/entity/Preference.java
new file mode 100644
index 0000000000..928884a2c5
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/naming/entity/Preference.java
@@ -0,0 +1,16 @@
+package com.baeldung.naming.entity;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+
+@Entity
+public class Preference {
+
+ @Id private Long id;
+
+ private String name;
+
+ @ManyToOne private Account account;
+
+}
diff --git a/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/naming/LegacyJpaImplNamingIntegrationTest.java b/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/naming/LegacyJpaImplNamingIntegrationTest.java
new file mode 100644
index 0000000000..e68be3bed8
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/naming/LegacyJpaImplNamingIntegrationTest.java
@@ -0,0 +1,58 @@
+package com.baeldung.naming;
+
+import com.baeldung.naming.entity.Account;
+import org.assertj.core.api.SoftAssertions;
+import org.hibernate.boot.Metadata;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Table;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@DataJpaTest
+@TestPropertySource(properties = {
+ "spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl",
+ "spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl"
+})
+public class LegacyJpaImplNamingIntegrationTest extends NamingConfig {
+
+ @Test
+ public void givenLegacyJpaImplNamingStrategy_whenCreateDatabase_thenGetStrategyNames() {
+ Metadata metadata = MetadataExtractorIntegrator.INSTANCE.getMetadata();
+ String entity = Account.class.getCanonicalName();
+ PersistentClass persistentClass = metadata.getEntityBinding(entity);
+ Table table = persistentClass.getTable();
+ String physicalNameExpected = "Secondary_Email";
+ String implicitNameExpected = "defaultEmail";
+ String tableNameExpected = "Account";
+
+ String tableNameCreated = table.getName();
+ boolean columnNameIsQuoted = table
+ .getColumn(3)
+ .isQuoted();
+ String physicalNameCreated = table
+ .getColumn(3)
+ .getName();
+ String implicitNameCreated = table
+ .getColumn(2)
+ .getName();
+
+ SoftAssertions.assertSoftly(softly -> {
+ softly
+ .assertThat(columnNameIsQuoted)
+ .isTrue();
+ softly
+ .assertThat(tableNameCreated)
+ .isEqualTo(tableNameExpected);
+ softly
+ .assertThat(physicalNameCreated)
+ .isEqualTo(physicalNameExpected);
+ softly
+ .assertThat(implicitNameCreated)
+ .isEqualTo(implicitNameExpected);
+ });
+ }
+}
diff --git a/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/naming/NamingConfig.java b/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/naming/NamingConfig.java
new file mode 100644
index 0000000000..c3ef37aeb4
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/naming/NamingConfig.java
@@ -0,0 +1,15 @@
+package com.baeldung.naming;
+
+import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.context.annotation.Bean;
+
+public class NamingConfig {
+ @TestConfiguration
+ static class Config {
+ @Bean
+ public HibernatePropertiesCustomizer customizer() {
+ return new HibernateConfig();
+ }
+ }
+}
diff --git a/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/naming/SpringBootDefaultNamingIntegrationTest.java b/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/naming/SpringBootDefaultNamingIntegrationTest.java
new file mode 100644
index 0000000000..089430aabb
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/naming/SpringBootDefaultNamingIntegrationTest.java
@@ -0,0 +1,54 @@
+package com.baeldung.naming;
+
+import com.baeldung.naming.entity.Account;
+import org.assertj.core.api.SoftAssertions;
+import org.hibernate.boot.Metadata;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Table;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(SpringRunner.class)
+@DataJpaTest
+@TestPropertySource(properties = {
+ "spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy",
+ "spring.jpa.hibernate.naming.implicit-strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy"
+})
+public class SpringBootDefaultNamingIntegrationTest extends NamingConfig {
+
+ @Test
+ public void givenDefaultBootNamingStrategy_whenCreateDatabase_thenGetStrategyNames() {
+ Metadata metadata = MetadataExtractorIntegrator.INSTANCE.getMetadata();
+ String entity = Account.class.getCanonicalName();
+ PersistentClass persistentClass = metadata.getEntityBinding(entity);
+ Table table = persistentClass.getTable();
+ String physicalNameExpected = "secondary_email";
+ String implicitNameExpected = "default_email";
+ String tableNameExpected = "account";
+
+ String tableNameCreated = table.getName();
+ String physicalNameCreated = table
+ .getColumn(3)
+ .getName();
+ String implicitNameCreated = table
+ .getColumn(2)
+ .getName();
+
+ SoftAssertions softly = new SoftAssertions();
+ softly
+ .assertThat(tableNameCreated)
+ .isEqualTo(tableNameExpected);
+ softly
+ .assertThat(physicalNameCreated)
+ .isEqualTo(physicalNameExpected);
+ softly
+ .assertThat(implicitNameCreated)
+ .isEqualTo(implicitNameExpected);
+ softly.assertAll();
+ }
+}
diff --git a/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/naming/StrategyLegacyHbmImplIntegrationTest.java b/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/naming/StrategyLegacyHbmImplIntegrationTest.java
new file mode 100644
index 0000000000..046755d9bc
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/naming/StrategyLegacyHbmImplIntegrationTest.java
@@ -0,0 +1,58 @@
+package com.baeldung.naming;
+
+import com.baeldung.naming.entity.Preference;
+import org.assertj.core.api.SoftAssertions;
+import org.hibernate.boot.Metadata;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Table;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.Collection;
+
+@RunWith(SpringRunner.class)
+@DataJpaTest
+@TestPropertySource(properties = {
+ "spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl",
+ "spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl",
+})
+public class StrategyLegacyHbmImplIntegrationTest extends NamingConfig {
+
+ @Test
+ public void givenLegacyHbmImplNamingNamingStrategy_whenCreateDatabase_thenGetStrategyNames() {
+ Metadata metadata = MetadataExtractorIntegrator.INSTANCE.getMetadata();
+ String entity = Preference.class.getCanonicalName();
+ PersistentClass persistentClass = metadata.getEntityBinding(entity);
+ Collection tables = metadata
+ .getDatabase()
+ .getDefaultNamespace()
+ .getTables();
+ Table preferenceTable = persistentClass.getTable();
+ String tableNameExpected = "Account_preferences";
+ Table accountPreferencesTable = tables
+ .stream()
+ .filter(table -> table
+ .getName()
+ .equals(tableNameExpected))
+ .findFirst()
+ .get();
+ String implicitNameExpected = "account";
+
+ String implicitNameCreated = preferenceTable
+ .getColumn(3)
+ .getName();
+ String tableNameCreated = accountPreferencesTable.getName();
+
+ SoftAssertions.assertSoftly(softly -> {
+ softly
+ .assertThat(implicitNameCreated)
+ .isEqualTo(implicitNameExpected);
+ softly
+ .assertThat(tableNameCreated)
+ .isEqualTo(tableNameExpected);
+ });
+ }
+}
diff --git a/testing-modules/junit-5/pom.xml b/testing-modules/junit-5/pom.xml
index 93365264ac..b7600267d9 100644
--- a/testing-modules/junit-5/pom.xml
+++ b/testing-modules/junit-5/pom.xml
@@ -72,6 +72,13 @@
+
+ org.mockito
+ mockito-junit-jupiter
+ ${mockito.junit.jupiter.version}
+ test
+
+
org.powermock
powermock-api-mockito2
@@ -118,13 +125,13 @@
- 5.2.0
+ 5.3.1
+ 2.23.0
1.2.0
5.2.0
2.8.2
1.4.196
- 2.8.9
- 1.7.4
+ 2.0.0-RC.1
2.21.0
1.6.0
5.0.1.RELEASE
diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/MockitoExtension.java b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/MockitoExtension.java
deleted file mode 100644
index 5836ef46e6..0000000000
--- a/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/MockitoExtension.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright 2015-2016 the original author or authors.
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution and is available at
- *
- * http://www.eclipse.org/legal/epl-v10.html
- */
-
-package com.baeldung.junit5.mockito;
-
-import static org.mockito.Mockito.mock;
-
-import java.lang.reflect.Parameter;
-
-import org.junit.jupiter.api.extension.ExtensionContext;
-import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
-import org.junit.jupiter.api.extension.ExtensionContext.Store;
-import org.junit.jupiter.api.extension.ParameterContext;
-import org.junit.jupiter.api.extension.ParameterResolver;
-import org.junit.jupiter.api.extension.TestInstancePostProcessor;
-import org.mockito.MockitoAnnotations;
-import org.mockito.Mock;
-
-/**
- * {@code MockitoExtension} showcases the {@link TestInstancePostProcessor}
- * and {@link ParameterResolver} extension APIs of JUnit 5 by providing
- * dependency injection support at the field level and at the method parameter
- * level via Mockito 2.x's {@link Mock @Mock} annotation.
- *
- * @since 5.0
- */
-public class MockitoExtension implements TestInstancePostProcessor, ParameterResolver {
-
- @Override
- public void postProcessTestInstance(Object testInstance, ExtensionContext context) {
- MockitoAnnotations.initMocks(testInstance);
- }
-
- @Override
- public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
- return parameterContext.getParameter().isAnnotationPresent(Mock.class);
- }
-
- @Override
- public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
- return getMock(parameterContext.getParameter(), extensionContext);
- }
-
- private Object getMock(Parameter parameter, ExtensionContext extensionContext) {
- Class> mockType = parameter.getType();
- Store mocks = extensionContext.getStore(Namespace.create(MockitoExtension.class, mockType));
- String mockName = getMockName(parameter);
-
- if (mockName != null) {
- return mocks.getOrComputeIfAbsent(mockName, key -> mock(mockType, mockName));
- }
- else {
- return mocks.getOrComputeIfAbsent(mockType.getCanonicalName(), key -> mock(mockType));
- }
- }
-
- private String getMockName(Parameter parameter) {
- String explicitMockName = parameter.getAnnotation(Mock.class).name().trim();
- if (!explicitMockName.isEmpty()) {
- return explicitMockName;
- }
- else if (parameter.isNamePresent()) {
- return parameter.getName();
- }
- return null;
- }
-
-}
\ No newline at end of file
diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java
index 1ddab0531a..d4195e3b12 100644
--- a/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java
+++ b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java
@@ -3,9 +3,7 @@ package com.baeldung.junit5.mockito;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
@@ -16,6 +14,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
+import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.stubbing.Answer;
import com.baeldung.junit5.mockito.repository.MailClient;
@@ -25,21 +24,24 @@ import com.baeldung.junit5.mockito.service.DefaultUserService;
import com.baeldung.junit5.mockito.service.Errors;
import com.baeldung.junit5.mockito.service.UserService;
-@RunWith(JUnitPlatform.class)
@ExtendWith(MockitoExtension.class)
+@RunWith(JUnitPlatform.class)
public class UserServiceUnitTest {
UserService userService;
+ SettingRepository settingRepository;
@Mock UserRepository userRepository;
-
+ @Mock MailClient mailClient;
+
User user;
@BeforeEach
- void init(@Mock SettingRepository settingRepository, @Mock MailClient mailClient) {
+ void init(@Mock SettingRepository settingRepository) {
userService = new DefaultUserService(userRepository, settingRepository, mailClient);
- when(settingRepository.getUserMinAge()).thenReturn(10);
+ lenient().when(settingRepository.getUserMinAge()).thenReturn(10);
when(settingRepository.getUserNameMinLength()).thenReturn(4);
- when(userRepository.isUsernameAlreadyExists(any(String.class))).thenReturn(false);
+ lenient().when(userRepository.isUsernameAlreadyExists(any(String.class))).thenReturn(false);
+ this.settingRepository = settingRepository;
}
@Test
@@ -56,7 +58,9 @@ public class UserServiceUnitTest {
return user;
}
});
-
+
+ userService = new DefaultUserService(userRepository, settingRepository, mailClient);
+
// When
User insertedUser = userService.register(user);