results = movieRepository.findByDirectorNotLike("An%");
+ assertEquals(5, results.size());
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-2/src/test/resources/test-movie-cleanup.sql b/persistence-modules/spring-data-jpa-2/src/test/resources/test-movie-cleanup.sql
new file mode 100644
index 0000000000..90aa15307c
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-2/src/test/resources/test-movie-cleanup.sql
@@ -0,0 +1 @@
+DELETE FROM Movie;
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-2/src/test/resources/test-movie-data.sql b/persistence-modules/spring-data-jpa-2/src/test/resources/test-movie-data.sql
new file mode 100644
index 0000000000..37f8e4fe64
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-2/src/test/resources/test-movie-data.sql
@@ -0,0 +1,7 @@
+INSERT INTO movie(id, title, director, rating, duration) VALUES(1, 'Godzilla: King of the Monsters', ' Michael Dougherty', 'PG-13', 132);
+INSERT INTO movie(id, title, director, rating, duration) VALUES(2, 'Avengers: Endgame', 'Anthony Russo', 'PG-13', 181);
+INSERT INTO movie(id, title, director, rating, duration) VALUES(3, 'Captain Marvel', 'Anna Boden', 'PG-13', 123);
+INSERT INTO movie(id, title, director, rating, duration) VALUES(4, 'Dumbo', 'Tim Burton', 'PG', 112);
+INSERT INTO movie(id, title, director, rating, duration) VALUES(5, 'Booksmart', 'Olivia Wilde', 'R', 102);
+INSERT INTO movie(id, title, director, rating, duration) VALUES(6, 'Aladdin', 'Guy Ritchie', 'PG', 128);
+INSERT INTO movie(id, title, director, rating, duration) VALUES(7, 'The Sun Is Also a Star', 'Ry Russo-Young', 'PG-13', 100);
diff --git a/persistence-modules/spring-data-jpa/README.md b/persistence-modules/spring-data-jpa/README.md
index 4e390c2faf..e85d8a8487 100644
--- a/persistence-modules/spring-data-jpa/README.md
+++ b/persistence-modules/spring-data-jpa/README.md
@@ -6,7 +6,6 @@
- [Spring JPA – Multiple Databases](http://www.baeldung.com/spring-data-jpa-multiple-databases)
- [Spring Data JPA – Adding a Method in All Repositories](http://www.baeldung.com/spring-data-jpa-method-in-all-repositories)
- [An Advanced Tagging Implementation with JPA](http://www.baeldung.com/jpa-tagging-advanced)
-- [Spring Data JPA @Query](http://www.baeldung.com/spring-data-jpa-query)
- [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations)
- [Spring Data Java 8 Support](http://www.baeldung.com/spring-data-java-8)
- [A Simple Tagging Implementation with JPA](http://www.baeldung.com/jpa-tagging)
diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/MultipleDbApplication.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/MultipleDbApplication.java
index 8ff6799e31..3b9aa2cc18 100644
--- a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/MultipleDbApplication.java
+++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/MultipleDbApplication.java
@@ -9,6 +9,6 @@ public class MultipleDbApplication {
public static void main(String[] args) {
SpringApplication.run(MultipleDbApplication.class, args);
}
-
+
}
diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceProductAutoConfiguration.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceProductAutoConfiguration.java
new file mode 100644
index 0000000000..a6f8f0829f
--- /dev/null
+++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceProductAutoConfiguration.java
@@ -0,0 +1,71 @@
+package com.baeldung.multipledb;
+
+import java.util.HashMap;
+
+import javax.sql.DataSource;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
+import org.springframework.transaction.PlatformTransactionManager;
+
+/**
+ * By default, the persistence-multiple-db.properties file is read for
+ * non auto configuration in PersistenceProductConfiguration.
+ *
+ * If we need to use persistence-multiple-db-boot.properties and auto configuration
+ * then uncomment the below @Configuration class and comment out PersistenceProductConfiguration.
+ */
+//@Configuration
+@PropertySource({"classpath:persistence-multiple-db-boot.properties"})
+@EnableJpaRepositories(basePackages = "com.baeldung.multipledb.dao.product", entityManagerFactoryRef = "productEntityManager", transactionManagerRef = "productTransactionManager")
+@Profile("!tc")
+public class PersistenceProductAutoConfiguration {
+ @Autowired
+ private Environment env;
+
+ public PersistenceProductAutoConfiguration() {
+ super();
+ }
+
+ //
+
+ @Bean
+ public LocalContainerEntityManagerFactoryBean productEntityManager() {
+ final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
+ em.setDataSource(productDataSource());
+ em.setPackagesToScan("com.baeldung.multipledb.model.product");
+
+ final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
+ em.setJpaVendorAdapter(vendorAdapter);
+ final HashMap properties = new HashMap();
+ properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
+ properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
+ em.setJpaPropertyMap(properties);
+
+ return em;
+ }
+
+ @Bean
+ @ConfigurationProperties(prefix="spring.second-datasource")
+ public DataSource productDataSource() {
+ return DataSourceBuilder.create().build();
+ }
+
+ @Bean
+ public PlatformTransactionManager productTransactionManager() {
+ final JpaTransactionManager transactionManager = new JpaTransactionManager();
+ transactionManager.setEntityManagerFactory(productEntityManager().getObject());
+ return transactionManager;
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceUserAutoConfiguration.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceUserAutoConfiguration.java
new file mode 100644
index 0000000000..e04a1621b2
--- /dev/null
+++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceUserAutoConfiguration.java
@@ -0,0 +1,75 @@
+package com.baeldung.multipledb;
+
+import java.util.HashMap;
+
+import javax.sql.DataSource;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.context.annotation.Profile;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
+import org.springframework.transaction.PlatformTransactionManager;
+
+/**
+ * By default, the persistence-multiple-db.properties file is read for
+ * non auto configuration in PersistenceUserConfiguration.
+ *
+ * If we need to use persistence-multiple-db-boot.properties and auto configuration
+ * then uncomment the below @Configuration class and comment out PersistenceUserConfiguration.
+ */
+//@Configuration
+@PropertySource({"classpath:persistence-multiple-db-boot.properties"})
+@EnableJpaRepositories(basePackages = "com.baeldung.multipledb.dao.user", entityManagerFactoryRef = "userEntityManager", transactionManagerRef = "userTransactionManager")
+@Profile("!tc")
+public class PersistenceUserAutoConfiguration {
+ @Autowired
+ private Environment env;
+
+ public PersistenceUserAutoConfiguration() {
+ super();
+ }
+
+ //
+
+ @Primary
+ @Bean
+ public LocalContainerEntityManagerFactoryBean userEntityManager() {
+ final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
+ em.setDataSource(userDataSource());
+ em.setPackagesToScan("com.baeldung.multipledb.model.user");
+
+ final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
+ em.setJpaVendorAdapter(vendorAdapter);
+ final HashMap properties = new HashMap();
+ properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
+ properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
+ em.setJpaPropertyMap(properties);
+
+ return em;
+ }
+
+ @Bean
+ @Primary
+ @ConfigurationProperties(prefix="spring.datasource")
+ public DataSource userDataSource() {
+ return DataSourceBuilder.create().build();
+ }
+
+ @Primary
+ @Bean
+ public PlatformTransactionManager userTransactionManager() {
+ final JpaTransactionManager transactionManager = new JpaTransactionManager();
+ transactionManager.setEntityManagerFactory(userEntityManager().getObject());
+ return transactionManager;
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db-boot.properties b/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db-boot.properties
new file mode 100644
index 0000000000..ffca79b3f5
--- /dev/null
+++ b/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db-boot.properties
@@ -0,0 +1,11 @@
+hibernate.hbm2ddl.auto=create-drop
+hibernate.cache.use_second_level_cache=false
+hibernate.cache.use_query_cache=false
+
+spring.datasource.jdbcUrl=jdbc:h2:mem:spring_jpa_user;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS USERS
+spring.datasource.username=sa
+spring.datasource.password=sa
+
+spring.second-datasource.jdbcUrl=jdbc:h2:mem:spring_jpa_product;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS PRODUCTS
+spring.second-datasource.username=sa
+spring.second-datasource.password=sa
diff --git a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/multipledb/JpaMultipleDBIntegrationTest.java b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/multipledb/JpaMultipleDBIntegrationTest.java
index bcc4103d08..6ba10a4d49 100644
--- a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/multipledb/JpaMultipleDBIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/multipledb/JpaMultipleDBIntegrationTest.java
@@ -12,7 +12,6 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.dao.DataIntegrityViolationException;
-import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;
diff --git a/persistence-modules/spring-persistence-simple/README.md b/persistence-modules/spring-persistence-simple/README.md
index 3ecd735091..c408ff3c96 100644
--- a/persistence-modules/spring-persistence-simple/README.md
+++ b/persistence-modules/spring-persistence-simple/README.md
@@ -9,6 +9,9 @@
- [The DAO with Spring and Hibernate](http://www.baeldung.com/persistence-layer-with-spring-and-hibernate)
- [DAO with Spring and Generics](https://www.baeldung.com/simplifying-the-data-access-layer-with-spring-and-java-generics)
- [Transactions with Spring and JPA](https://www.baeldung.com/transaction-configuration-with-jpa-and-spring)
+- [Introduction to Spring Data JPA](http://www.baeldung.com/the-persistence-layer-with-spring-data-jpa)
+- [Spring Data JPA @Query](http://www.baeldung.com/spring-data-jpa-query)
+- [Spring JDBC](https://www.baeldung.com/spring-jdbc-jdbctemplate)
### Eclipse Config
diff --git a/persistence-modules/spring-persistence-simple/pom.xml b/persistence-modules/spring-persistence-simple/pom.xml
index 4057db8033..1afacab164 100644
--- a/persistence-modules/spring-persistence-simple/pom.xml
+++ b/persistence-modules/spring-persistence-simple/pom.xml
@@ -18,12 +18,6 @@
org.springframework
spring-orm
${org.springframework.version}
-
-
- commons-logging
- commons-logging
-
-
org.springframework
@@ -98,7 +92,16 @@
${org.springframework.version}
test
-
+
+ com.querydsl
+ querydsl-jpa
+ ${querydsl.version}
+
+
+ com.querydsl
+ querydsl-apt
+ ${querydsl.version}
+
@@ -109,6 +112,25 @@
true
+
+
+ com.mysema.maven
+ apt-maven-plugin
+ 1.1.3
+
+
+ generate-sources
+
+ process
+
+
+ target/generated-sources
+ com.querydsl.apt.jpa.JPAAnnotationProcessor
+
+
+
+
+
@@ -121,6 +143,7 @@
2.1.6.RELEASE
9.0.0.M26
1.1
+ 4.2.1
21.0
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/config/PersistenceConfig.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/config/PersistenceConfig.java
similarity index 93%
rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/config/PersistenceConfig.java
rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/config/PersistenceConfig.java
index c454ab3b54..569971e311 100644
--- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/config/PersistenceConfig.java
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/config/PersistenceConfig.java
@@ -1,11 +1,10 @@
-package org.baeldung.config;
+package com.baeldung.config;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
-import org.baeldung.persistence.dao.IFooDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
@@ -24,15 +23,16 @@ import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
-import com.baeldung.persistence.dao.impl.FooDao;
+import com.baeldung.hibernate.dao.FooDao;
+import com.baeldung.jpa.dao.IFooDao;
import com.google.common.base.Preconditions;
@Configuration
@EnableTransactionManagement
-@EnableJpaRepositories(basePackages = { "com.baeldung.persistence" }, transactionManagerRef = "jpaTransactionManager")
+@EnableJpaRepositories(basePackages = { "com.baeldung.hibernate.dao" }, transactionManagerRef = "jpaTransactionManager")
@EnableJpaAuditing
@PropertySource({ "classpath:persistence-mysql.properties" })
-@ComponentScan({ "com.baeldung.persistence" })
+@ComponentScan({ "com.baeldung.persistence", "com.baeldung.hibernate.dao" })
public class PersistenceConfig {
@Autowired
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/config/PersistenceJPAConfig.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/config/PersistenceJPAConfig.java
similarity index 93%
rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/config/PersistenceJPAConfig.java
rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/config/PersistenceJPAConfig.java
index ec0d4bca3c..9fae34d99e 100644
--- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/config/PersistenceJPAConfig.java
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/config/PersistenceJPAConfig.java
@@ -1,4 +1,4 @@
-package org.baeldung.config;
+package com.baeldung.config;
import java.util.Properties;
@@ -25,8 +25,8 @@ import com.google.common.base.Preconditions;
@Configuration
@EnableTransactionManagement
@PropertySource({ "classpath:persistence-h2.properties" })
-@ComponentScan({ "org.baeldung.persistence" })
-@EnableJpaRepositories(basePackages = "org.baeldung.persistence.dao")
+@ComponentScan({ "com.baeldung.persistence","com.baeldung.jpa.dao" })
+@EnableJpaRepositories(basePackages = "com.baeldung.jpa.dao")
public class PersistenceJPAConfig {
@Autowired
@@ -42,7 +42,7 @@ public class PersistenceJPAConfig {
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
- em.setPackagesToScan(new String[] { "org.baeldung.persistence.model" });
+ em.setPackagesToScan(new String[] { "com.baeldung.persistence.model" });
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/impl/FooDao.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/hibernate/dao/FooDao.java
similarity index 69%
rename from persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/impl/FooDao.java
rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/hibernate/dao/FooDao.java
index 2d940527e1..67c10fe7fe 100644
--- a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/impl/FooDao.java
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/hibernate/dao/FooDao.java
@@ -1,9 +1,9 @@
-package com.baeldung.persistence.dao.impl;
+package com.baeldung.hibernate.dao;
-import org.baeldung.persistence.dao.IFooDao;
-import org.baeldung.persistence.model.Foo;
+import com.baeldung.persistence.model.Foo;
import org.springframework.stereotype.Repository;
+import com.baeldung.jpa.dao.IFooDao;
import com.baeldung.persistence.dao.common.AbstractHibernateDao;
@Repository
diff --git a/spring-all/src/main/java/org/baeldung/jdbc/CustomSQLErrorCodeTranslator.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/CustomSQLErrorCodeTranslator.java
similarity index 88%
rename from spring-all/src/main/java/org/baeldung/jdbc/CustomSQLErrorCodeTranslator.java
rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/CustomSQLErrorCodeTranslator.java
index 8a02fe6a53..48ddfb04b1 100644
--- a/spring-all/src/main/java/org/baeldung/jdbc/CustomSQLErrorCodeTranslator.java
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/CustomSQLErrorCodeTranslator.java
@@ -1,4 +1,4 @@
-package org.baeldung.jdbc;
+package com.baeldung.jdbc;
import java.sql.SQLException;
@@ -10,7 +10,7 @@ public class CustomSQLErrorCodeTranslator extends SQLErrorCodeSQLExceptionTransl
@Override
protected DataAccessException customTranslate(final String task, final String sql, final SQLException sqlException) {
- if (sqlException.getErrorCode() == -104) {
+ if (sqlException.getErrorCode() == 23505) {
return new DuplicateKeyException("Custome Exception translator - Integrity contraint voilation.", sqlException);
}
return null;
diff --git a/spring-all/src/main/java/org/baeldung/jdbc/Employee.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/Employee.java
similarity index 96%
rename from spring-all/src/main/java/org/baeldung/jdbc/Employee.java
rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/Employee.java
index e9408eb7fa..a43eb265c7 100644
--- a/spring-all/src/main/java/org/baeldung/jdbc/Employee.java
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/Employee.java
@@ -1,4 +1,4 @@
-package org.baeldung.jdbc;
+package com.baeldung.jdbc;
public class Employee {
private int id;
diff --git a/spring-all/src/main/java/org/baeldung/jdbc/EmployeeDAO.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/EmployeeDAO.java
similarity index 99%
rename from spring-all/src/main/java/org/baeldung/jdbc/EmployeeDAO.java
rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/EmployeeDAO.java
index 1f0e7b28ad..9ba4ebdb6d 100644
--- a/spring-all/src/main/java/org/baeldung/jdbc/EmployeeDAO.java
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/EmployeeDAO.java
@@ -1,4 +1,4 @@
-package org.baeldung.jdbc;
+package com.baeldung.jdbc;
import java.sql.PreparedStatement;
import java.sql.SQLException;
diff --git a/spring-all/src/main/java/org/baeldung/jdbc/EmployeeRowMapper.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/EmployeeRowMapper.java
similarity index 95%
rename from spring-all/src/main/java/org/baeldung/jdbc/EmployeeRowMapper.java
rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/EmployeeRowMapper.java
index f926836c40..d09cd45dbc 100644
--- a/spring-all/src/main/java/org/baeldung/jdbc/EmployeeRowMapper.java
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/EmployeeRowMapper.java
@@ -1,4 +1,4 @@
-package org.baeldung.jdbc;
+package com.baeldung.jdbc;
import java.sql.ResultSet;
import java.sql.SQLException;
diff --git a/spring-all/src/main/java/org/baeldung/jdbc/config/SpringJdbcConfig.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/config/SpringJdbcConfig.java
similarity index 84%
rename from spring-all/src/main/java/org/baeldung/jdbc/config/SpringJdbcConfig.java
rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/config/SpringJdbcConfig.java
index f7eb592366..ddc24e439f 100644
--- a/spring-all/src/main/java/org/baeldung/jdbc/config/SpringJdbcConfig.java
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/config/SpringJdbcConfig.java
@@ -1,4 +1,4 @@
-package org.baeldung.jdbc.config;
+package com.baeldung.jdbc.config;
import javax.sql.DataSource;
@@ -10,12 +10,12 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
@Configuration
-@ComponentScan("org.baeldung.jdbc")
+@ComponentScan("com.baeldung.jdbc")
public class SpringJdbcConfig {
@Bean
public DataSource dataSource() {
- return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).addScript("classpath:jdbc/schema.sql").addScript("classpath:jdbc/test-data.sql").build();
+ return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).addScript("classpath:jdbc/schema.sql").addScript("classpath:jdbc/test-data.sql").build();
}
// @Bean
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/dao/AbstractJpaDAO.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jpa/dao/AbstractJpaDAO.java
similarity index 91%
rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/dao/AbstractJpaDAO.java
rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jpa/dao/AbstractJpaDAO.java
index 13007d9fcc..4fbc8464bb 100644
--- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/dao/AbstractJpaDAO.java
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jpa/dao/AbstractJpaDAO.java
@@ -1,4 +1,4 @@
-package org.baeldung.persistence.dao;
+package com.baeldung.jpa.dao;
import java.io.Serializable;
import java.util.List;
@@ -26,8 +26,9 @@ public abstract class AbstractJpaDAO {
return entityManager.createQuery("from " + clazz.getName()).getResultList();
}
- public void create(final T entity) {
+ public T create(final T entity) {
entityManager.persist(entity);
+ return entity;
}
public T update(final T entity) {
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/dao/FooDao.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jpa/dao/FooDao.java
similarity index 73%
rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/dao/FooDao.java
rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jpa/dao/FooDao.java
index 77978c5cf2..e79a44a0c2 100644
--- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/dao/FooDao.java
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jpa/dao/FooDao.java
@@ -1,6 +1,6 @@
-package org.baeldung.persistence.dao;
+package com.baeldung.jpa.dao;
-import org.baeldung.persistence.model.Foo;
+import com.baeldung.persistence.model.Foo;
import org.springframework.stereotype.Repository;
@Repository
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/dao/IFooDao.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jpa/dao/IFooDao.java
similarity index 65%
rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/dao/IFooDao.java
rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jpa/dao/IFooDao.java
index f5799522e2..8140c56edd 100644
--- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/dao/IFooDao.java
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jpa/dao/IFooDao.java
@@ -1,8 +1,8 @@
-package org.baeldung.persistence.dao;
+package com.baeldung.jpa.dao;
import java.util.List;
-import org.baeldung.persistence.model.Foo;
+import com.baeldung.persistence.model.Foo;
public interface IFooDao {
@@ -10,7 +10,7 @@ public interface IFooDao {
List findAll();
- void create(Foo entity);
+ Foo create(Foo entity);
Foo update(Foo entity);
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateDao.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateDao.java
index f3ade67f80..e406f896dc 100644
--- a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateDao.java
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateDao.java
@@ -28,9 +28,10 @@ public abstract class AbstractHibernateDao extends Abstr
}
@Override
- public void create(final T entity) {
+ public T create(final T entity) {
Preconditions.checkNotNull(entity);
getCurrentSession().saveOrUpdate(entity);
+ return entity;
}
@Override
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/common/GenericJpaDao.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/common/GenericJpaDao.java
index 5bcebed761..d4da194f4d 100644
--- a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/common/GenericJpaDao.java
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/common/GenericJpaDao.java
@@ -2,11 +2,12 @@ package com.baeldung.persistence.dao.common;
import java.io.Serializable;
-import org.baeldung.persistence.dao.AbstractJpaDAO;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;
+import com.baeldung.jpa.dao.AbstractJpaDAO;
+
@Repository
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class GenericJpaDao extends AbstractJpaDAO implements IGenericDao {
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/common/IOperations.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/common/IOperations.java
index 4ef99221ab..34c5e0f616 100644
--- a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/common/IOperations.java
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/common/IOperations.java
@@ -9,7 +9,7 @@ public interface IOperations {
List findAll();
- void create(final T entity);
+ T create(final T entity);
T update(final T entity);
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/model/Bar.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/model/Bar.java
similarity index 98%
rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/model/Bar.java
rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/model/Bar.java
index b602e57562..5a88ecc6cf 100644
--- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/model/Bar.java
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/model/Bar.java
@@ -1,4 +1,4 @@
-package org.baeldung.persistence.model;
+package com.baeldung.persistence.model;
import java.io.Serializable;
import java.util.List;
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/model/Foo.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/model/Foo.java
similarity index 98%
rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/model/Foo.java
rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/model/Foo.java
index 30635e9ef2..009876f8cb 100644
--- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/model/Foo.java
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/model/Foo.java
@@ -1,4 +1,4 @@
-package org.baeldung.persistence.model;
+package com.baeldung.persistence.model;
import java.io.Serializable;
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/service/FooService.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/service/FooService.java
similarity index 81%
rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/service/FooService.java
rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/service/FooService.java
index 6d1bb0adbe..efe9743670 100644
--- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/service/FooService.java
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/service/FooService.java
@@ -1,9 +1,9 @@
-package org.baeldung.persistence.service;
+package com.baeldung.persistence.service;
import java.util.List;
-import org.baeldung.persistence.dao.IFooDao;
-import org.baeldung.persistence.model.Foo;
+import com.baeldung.jpa.dao.IFooDao;
+import com.baeldung.persistence.model.Foo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/config/PersistenceConfig.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/config/PersistenceConfig.java
new file mode 100644
index 0000000000..717b9c3aa0
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/config/PersistenceConfig.java
@@ -0,0 +1,85 @@
+package com.baeldung.spring.data.persistence.config;
+
+import java.util.Properties;
+
+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.annotation.EnableTransactionManagement;
+
+import com.google.common.base.Preconditions;
+
+@Configuration
+@EnableTransactionManagement
+@PropertySource({ "classpath:persistence-${envTarget:h2}.properties" })
+@ComponentScan({ "com.baeldung.spring.data.persistence" })
+// @ImportResource("classpath*:springDataPersistenceConfig.xml")
+@EnableJpaRepositories(basePackages = "com.baeldung.spring.data.persistence.dao")
+public class PersistenceConfig {
+
+ @Autowired
+ private Environment env;
+
+ public PersistenceConfig() {
+ super();
+ }
+
+ @Bean
+ public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
+ final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
+ em.setDataSource(dataSource());
+ em.setPackagesToScan(new String[] { "com.baeldung.spring.data.persistence.model" });
+
+ final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
+ // vendorAdapter.set
+ 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 JpaTransactionManager transactionManager = new JpaTransactionManager();
+ transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
+
+ 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.globally_quoted_identifiers", "true");
+ return hibernateProperties;
+ }
+
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/IFooDao.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/IFooDao.java
new file mode 100644
index 0000000000..d2b746dc8b
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/IFooDao.java
@@ -0,0 +1,11 @@
+package com.baeldung.spring.data.persistence.dao;
+
+import com.baeldung.spring.data.persistence.model.Foo;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+public interface IFooDao extends JpaRepository {
+
+ @Query("SELECT f FROM Foo f WHERE LOWER(f.name) = LOWER(:name)")
+ Foo retrieveByName(@Param("name") String name);
+}
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/user/UserRepository.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/user/UserRepository.java
new file mode 100644
index 0000000000..e8f95302ef
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/user/UserRepository.java
@@ -0,0 +1,98 @@
+package com.baeldung.spring.data.persistence.dao.user;
+
+import java.time.LocalDate;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Stream;
+
+import com.baeldung.spring.data.persistence.model.User;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+public interface UserRepository extends JpaRepository, UserRepositoryCustom {
+
+ Stream findAllByName(String name);
+
+ @Query("SELECT u FROM User u WHERE u.status = 1")
+ Collection findAllActiveUsers();
+
+ @Query("select u from User u where u.email like '%@gmail.com'")
+ List findUsersWithGmailAddress();
+
+ @Query(value = "SELECT * FROM Users u WHERE u.status = 1", nativeQuery = true)
+ Collection findAllActiveUsersNative();
+
+ @Query("SELECT u FROM User u WHERE u.status = ?1")
+ User findUserByStatus(Integer status);
+
+ @Query(value = "SELECT * FROM Users u WHERE u.status = ?1", nativeQuery = true)
+ User findUserByStatusNative(Integer status);
+
+ @Query("SELECT u FROM User u WHERE u.status = ?1 and u.name = ?2")
+ User findUserByStatusAndName(Integer status, String name);
+
+ @Query("SELECT u FROM User u WHERE u.status = :status and u.name = :name")
+ User findUserByStatusAndNameNamedParams(@Param("status") Integer status, @Param("name") String name);
+
+ @Query(value = "SELECT * FROM Users u WHERE u.status = :status AND u.name = :name", nativeQuery = true)
+ User findUserByStatusAndNameNamedParamsNative(@Param("status") Integer status, @Param("name") String name);
+
+ @Query("SELECT u FROM User u WHERE u.status = :status and u.name = :name")
+ User findUserByUserStatusAndUserName(@Param("status") Integer userStatus, @Param("name") String userName);
+
+ @Query("SELECT u FROM User u WHERE u.name like ?1%")
+ User findUserByNameLike(String name);
+
+ @Query("SELECT u FROM User u WHERE u.name like :name%")
+ User findUserByNameLikeNamedParam(@Param("name") String name);
+
+ @Query(value = "SELECT * FROM users u WHERE u.name LIKE ?1%", nativeQuery = true)
+ User findUserByNameLikeNative(String name);
+
+ @Query(value = "SELECT u FROM User u")
+ List findAllUsers(Sort sort);
+
+ @Query(value = "SELECT u FROM User u ORDER BY id")
+ Page findAllUsersWithPagination(Pageable pageable);
+
+ @Query(value = "SELECT * FROM Users ORDER BY id", countQuery = "SELECT count(*) FROM Users", nativeQuery = true)
+ Page findAllUsersWithPaginationNative(Pageable pageable);
+
+ @Modifying
+ @Query("update User u set u.status = :status where u.name = :name")
+ int updateUserSetStatusForName(@Param("status") Integer status, @Param("name") String name);
+
+ @Modifying
+ @Query(value = "UPDATE Users u SET u.status = ? WHERE u.name = ?", nativeQuery = true)
+ int updateUserSetStatusForNameNative(Integer status, String name);
+
+ @Query(value = "INSERT INTO Users (name, age, email, status, active) VALUES (:name, :age, :email, :status, :active)", nativeQuery = true)
+ @Modifying
+ void insertUser(@Param("name") String name, @Param("age") Integer age, @Param("email") String email, @Param("status") Integer status, @Param("active") boolean active);
+
+ @Modifying
+ @Query(value = "UPDATE Users u SET status = ? WHERE u.name = ?", nativeQuery = true)
+ int updateUserSetStatusForNameNativePostgres(Integer status, String name);
+
+ @Query(value = "SELECT u FROM User u WHERE u.name IN :names")
+ List findUserByNameList(@Param("names") Collection names);
+
+ void deleteAllByCreationDateAfter(LocalDate date);
+
+ @Modifying(clearAutomatically = true, flushAutomatically = true)
+ @Query("update User u set u.active = false where u.lastLoginDate < :date")
+ void deactivateUsersNotLoggedInSince(@Param("date") LocalDate date);
+
+ @Modifying(clearAutomatically = true, flushAutomatically = true)
+ @Query("delete User u where u.active = false")
+ int deleteDeactivatedUsers();
+
+ @Modifying(clearAutomatically = true, flushAutomatically = true)
+ @Query(value = "alter table USERS add column deleted int(1) not null default 0", nativeQuery = true)
+ void addDeletedColumn();
+}
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/user/UserRepositoryCustom.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/user/UserRepositoryCustom.java
new file mode 100644
index 0000000000..ff92159077
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/user/UserRepositoryCustom.java
@@ -0,0 +1,14 @@
+package com.baeldung.spring.data.persistence.dao.user;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Predicate;
+
+import com.baeldung.spring.data.persistence.model.User;
+
+public interface UserRepositoryCustom {
+ List findUserByEmails(Set emails);
+
+ List findAllUsersByPredicates(Collection> predicates);
+}
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/user/UserRepositoryCustomImpl.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/user/UserRepositoryCustomImpl.java
new file mode 100644
index 0000000000..8bd8217e83
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/user/UserRepositoryCustomImpl.java
@@ -0,0 +1,57 @@
+package com.baeldung.spring.data.persistence.dao.user;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Path;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import com.baeldung.spring.data.persistence.model.User;
+
+public class UserRepositoryCustomImpl implements UserRepositoryCustom {
+
+ @PersistenceContext
+ private EntityManager entityManager;
+
+ @Override
+ public List findUserByEmails(Set emails) {
+ CriteriaBuilder cb = entityManager.getCriteriaBuilder();
+ CriteriaQuery query = cb.createQuery(User.class);
+ Root user = query.from(User.class);
+
+ Path emailPath = user.get("email");
+
+ List predicates = new ArrayList<>();
+ for (String email : emails) {
+
+ predicates.add(cb.like(emailPath, email));
+
+ }
+ query.select(user)
+ .where(cb.or(predicates.toArray(new Predicate[predicates.size()])));
+
+ return entityManager.createQuery(query)
+ .getResultList();
+ }
+
+ @Override
+ public List findAllUsersByPredicates(Collection> predicates) {
+ List allUsers = entityManager.createQuery("select u from User u", User.class).getResultList();
+ Stream allUsersStream = allUsers.stream();
+ for (java.util.function.Predicate predicate : predicates) {
+ allUsersStream = allUsersStream.filter(predicate);
+ }
+
+ return allUsersStream.collect(Collectors.toList());
+ }
+
+}
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/model/Foo.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/model/Foo.java
new file mode 100644
index 0000000000..64bfe203d0
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/model/Foo.java
@@ -0,0 +1,83 @@
+package com.baeldung.spring.data.persistence.model;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+public class Foo implements Serializable {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private long id;
+
+ @Column(nullable = false)
+ private String name;
+
+ public Foo() {
+ super();
+ }
+
+ public Foo(final String name) {
+ super();
+
+ this.name = name;
+ }
+
+ // API
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(final long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ //
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final Foo other = (Foo) obj;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("Foo [name=").append(name).append("]");
+ return builder.toString();
+ }
+
+}
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/model/Possession.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/model/Possession.java
new file mode 100644
index 0000000000..44ca9fc62e
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/model/Possession.java
@@ -0,0 +1,86 @@
+package com.baeldung.spring.data.persistence.model;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table
+public class Possession {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ private String name;
+
+ public Possession() {
+ super();
+ }
+
+ public Possession(final String name) {
+ super();
+
+ this.name = name;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(final int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = (prime * result) + (int) (id ^ (id >>> 32));
+ result = (prime * result) + ((name == null) ? 0 : name.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final Possession other = (Possession) obj;
+ if (id != other.id) {
+ return false;
+ }
+ if (name == null) {
+ if (other.name != null) {
+ return false;
+ }
+ } else if (!name.equals(other.name)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("Possesion [id=").append(id).append(", name=").append(name).append("]");
+ return builder.toString();
+ }
+
+}
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/model/User.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/model/User.java
new file mode 100644
index 0000000000..09f1092644
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/model/User.java
@@ -0,0 +1,132 @@
+package com.baeldung.spring.data.persistence.model;
+
+import javax.persistence.*;
+
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Objects;
+
+@Entity
+@Table(name = "users")
+public class User {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private int id;
+ private String name;
+ private LocalDate creationDate;
+ private LocalDate lastLoginDate;
+ private boolean active;
+ private int age;
+ @Column(unique = true, nullable = false)
+ private String email;
+ private Integer status;
+ @OneToMany
+ List possessionList;
+
+ public User() {
+ super();
+ }
+
+ public User(String name, LocalDate creationDate,String email, Integer status) {
+ this.name = name;
+ this.creationDate = creationDate;
+ this.email = email;
+ this.status = status;
+ this.active = true;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(final int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(final String email) {
+ this.email = email;
+ }
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public void setStatus(Integer status) {
+ this.status = status;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(final int age) {
+ this.age = age;
+ }
+
+ public LocalDate getCreationDate() {
+ return creationDate;
+ }
+
+ public List getPossessionList() {
+ return possessionList;
+ }
+
+ public void setPossessionList(List possessionList) {
+ this.possessionList = possessionList;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("User [name=").append(name).append(", id=").append(id).append("]");
+ return builder.toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ User user = (User) o;
+ return id == user.id &&
+ age == user.age &&
+ Objects.equals(name, user.name) &&
+ Objects.equals(creationDate, user.creationDate) &&
+ Objects.equals(email, user.email) &&
+ Objects.equals(status, user.status);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, name, creationDate, age, email, status);
+ }
+
+ public LocalDate getLastLoginDate() {
+ return lastLoginDate;
+ }
+
+ public void setLastLoginDate(LocalDate lastLoginDate) {
+ this.lastLoginDate = lastLoginDate;
+ }
+
+ public boolean isActive() {
+ return active;
+ }
+
+ public void setActive(boolean active) {
+ this.active = active;
+ }
+
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/service/IFooService.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/service/IFooService.java
new file mode 100644
index 0000000000..00e7ac01e4
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/service/IFooService.java
@@ -0,0 +1,11 @@
+package com.baeldung.spring.data.persistence.service;
+
+import com.baeldung.spring.data.persistence.model.Foo;
+
+import com.baeldung.persistence.dao.common.IOperations;
+
+public interface IFooService extends IOperations {
+
+ Foo retrieveByName(String name);
+
+}
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/service/common/AbstractService.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/service/common/AbstractService.java
new file mode 100644
index 0000000000..61c7d6fcaa
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/service/common/AbstractService.java
@@ -0,0 +1,56 @@
+package com.baeldung.spring.data.persistence.service.common;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.springframework.data.repository.PagingAndSortingRepository;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.baeldung.persistence.dao.common.IOperations;
+import com.google.common.collect.Lists;
+
+@Transactional
+public abstract class AbstractService implements IOperations {
+
+ // read - one
+
+ @Override
+ @Transactional(readOnly = true)
+ public T findOne(final long id) {
+ return getDao().findById(id).orElse(null);
+ }
+
+ // read - all
+
+ @Override
+ @Transactional(readOnly = true)
+ public List findAll() {
+ return Lists.newArrayList(getDao().findAll());
+ }
+
+ // write
+
+ @Override
+ public T create(final T entity) {
+ return getDao().save(entity);
+ }
+
+ @Override
+ public T update(final T entity) {
+ return getDao().save(entity);
+ }
+
+ @Override
+ public void delete(T entity) {
+ getDao().delete(entity);
+ }
+
+ @Override
+ public void deleteById(long entityId) {
+ T entity = findOne(entityId);
+ delete(entity);
+ }
+
+ protected abstract PagingAndSortingRepository getDao();
+
+}
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/service/impl/FooService.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/service/impl/FooService.java
new file mode 100644
index 0000000000..cd566ba9f6
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/service/impl/FooService.java
@@ -0,0 +1,38 @@
+package com.baeldung.spring.data.persistence.service.impl;
+
+
+import com.baeldung.spring.data.persistence.model.Foo;
+import com.baeldung.spring.data.persistence.dao.IFooDao;
+import com.baeldung.spring.data.persistence.service.IFooService;
+import com.baeldung.spring.data.persistence.service.common.AbstractService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.repository.PagingAndSortingRepository;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@Transactional
+public class FooService extends AbstractService implements IFooService {
+
+ @Autowired
+ private IFooDao dao;
+
+ public FooService() {
+ super();
+ }
+
+ // API
+
+ @Override
+ protected PagingAndSortingRepository getDao() {
+ return dao;
+ }
+
+ // custom methods
+
+ @Override
+ public Foo retrieveByName(final String name) {
+ return dao.retrieveByName(name);
+ }
+
+}
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/util/IDUtil.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/util/IDUtil.java
new file mode 100644
index 0000000000..45e72e046d
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/util/IDUtil.java
@@ -0,0 +1,33 @@
+package com.baeldung.util;
+
+import java.util.Random;
+
+public final class IDUtil {
+
+ private IDUtil() {
+ throw new AssertionError();
+ }
+
+ // API
+
+ public static String randomPositiveLongAsString() {
+ return Long.toString(randomPositiveLong());
+ }
+
+ public static String randomNegativeLongAsString() {
+ return Long.toString(randomNegativeLong());
+ }
+
+ public static long randomPositiveLong() {
+ long id = new Random().nextLong() * 10000;
+ id = (id < 0) ? (-1 * id) : id;
+ return id;
+ }
+
+ private static long randomNegativeLong() {
+ long id = new Random().nextLong() * 10000;
+ id = (id > 0) ? (-1 * id) : id;
+ return id;
+ }
+
+}
diff --git a/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/schema.sql b/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/schema.sql
new file mode 100644
index 0000000000..c86d35cdae
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/schema.sql
@@ -0,0 +1,7 @@
+CREATE TABLE EMPLOYEE
+(
+ ID int NOT NULL PRIMARY KEY,
+ FIRST_NAME varchar(255),
+ LAST_NAME varchar(255),
+ ADDRESS varchar(255),
+);
\ No newline at end of file
diff --git a/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/springJdbc-config.xml b/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/springJdbc-config.xml
new file mode 100644
index 0000000000..e3d7452eb1
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/springJdbc-config.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/test-data.sql b/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/test-data.sql
new file mode 100644
index 0000000000..b9ef8fec25
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/test-data.sql
@@ -0,0 +1,7 @@
+INSERT INTO EMPLOYEE VALUES (1, 'James', 'Gosling', 'Canada');
+
+INSERT INTO EMPLOYEE VALUES (2, 'Donald', 'Knuth', 'USA');
+
+INSERT INTO EMPLOYEE VALUES (3, 'Linus', 'Torvalds', 'Finland');
+
+INSERT INTO EMPLOYEE VALUES (4, 'Dennis', 'Ritchie', 'USA');
\ No newline at end of file
diff --git a/persistence-modules/spring-persistence-simple/src/main/resources/persistence.xml b/persistence-modules/spring-persistence-simple/src/main/resources/persistence.xml
index 6304fa0a65..57687c306d 100644
--- a/persistence-modules/spring-persistence-simple/src/main/resources/persistence.xml
+++ b/persistence-modules/spring-persistence-simple/src/main/resources/persistence.xml
@@ -11,7 +11,7 @@
-
+
- 2.21.0
+ 2.22.0
3.7.0
1.6.0
1.8
@@ -1549,8 +1548,8 @@
1.2
2.9.8
1.3
- 1.2.0
- 5.2.0
+ 1.4.2
+ 5.4.2
0.3.1
2.5.1
0.0.1
diff --git a/spring-5-webflux/pom.xml b/spring-5-webflux/pom.xml
index 3306fd1729..c1f537d2fe 100644
--- a/spring-5-webflux/pom.xml
+++ b/spring-5-webflux/pom.xml
@@ -28,12 +28,22 @@
+
+ 1.8
+ 2.2.0.M3
+
+
org.springframework.boot
spring-boot-starter-webflux
+
+ org.springframework.boot
+ spring-boot-starter-rsocket
+
+
org.projectlombok
lombok
@@ -46,8 +56,8 @@
- junit
- junit
+ io.projectreactor
+ reactor-test
test
@@ -60,4 +70,35 @@
+
+
+
+ spring-snapshots
+ Spring Snapshots
+ https://repo.spring.io/snapshot
+
+ true
+
+
+
+ spring-milestones
+ Spring Milestones
+ https://repo.spring.io/milestone
+
+
+
+
+ spring-snapshots
+ Spring Snapshots
+ https://repo.spring.io/snapshot
+
+ true
+
+
+
+ spring-milestones
+ Spring Milestones
+ https://repo.spring.io/milestone
+
+
diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/ClientApplication.java b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/ClientApplication.java
new file mode 100644
index 0000000000..6f35ec5ee0
--- /dev/null
+++ b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/ClientApplication.java
@@ -0,0 +1,16 @@
+package com.baeldung.spring.rsocket.client;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+
+@SpringBootApplication
+public class ClientApplication {
+
+ public static void main(String[] args) {
+ new SpringApplicationBuilder()
+ .main(ClientApplication.class)
+ .sources(ClientApplication.class)
+ .profiles("client")
+ .run(args);
+ }
+}
diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/ClientConfiguration.java b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/ClientConfiguration.java
new file mode 100644
index 0000000000..7dd3591cd6
--- /dev/null
+++ b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/ClientConfiguration.java
@@ -0,0 +1,30 @@
+package com.baeldung.spring.rsocket.client;
+
+import io.rsocket.RSocket;
+import io.rsocket.RSocketFactory;
+import io.rsocket.frame.decoder.PayloadDecoder;
+import io.rsocket.transport.netty.client.TcpClientTransport;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.rsocket.RSocketRequester;
+import org.springframework.messaging.rsocket.RSocketStrategies;
+import org.springframework.util.MimeTypeUtils;
+
+@Configuration
+public class ClientConfiguration {
+
+ @Bean
+ public RSocket rSocket() {
+ return RSocketFactory.connect()
+ .mimeType(MimeTypeUtils.APPLICATION_JSON_VALUE, MimeTypeUtils.APPLICATION_JSON_VALUE)
+ .frameDecoder(PayloadDecoder.ZERO_COPY)
+ .transport(TcpClientTransport.create(7000))
+ .start()
+ .block();
+ }
+
+ @Bean
+ RSocketRequester rSocketRequester(RSocketStrategies rSocketStrategies) {
+ return RSocketRequester.wrap(rSocket(), MimeTypeUtils.APPLICATION_JSON, rSocketStrategies);
+ }
+}
diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/MarketDataRestController.java b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/MarketDataRestController.java
new file mode 100644
index 0000000000..3701bd69e9
--- /dev/null
+++ b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/MarketDataRestController.java
@@ -0,0 +1,47 @@
+package com.baeldung.spring.rsocket.client;
+
+import com.baeldung.spring.rsocket.model.MarketData;
+import com.baeldung.spring.rsocket.model.MarketDataRequest;
+import java.util.Random;
+import org.reactivestreams.Publisher;
+import org.springframework.http.MediaType;
+import org.springframework.messaging.rsocket.RSocketRequester;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class MarketDataRestController {
+
+ private final Random random = new Random();
+ private final RSocketRequester rSocketRequester;
+
+ public MarketDataRestController(RSocketRequester rSocketRequester) {
+ this.rSocketRequester = rSocketRequester;
+ }
+
+ @GetMapping(value = "/current/{stock}")
+ public Publisher current(@PathVariable("stock") String stock) {
+ return rSocketRequester.route("currentMarketData")
+ .data(new MarketDataRequest(stock))
+ .retrieveMono(MarketData.class);
+ }
+
+ @GetMapping(value = "/feed/{stock}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
+ public Publisher feed(@PathVariable("stock") String stock) {
+ return rSocketRequester.route("feedMarketData")
+ .data(new MarketDataRequest(stock))
+ .retrieveFlux(MarketData.class);
+ }
+
+ @GetMapping(value = "/collect")
+ public Publisher collect() {
+ return rSocketRequester.route("collectMarketData")
+ .data(getMarketData())
+ .send();
+ }
+
+ private MarketData getMarketData() {
+ return new MarketData("X", random.nextInt(10));
+ }
+}
diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/model/MarketData.java b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/model/MarketData.java
new file mode 100644
index 0000000000..3eeaf449e9
--- /dev/null
+++ b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/model/MarketData.java
@@ -0,0 +1,20 @@
+package com.baeldung.spring.rsocket.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class MarketData {
+
+ private String stock;
+ private int currentPrice;
+
+ public static MarketData fromException(Exception e) {
+ MarketData marketData = new MarketData();
+ marketData.setStock(e.getMessage());
+ return marketData;
+ }
+}
diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/model/MarketDataRequest.java b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/model/MarketDataRequest.java
new file mode 100644
index 0000000000..1debbb0870
--- /dev/null
+++ b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/model/MarketDataRequest.java
@@ -0,0 +1,13 @@
+package com.baeldung.spring.rsocket.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class MarketDataRequest {
+
+ private String stock;
+}
diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/server/MarketDataRSocketController.java b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/server/MarketDataRSocketController.java
new file mode 100644
index 0000000000..1ff23966fa
--- /dev/null
+++ b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/server/MarketDataRSocketController.java
@@ -0,0 +1,40 @@
+package com.baeldung.spring.rsocket.server;
+
+import com.baeldung.spring.rsocket.model.MarketData;
+import com.baeldung.spring.rsocket.model.MarketDataRequest;
+import org.springframework.messaging.handler.annotation.MessageExceptionHandler;
+import org.springframework.messaging.handler.annotation.MessageMapping;
+import org.springframework.stereotype.Controller;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+@Controller
+public class MarketDataRSocketController {
+
+ private final MarketDataRepository marketDataRepository;
+
+ public MarketDataRSocketController(MarketDataRepository marketDataRepository) {
+ this.marketDataRepository = marketDataRepository;
+ }
+
+ @MessageMapping("currentMarketData")
+ public Mono currentMarketData(MarketDataRequest marketDataRequest) {
+ return marketDataRepository.getOne(marketDataRequest.getStock());
+ }
+
+ @MessageMapping("feedMarketData")
+ public Flux feedMarketData(MarketDataRequest marketDataRequest) {
+ return marketDataRepository.getAll(marketDataRequest.getStock());
+ }
+
+ @MessageMapping("collectMarketData")
+ public Mono collectMarketData(MarketData marketData) {
+ marketDataRepository.add(marketData);
+ return Mono.empty();
+ }
+
+ @MessageExceptionHandler
+ public Mono handleException(Exception e) {
+ return Mono.just(MarketData.fromException(e));
+ }
+}
diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/server/MarketDataRepository.java b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/server/MarketDataRepository.java
new file mode 100644
index 0000000000..4f30c36c2f
--- /dev/null
+++ b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/server/MarketDataRepository.java
@@ -0,0 +1,37 @@
+package com.baeldung.spring.rsocket.server;
+
+import com.baeldung.spring.rsocket.model.MarketData;
+import java.time.Duration;
+import java.util.Random;
+import java.util.stream.Stream;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+@Slf4j
+@Component
+public class MarketDataRepository {
+
+ private static final int BOUND = 100;
+
+ private Random random = new Random();
+
+ public Flux getAll(String stock) {
+ return Flux.fromStream(Stream.generate(() -> getMarketDataResponse(stock)))
+ .log()
+ .delayElements(Duration.ofSeconds(1));
+ }
+
+ public Mono getOne(String stock) {
+ return Mono.just(getMarketDataResponse(stock));
+ }
+
+ public void add(MarketData marketData) {
+ log.info("New market data: {}", marketData);
+ }
+
+ private MarketData getMarketDataResponse(String stock) {
+ return new MarketData(stock, random.nextInt(BOUND));
+ }
+}
diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/server/ServerApplication.java b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/server/ServerApplication.java
new file mode 100644
index 0000000000..4213e315dd
--- /dev/null
+++ b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/server/ServerApplication.java
@@ -0,0 +1,16 @@
+package com.baeldung.spring.rsocket.server;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+
+@SpringBootApplication
+public class ServerApplication {
+
+ public static void main(String[] args) {
+ new SpringApplicationBuilder()
+ .main(ServerApplication.class)
+ .sources(ServerApplication.class)
+ .profiles("server")
+ .run(args);
+ }
+}
diff --git a/spring-5-webflux/src/main/resources/application-client.properties b/spring-5-webflux/src/main/resources/application-client.properties
new file mode 100644
index 0000000000..4c00e40deb
--- /dev/null
+++ b/spring-5-webflux/src/main/resources/application-client.properties
@@ -0,0 +1 @@
+server.port=8080
diff --git a/spring-5-webflux/src/main/resources/application-server.properties b/spring-5-webflux/src/main/resources/application-server.properties
new file mode 100644
index 0000000000..1e343b5bf5
--- /dev/null
+++ b/spring-5-webflux/src/main/resources/application-server.properties
@@ -0,0 +1,2 @@
+spring.rsocket.server.port=7000
+server.port=8081
diff --git a/spring-5-webflux/src/test/java/com/baeldung/spring/rsocket/client/MarketDataRestControllerIntegrationTest.java b/spring-5-webflux/src/test/java/com/baeldung/spring/rsocket/client/MarketDataRestControllerIntegrationTest.java
new file mode 100644
index 0000000000..ff00d5ec24
--- /dev/null
+++ b/spring-5-webflux/src/test/java/com/baeldung/spring/rsocket/client/MarketDataRestControllerIntegrationTest.java
@@ -0,0 +1,92 @@
+package com.baeldung.spring.rsocket.client;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+import static org.springframework.http.MediaType.TEXT_EVENT_STREAM;
+
+import com.baeldung.spring.rsocket.model.MarketData;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.messaging.rsocket.RSocketRequester;
+import org.springframework.messaging.rsocket.RSocketRequester.RequestSpec;
+import org.springframework.messaging.rsocket.RSocketRequester.ResponseSpec;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.reactive.server.FluxExchangeResult;
+import org.springframework.test.web.reactive.server.WebTestClient;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+import reactor.test.StepVerifier;
+
+@RunWith(SpringRunner.class)
+@WebFluxTest(value = MarketDataRestController.class)
+public class MarketDataRestControllerIntegrationTest {
+
+ @Autowired
+ private WebTestClient testClient;
+
+ @MockBean
+ private RSocketRequester rSocketRequester;
+
+ @Mock
+ private RequestSpec requestSpec;
+
+ @Mock
+ private ResponseSpec responseSpec;
+
+ @Test
+ public void whenInitiatesRequest_ThenGetsResponse() throws Exception {
+ when(rSocketRequester.route("currentMarketData")).thenReturn(requestSpec);
+ when(requestSpec.data(any())).thenReturn(responseSpec);
+ MarketData marketData = new MarketData("X", 1);
+ when(responseSpec.retrieveMono(MarketData.class)).thenReturn(Mono.just(marketData));
+
+ testClient.get()
+ .uri("/current/{stock}", "X")
+ .exchange()
+ .expectStatus()
+ .isOk()
+ .expectBody(MarketData.class)
+ .isEqualTo(marketData);
+ }
+
+ @Test
+ public void whenInitiatesFireAndForget_ThenGetsNoResponse() throws Exception {
+ when(rSocketRequester.route("collectMarketData")).thenReturn(requestSpec);
+ when(requestSpec.data(any())).thenReturn(responseSpec);
+ when(responseSpec.send()).thenReturn(Mono.empty());
+
+ testClient.get()
+ .uri("/collect")
+ .exchange()
+ .expectStatus()
+ .isOk()
+ .expectBody(Void.class);
+ }
+
+ @Test
+ public void whenInitiatesRequest_ThenGetsStream() throws Exception {
+ when(rSocketRequester.route("feedMarketData")).thenReturn(requestSpec);
+ when(requestSpec.data(any())).thenReturn(responseSpec);
+ MarketData firstMarketData = new MarketData("X", 1);
+ MarketData secondMarketData = new MarketData("X", 2);
+ when(responseSpec.retrieveFlux(MarketData.class)).thenReturn(Flux.just(firstMarketData, secondMarketData));
+
+ FluxExchangeResult result = testClient.get()
+ .uri("/feed/{stock}", "X")
+ .accept(TEXT_EVENT_STREAM)
+ .exchange()
+ .expectStatus()
+ .isOk()
+ .returnResult(MarketData.class);
+ Flux marketDataFlux = result.getResponseBody();
+ StepVerifier.create(marketDataFlux)
+ .expectNext(firstMarketData)
+ .expectNext(secondMarketData)
+ .thenCancel()
+ .verify();
+ }
+}
\ No newline at end of file
diff --git a/spring-5-webflux/src/test/java/com/baeldung/spring/rsocket/server/MarketDataRSocketControllerLiveTest.java b/spring-5-webflux/src/test/java/com/baeldung/spring/rsocket/server/MarketDataRSocketControllerLiveTest.java
new file mode 100644
index 0000000000..dcf3b82730
--- /dev/null
+++ b/spring-5-webflux/src/test/java/com/baeldung/spring/rsocket/server/MarketDataRSocketControllerLiveTest.java
@@ -0,0 +1,98 @@
+package com.baeldung.spring.rsocket.server;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
+
+import com.baeldung.spring.rsocket.model.MarketData;
+import com.baeldung.spring.rsocket.model.MarketDataRequest;
+import io.rsocket.RSocket;
+import io.rsocket.RSocketFactory;
+import io.rsocket.frame.decoder.PayloadDecoder;
+import io.rsocket.transport.netty.client.TcpClientTransport;
+import java.time.Duration;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.boot.test.mock.mockito.SpyBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.messaging.rsocket.RSocketRequester;
+import org.springframework.messaging.rsocket.RSocketStrategies;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.util.MimeTypeUtils;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+@TestPropertySource(properties = {"spring.rsocket.server.port=7000"})
+public class MarketDataRSocketControllerLiveTest {
+
+ @Autowired
+ private RSocketRequester rSocketRequester;
+
+ @SpyBean
+ private MarketDataRSocketController rSocketController;
+
+ @Test
+ public void whenGetsFireAndForget_ThenReturnsNoResponse() throws InterruptedException {
+ final MarketData marketData = new MarketData("X", 1);
+ rSocketRequester.route("collectMarketData")
+ .data(marketData)
+ .send()
+ .block(Duration.ofSeconds(10));
+
+ sleepForProcessing();
+ verify(rSocketController).collectMarketData(any());
+ }
+
+ @Test
+ public void whenGetsRequest_ThenReturnsResponse() throws InterruptedException {
+ final MarketDataRequest marketDataRequest = new MarketDataRequest("X");
+ rSocketRequester.route("currentMarketData")
+ .data(marketDataRequest)
+ .send()
+ .block(Duration.ofSeconds(10));
+
+ sleepForProcessing();
+ verify(rSocketController).currentMarketData(any());
+ }
+
+ @Test
+ public void whenGetsRequest_ThenReturnsStream() throws InterruptedException {
+ final MarketDataRequest marketDataRequest = new MarketDataRequest("X");
+ rSocketRequester.route("feedMarketData")
+ .data(marketDataRequest)
+ .send()
+ .block(Duration.ofSeconds(10));
+
+ sleepForProcessing();
+ verify(rSocketController).feedMarketData(any());
+ }
+
+ private void sleepForProcessing() throws InterruptedException {
+ Thread.sleep(1000);
+ }
+
+ @TestConfiguration
+ public static class ClientConfiguration {
+
+ @Bean
+ @Lazy
+ public RSocket rSocket() {
+ return RSocketFactory.connect()
+ .mimeType(MimeTypeUtils.APPLICATION_JSON_VALUE, MimeTypeUtils.APPLICATION_JSON_VALUE)
+ .frameDecoder(PayloadDecoder.ZERO_COPY)
+ .transport(TcpClientTransport.create(7000))
+ .start()
+ .block();
+ }
+
+ @Bean
+ @Lazy
+ RSocketRequester rSocketRequester(RSocketStrategies rSocketStrategies) {
+ return RSocketRequester.wrap(rSocket(), MimeTypeUtils.APPLICATION_JSON, rSocketStrategies);
+ }
+ }
+}
\ No newline at end of file
diff --git a/spring-5-webflux/src/test/java/com/baeldung/spring/webclientrequests/WebClientRequestsUnitTest.java b/spring-5-webflux/src/test/java/com/baeldung/spring/webclientrequests/WebClientRequestsUnitTest.java
index 8919daa9fb..353cb24d0a 100644
--- a/spring-5-webflux/src/test/java/com/baeldung/spring/webclientrequests/WebClientRequestsUnitTest.java
+++ b/spring-5-webflux/src/test/java/com/baeldung/spring/webclientrequests/WebClientRequestsUnitTest.java
@@ -1,5 +1,10 @@
package com.baeldung.spring.webclientrequests;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import java.time.Duration;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -17,8 +22,6 @@ import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.DefaultUriBuilderFactory;
import reactor.core.publisher.Mono;
-import static org.mockito.Mockito.*;
-
@RunWith(SpringRunner.class)
@WebFluxTest
public class WebClientRequestsUnitTest {
@@ -50,7 +53,8 @@ public class WebClientRequestsUnitTest {
public void whenCallSimpleURI_thenURIMatched() {
this.webClient.get()
.uri("/products")
- .retrieve();
+ .exchange()
+ .block(Duration.ofSeconds(1));
verifyCalledUrl("/products");
}
@@ -60,7 +64,8 @@ public class WebClientRequestsUnitTest {
.uri(uriBuilder -> uriBuilder
.path("/products/{id}")
.build(2))
- .retrieve();
+ .exchange()
+ .block(Duration.ofSeconds(1));
verifyCalledUrl("/products/2");
}
@@ -70,7 +75,8 @@ public class WebClientRequestsUnitTest {
.uri(uriBuilder -> uriBuilder
.path("/products/{id}/attributes/{attributeId}")
.build(2, 13))
- .retrieve();
+ .exchange()
+ .block(Duration.ofSeconds(1));
verifyCalledUrl("/products/2/attributes/13");
}
@@ -83,7 +89,8 @@ public class WebClientRequestsUnitTest {
.queryParam("color", "black")
.queryParam("deliveryDate", "13/04/2019")
.build())
- .retrieve();
+ .exchange()
+ .block(Duration.ofSeconds(1));
verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13/04/2019");
}
@@ -96,7 +103,8 @@ public class WebClientRequestsUnitTest {
.queryParam("color", "{authorId}")
.queryParam("deliveryDate", "{date}")
.build("AndroidPhone", "black", "13/04/2019"))
- .retrieve();
+ .exchange()
+ .block(Duration.ofSeconds(1));
verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13%2F04%2F2019");
}
@@ -107,7 +115,8 @@ public class WebClientRequestsUnitTest {
.path("/products/")
.queryParam("tag[]", "Snapdragon", "NFC")
.build())
- .retrieve();
+ .exchange()
+ .block(Duration.ofSeconds(1));
verifyCalledUrl("/products/?tag%5B%5D=Snapdragon&tag%5B%5D=NFC");
}
@@ -119,7 +128,8 @@ public class WebClientRequestsUnitTest {
.path("/products/")
.queryParam("category", "Phones", "Tablets")
.build())
- .retrieve();
+ .exchange()
+ .block(Duration.ofSeconds(1));
verifyCalledUrl("/products/?category=Phones&category=Tablets");
}
@@ -130,7 +140,8 @@ public class WebClientRequestsUnitTest {
.path("/products/")
.queryParam("category", String.join(",", "Phones", "Tablets"))
.build())
- .retrieve();
+ .exchange()
+ .block(Duration.ofSeconds(1));
verifyCalledUrl("/products/?category=Phones,Tablets");
}
@@ -151,7 +162,8 @@ public class WebClientRequestsUnitTest {
.queryParam("color", "black")
.queryParam("deliveryDate", "13/04/2019")
.build())
- .retrieve();
+ .exchange()
+ .block(Duration.ofSeconds(1));
verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13/04/2019");
}
diff --git a/spring-all/README.md b/spring-all/README.md
index b0805e5477..b5e91d8d60 100644
--- a/spring-all/README.md
+++ b/spring-all/README.md
@@ -33,5 +33,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Spring @Primary Annotation](http://www.baeldung.com/spring-primary)
- [Spring Events](https://www.baeldung.com/spring-events)
- [Spring Null-Safety Annotations](https://www.baeldung.com/spring-null-safety-annotations)
-- [Spring JDBC](https://www.baeldung.com/spring-jdbc-jdbctemplate)
- [Using @Autowired in Abstract Classes](https://www.baeldung.com/spring-autowired-abstract-class)
diff --git a/spring-cloud/spring-cloud-contract/pom.xml b/spring-cloud/spring-cloud-contract/pom.xml
index 4d4e8ad2c3..ea71891648 100644
--- a/spring-cloud/spring-cloud-contract/pom.xml
+++ b/spring-cloud/spring-cloud-contract/pom.xml
@@ -19,4 +19,45 @@
spring-cloud-contract-consumer
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+ ${spring-boot.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-data-rest
+ ${spring-boot.version}
+
+
+
+ org.springframework.cloud
+ spring-cloud-contract-wiremock
+ ${spring-cloud.version}
+ test
+
+
+ org.springframework.cloud
+ spring-cloud-contract-stub-runner
+ ${spring-cloud.version}
+ test
+
+
+ org.springframework.cloud
+ spring-cloud-starter-contract-verifier
+ ${spring-cloud.version}
+ test
+
+
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ 2.1.1.RELEASE
+ 2.1.4.RELEASE
+
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/pom.xml b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/pom.xml
index afd045189c..3b711c58d9 100644
--- a/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/pom.xml
+++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/pom.xml
@@ -20,37 +20,27 @@
org.springframework.cloud
spring-cloud-contract-wiremock
- ${spring-cloud.version}
test
org.springframework.cloud
spring-cloud-contract-stub-runner
- ${spring-cloud.version}
test
org.springframework.boot
spring-boot-starter-web
- ${spring-boot.version}
org.springframework.boot
spring-boot-starter-data-rest
- ${spring-boot.version}
com.baeldung.spring.cloud
spring-cloud-contract-producer
- 1.0.0-SNAPSHOT
+ ${project.parent.version}
test
-
- UTF-8
- UTF-8
- 1.2.2.RELEASE
- 1.5.9.RELEASE
-
diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathControllerIntegrationTest.java b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathControllerIntegrationTest.java
index 5cf5c6d3b8..e21223e6ea 100644
--- a/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathControllerIntegrationTest.java
+++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathControllerIntegrationTest.java
@@ -7,6 +7,7 @@ import org.springframework.boot.test.autoconfigure.json.AutoConfigureJsonTesters
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner;
+import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
@@ -19,7 +20,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@AutoConfigureMockMvc
@AutoConfigureJsonTesters
-@AutoConfigureStubRunner(workOffline = true,
+@AutoConfigureStubRunner(stubsMode = StubRunnerProperties.StubsMode.LOCAL,
ids = "com.baeldung.spring.cloud:spring-cloud-contract-producer:+:stubs:8090")
public class BasicMathControllerIntegrationTest {
diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/pom.xml b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/pom.xml
index 07429687c7..dffbd29206 100644
--- a/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/pom.xml
+++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/pom.xml
@@ -25,12 +25,10 @@
org.springframework.boot
spring-boot-starter-web
- ${spring-boot.version}
org.springframework.boot
spring-boot-starter-data-rest
- ${spring-boot.version}
@@ -38,7 +36,7 @@
org.springframework.cloud
spring-cloud-contract-maven-plugin
- 1.2.2.RELEASE
+ 2.1.1.RELEASE
true
com.baeldung.spring.cloud.springcloudcontractproducer.BaseTestClass
@@ -47,25 +45,4 @@
-
-
-
-
-
- org.springframework.cloud
- spring-cloud-dependencies
- ${spring-cloud.version}
- pom
- import
-
-
-
-
-
- UTF-8
- UTF-8
- Edgware.SR1
- 1.5.9.RELEASE
-
-
diff --git a/spring-cloud/spring-cloud-eureka/pom.xml b/spring-cloud/spring-cloud-eureka/pom.xml
index 924981765c..e8e3d67805 100644
--- a/spring-cloud/spring-cloud-eureka/pom.xml
+++ b/spring-cloud/spring-cloud-eureka/pom.xml
@@ -32,8 +32,8 @@
- 2.0.1.RELEASE
- Finchley.SR2
+ 2.1.2.RELEASE
+ Greenwich.RELEASE
diff --git a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client/pom.xml b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client/pom.xml
index 85fa6606d2..04a5bd3e58 100644
--- a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client/pom.xml
+++ b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client/pom.xml
@@ -19,12 +19,10 @@
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
- ${spring-cloud-starter-eureka.version}
org.springframework.boot
spring-boot-starter-web
- ${spring-boot.version}
diff --git a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-feign-client/pom.xml b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-feign-client/pom.xml
index 84ba1e28fe..acc436c574 100644
--- a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-feign-client/pom.xml
+++ b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-feign-client/pom.xml
@@ -18,23 +18,19 @@
org.springframework.cloud
- spring-cloud-starter-feign
- ${spring-cloud-starter-feign.version}
+ spring-cloud-starter-openfeign
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
- ${spring-cloud-starter-eureka.version}
org.springframework.boot
spring-boot-starter-web
- ${spring-boot.version}
org.springframework.boot
spring-boot-starter-thymeleaf
- ${spring-boot.version}
@@ -49,8 +45,4 @@
-
-
- 1.0.0-SNAPSHOT
-
diff --git a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-server/pom.xml b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-server/pom.xml
index f51f6d229d..95edba29f9 100644
--- a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-server/pom.xml
+++ b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-server/pom.xml
@@ -19,7 +19,6 @@
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
- ${spring-cloud-starter-eureka.version}
diff --git a/spring-mvc-simple/README.md b/spring-mvc-simple/README.md
index cd4ad5aba2..755e0932fc 100644
--- a/spring-mvc-simple/README.md
+++ b/spring-mvc-simple/README.md
@@ -8,4 +8,3 @@
- [Guide to Spring Email](http://www.baeldung.com/spring-email)
- [Request Method Not Supported (405) in Spring](https://www.baeldung.com/spring-request-method-not-supported-405)
- [Spring @RequestParam Annotation](https://www.baeldung.com/spring-request-param)
-- [Validating RequestParams and PathVariables in Spring](https://www.baeldung.com/spring-validate-requestparam-pathvariable)
diff --git a/spring-mvc-xml/README.md b/spring-mvc-xml/README.md
index 216517f52d..c8ec074d17 100644
--- a/spring-mvc-xml/README.md
+++ b/spring-mvc-xml/README.md
@@ -15,3 +15,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Exploring SpringMVC’s Form Tag Library](http://www.baeldung.com/spring-mvc-form-tags)
- [web.xml vs Initializer with Spring](http://www.baeldung.com/spring-xml-vs-java-config)
- [A Java Web Application Without a web.xml](https://www.baeldung.com/java-web-app-without-web-xml)
+- [Validating RequestParams and PathVariables in Spring](https://www.baeldung.com/spring-validate-requestparam-pathvariable)
\ No newline at end of file
diff --git a/spring-mvc-xml/pom.xml b/spring-mvc-xml/pom.xml
index beea8e5ee2..46af321d1b 100644
--- a/spring-mvc-xml/pom.xml
+++ b/spring-mvc-xml/pom.xml
@@ -1,4 +1,5 @@
-
4.0.0
0.1-SNAPSHOT
@@ -20,12 +21,6 @@
org.springframework
spring-web
${org.springframework.version}
-
-
- commons-logging
- commons-logging
-
-
org.springframework
@@ -50,7 +45,7 @@
- org.hibernate
+ org.hibernate.validator
hibernate-validator
${hibernate-validator.version}
@@ -84,6 +79,11 @@
+
+ org.glassfish
+ javax.el
+ 3.0.1-b08
+
org.springframework.boot
diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfigJava.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfigJava.java
index 7925fa451d..09c34ccc80 100644
--- a/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfigJava.java
+++ b/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfigJava.java
@@ -5,8 +5,10 @@ import java.util.ResourceBundle;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.support.MessageSourceResourceBundle;
import org.springframework.context.support.ResourceBundleMessageSource;
+import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@@ -15,6 +17,7 @@ import org.springframework.web.servlet.view.JstlView;
//@EnableWebMvc
//@Configuration
+@ComponentScan("com.baeldung.spring")
public class ClientWebConfigJava implements WebMvcConfigurer {
public ClientWebConfigJava() {
@@ -51,4 +54,9 @@ public class ClientWebConfigJava implements WebMvcConfigurer {
return bean;
}
+
+ @Bean
+ public MethodValidationPostProcessor methodValidationPostProcessor() {
+ return new MethodValidationPostProcessor();
+ }
}
\ No newline at end of file
diff --git a/spring-mvc-xml/src/test/java/com/baeldung/spring/controller/RequestAndPathVariableValidationControllerIntegrationTest.java b/spring-mvc-xml/src/test/java/com/baeldung/spring/controller/RequestAndPathVariableValidationControllerIntegrationTest.java
index 318a15d8f7..c4332dd879 100644
--- a/spring-mvc-xml/src/test/java/com/baeldung/spring/controller/RequestAndPathVariableValidationControllerIntegrationTest.java
+++ b/spring-mvc-xml/src/test/java/com/baeldung/spring/controller/RequestAndPathVariableValidationControllerIntegrationTest.java
@@ -12,12 +12,13 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import com.baeldung.spring.ClientWebConfig;
+import com.baeldung.spring.ClientWebConfigJava;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(classes = ClientWebConfig.class)
+@ContextConfiguration(classes = ClientWebConfigJava.class)
@WebAppConfiguration
public class RequestAndPathVariableValidationControllerIntegrationTest {
diff --git a/spring-rest-full/README.md b/spring-rest-full/README.md
index e0d3a70626..b7b006d75e 100644
--- a/spring-rest-full/README.md
+++ b/spring-rest-full/README.md
@@ -9,7 +9,6 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com
### Relevant Articles:
- [Integration Testing with the Maven Cargo plugin](http://www.baeldung.com/integration-testing-with-the-maven-cargo-plugin)
-- [Introduction to Spring Data JPA](http://www.baeldung.com/the-persistence-layer-with-spring-data-jpa)
- [Project Configuration with Spring](http://www.baeldung.com/project-configuration-with-spring)
- [Metrics for your Spring REST API](http://www.baeldung.com/spring-rest-api-metrics)
- [Spring Security Expressions - hasRole Example](https://www.baeldung.com/spring-security-expressions-basic)
diff --git a/spring-rest-full/pom.xml b/spring-rest-full/pom.xml
index ee6e5dbe3e..a85393b7a8 100644
--- a/spring-rest-full/pom.xml
+++ b/spring-rest-full/pom.xml
@@ -8,10 +8,10 @@
war
- parent-boot-1
+ parent-boot-2
com.baeldung
0.0.1-SNAPSHOT
- ../parent-boot-1
+ ../parent-boot-2
@@ -129,6 +129,7 @@
org.javassist
javassist
+ ${javassist.version}
mysql
@@ -287,6 +288,7 @@
19.0
3.5
+ 3.25.0-GA
1.6.1
diff --git a/spring-rest-full/src/main/java/org/baeldung/persistence/service/common/AbstractService.java b/spring-rest-full/src/main/java/org/baeldung/persistence/service/common/AbstractService.java
index 059516eeba..ceefbbe0e3 100644
--- a/spring-rest-full/src/main/java/org/baeldung/persistence/service/common/AbstractService.java
+++ b/spring-rest-full/src/main/java/org/baeldung/persistence/service/common/AbstractService.java
@@ -17,7 +17,7 @@ public abstract class AbstractService implements IOperat
@Override
@Transactional(readOnly = true)
public T findOne(final long id) {
- return getDao().findOne(id);
+ return getDao().findById(id).orElse(null);
}
// read - all
diff --git a/spring-rest-full/src/main/java/org/baeldung/spring/Application.java b/spring-rest-full/src/main/java/org/baeldung/spring/Application.java
index 950e2085a6..ca72a4ef56 100644
--- a/spring-rest-full/src/main/java/org/baeldung/spring/Application.java
+++ b/spring-rest-full/src/main/java/org/baeldung/spring/Application.java
@@ -7,7 +7,7 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
-import org.springframework.boot.web.support.SpringBootServletInitializer;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.context.request.RequestContextListener;
diff --git a/spring-rest-full/src/main/java/org/baeldung/spring/WebConfig.java b/spring-rest-full/src/main/java/org/baeldung/spring/WebConfig.java
index 86cb93175a..a0db08d93d 100644
--- a/spring-rest-full/src/main/java/org/baeldung/spring/WebConfig.java
+++ b/spring-rest-full/src/main/java/org/baeldung/spring/WebConfig.java
@@ -6,13 +6,13 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@ComponentScan("org.baeldung.web")
@EnableWebMvc
-public class WebConfig extends WebMvcConfigurerAdapter {
+public class WebConfig implements WebMvcConfigurer {
public WebConfig() {
super();
@@ -29,7 +29,6 @@ public class WebConfig extends WebMvcConfigurerAdapter {
// API
@Override
public void addViewControllers(final ViewControllerRegistry registry) {
- super.addViewControllers(registry);
registry.addViewController("/graph.html");
registry.addViewController("/homepage.html");
}
diff --git a/spring-rest-full/src/main/java/org/baeldung/web/metric/ActuatorMetricService.java b/spring-rest-full/src/main/java/org/baeldung/web/metric/ActuatorMetricService.java
index 89e3a22d45..4dcec17b9e 100644
--- a/spring-rest-full/src/main/java/org/baeldung/web/metric/ActuatorMetricService.java
+++ b/spring-rest-full/src/main/java/org/baeldung/web/metric/ActuatorMetricService.java
@@ -6,16 +6,18 @@ import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.actuate.endpoint.MetricReaderPublicMetrics;
-import org.springframework.boot.actuate.metrics.Metric;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
+import io.micrometer.core.instrument.Counter;
+import io.micrometer.core.instrument.Meter;
+import io.micrometer.core.instrument.MeterRegistry;
+
@Service
public class ActuatorMetricService implements IActuatorMetricService {
@Autowired
- private MetricReaderPublicMetrics publicMetrics;
+ private MeterRegistry publicMetrics;
private final List> statusMetricsByMinute;
private final List statusList;
@@ -68,7 +70,7 @@ public class ActuatorMetricService implements IActuatorMetricService {
private void exportMetrics() {
final ArrayList lastMinuteStatuses = initializeStatuses(statusList.size());
- for (final Metric> counterMetric : publicMetrics.metrics()) {
+ for (final Meter counterMetric : publicMetrics.getMeters()) {
updateMetrics(counterMetric, lastMinuteStatuses);
}
@@ -83,17 +85,17 @@ public class ActuatorMetricService implements IActuatorMetricService {
return counterList;
}
- private void updateMetrics(final Metric> counterMetric, final ArrayList statusCount) {
+ private void updateMetrics(final Meter counterMetric, final ArrayList statusCount) {
String status = "";
int index = -1;
int oldCount = 0;
- if (counterMetric.getName().contains("counter.status.")) {
- status = counterMetric.getName().substring(15, 18); // example 404, 200
+ if (counterMetric.getId().getName().contains("counter.status.")) {
+ status = counterMetric.getId().getName().substring(15, 18); // example 404, 200
appendStatusIfNotExist(status, statusCount);
index = statusList.indexOf(status);
oldCount = statusCount.get(index) == null ? 0 : statusCount.get(index);
- statusCount.set(index, counterMetric.getValue().intValue() + oldCount);
+ statusCount.set(index, (int)((Counter) counterMetric).count() + oldCount);
}
}
diff --git a/spring-rest-full/src/main/java/org/baeldung/web/metric/CustomActuatorMetricService.java b/spring-rest-full/src/main/java/org/baeldung/web/metric/CustomActuatorMetricService.java
index 852a9fae99..cf30686e52 100644
--- a/spring-rest-full/src/main/java/org/baeldung/web/metric/CustomActuatorMetricService.java
+++ b/spring-rest-full/src/main/java/org/baeldung/web/metric/CustomActuatorMetricService.java
@@ -6,20 +6,18 @@ import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.actuate.metrics.CounterService;
-import org.springframework.boot.actuate.metrics.Metric;
-import org.springframework.boot.actuate.metrics.repository.InMemoryMetricRepository;
-import org.springframework.boot.actuate.metrics.repository.MetricRepository;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
+import io.micrometer.core.instrument.Counter;
+import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.search.Search;
+
@Service
public class CustomActuatorMetricService implements ICustomActuatorMetricService {
- private MetricRepository repo;
-
@Autowired
- private CounterService counter;
+ private MeterRegistry registry;
private final List> statusMetricsByMinute;
private final List statusList;
@@ -27,7 +25,6 @@ public class CustomActuatorMetricService implements ICustomActuatorMetricService
public CustomActuatorMetricService() {
super();
- repo = new InMemoryMetricRepository();
statusMetricsByMinute = new ArrayList>();
statusList = new ArrayList();
}
@@ -36,9 +33,10 @@ public class CustomActuatorMetricService implements ICustomActuatorMetricService
@Override
public void increaseCount(final int status) {
- counter.increment("status." + status);
- if (!statusList.contains("counter.status." + status)) {
- statusList.add("counter.status." + status);
+ String counterName = "counter.status." + status;
+ registry.counter(counterName).increment(1);
+ if (!statusList.contains(counterName)) {
+ statusList.add(counterName);
}
}
@@ -78,17 +76,16 @@ public class CustomActuatorMetricService implements ICustomActuatorMetricService
@Scheduled(fixedDelay = 60000)
private void exportMetrics() {
- Metric> metric;
final ArrayList statusCount = new ArrayList();
for (final String status : statusList) {
- metric = repo.findOne(status);
- if (metric != null) {
- statusCount.add(metric.getValue().intValue());
- repo.reset(status);
+ Search search = registry.find(status);
+ if (search != null) {
+ Counter counter = search.counter();
+ statusCount.add(counter != null ? ((int) counter.count()) : 0);
+ registry.remove(counter);
} else {
statusCount.add(0);
}
-
}
statusMetricsByMinute.add(statusCount);
}
diff --git a/spring-rest-full/src/main/resources/application.properties b/spring-rest-full/src/main/resources/application.properties
index 6c7461f12c..52d93b4cff 100644
--- a/spring-rest-full/src/main/resources/application.properties
+++ b/spring-rest-full/src/main/resources/application.properties
@@ -1,3 +1,3 @@
server.port=8082
-server.context-path=/spring-rest-full
+server.servlet.context-path=/spring-rest-full
endpoints.metrics.enabled=true
\ No newline at end of file
diff --git a/spring-security-rest-custom/pom.xml b/spring-security-rest-custom/pom.xml
index 8fdcb509ee..38cbfddab8 100644
--- a/spring-security-rest-custom/pom.xml
+++ b/spring-security-rest-custom/pom.xml
@@ -8,10 +8,10 @@
war
- parent-boot-1
+ parent-boot-2
com.baeldung
0.0.1-SNAPSHOT
- ../parent-boot-1
+ ../parent-boot-2
diff --git a/spring-security-rest-custom/src/main/java/org/baeldung/config/child/WebConfig.java b/spring-security-rest-custom/src/main/java/org/baeldung/config/child/WebConfig.java
index 0c2042f711..d7b2da6fe7 100644
--- a/spring-security-rest-custom/src/main/java/org/baeldung/config/child/WebConfig.java
+++ b/spring-security-rest-custom/src/main/java/org/baeldung/config/child/WebConfig.java
@@ -9,14 +9,14 @@ import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableWebMvc
@ComponentScan("org.baeldung.web")
// @ImportResource({ "classpath:prop.xml" })
// @PropertySource("classpath:foo.properties")
-public class WebConfig extends WebMvcConfigurerAdapter {
+public class WebConfig implements WebMvcConfigurer {
public WebConfig() {
super();
@@ -26,7 +26,6 @@ public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureMessageConverters(final List> converters) {
- super.configureMessageConverters(converters);
converters.add(new MappingJackson2HttpMessageConverter());
}
diff --git a/testing-modules/junit-5/pom.xml b/testing-modules/junit-5/pom.xml
index 84e0577cfe..b3074635a7 100644
--- a/testing-modules/junit-5/pom.xml
+++ b/testing-modules/junit-5/pom.xml
@@ -139,7 +139,7 @@
5.4.2
2.8.2
2.0.0-RC.1
- 2.21.0
+ 2.22.0
1.6.0
5.0.1.RELEASE
diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/MultipleExtensionsUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/MultipleExtensionsUnitTest.java
new file mode 100644
index 0000000000..db37e9a6d2
--- /dev/null
+++ b/testing-modules/junit-5/src/test/java/com/baeldung/MultipleExtensionsUnitTest.java
@@ -0,0 +1,28 @@
+package com.baeldung;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import com.baeldung.extensions.EmployeeDatabaseSetupExtension;
+
+public class MultipleExtensionsUnitTest {
+
+ @Order(1)
+ @RegisterExtension
+ static EmployeeDatabaseSetupExtension SECOND_DB =
+ new EmployeeDatabaseSetupExtension("jdbc:h2:mem:DbTwo;DB_CLOSE_DELAY=-1", "org.h2.Driver", "sa", "");
+
+ @Order(0)
+ @RegisterExtension
+ static EmployeeDatabaseSetupExtension FIRST_DB =
+ new EmployeeDatabaseSetupExtension("jdbc:h2:mem:DbOne;DB_CLOSE_DELAY=-1", "org.h2.Driver", "sa", "");
+
+ @RegisterExtension
+ static EmployeeDatabaseSetupExtension LAST_DB =
+ new EmployeeDatabaseSetupExtension("jdbc:h2:mem:DbLast;DB_CLOSE_DELAY=-1", "org.h2.Driver", "sa", "");
+
+ @Test
+ public void justDemonstratingTheIdea() {
+ // empty test
+ }
+}
diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/ProgrammaticEmployeesUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/ProgrammaticEmployeesUnitTest.java
new file mode 100644
index 0000000000..a29fafd193
--- /dev/null
+++ b/testing-modules/junit-5/src/test/java/com/baeldung/ProgrammaticEmployeesUnitTest.java
@@ -0,0 +1,40 @@
+package com.baeldung;
+
+import java.sql.SQLException;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import com.baeldung.helpers.Employee;
+import com.baeldung.extensions.EmployeeDaoParameterResolver;
+import com.baeldung.extensions.EmployeeDatabaseSetupExtension;
+import com.baeldung.extensions.EnvironmentExtension;
+import com.baeldung.helpers.EmployeeJdbcDao;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+@ExtendWith({ EnvironmentExtension.class, EmployeeDaoParameterResolver.class })
+public class ProgrammaticEmployeesUnitTest {
+
+ private EmployeeJdbcDao employeeDao;
+
+ @RegisterExtension static EmployeeDatabaseSetupExtension DB =
+ new EmployeeDatabaseSetupExtension("jdbc:h2:mem:AnotherDb;DB_CLOSE_DELAY=-1", "org.h2.Driver", "sa", "");
+
+ public ProgrammaticEmployeesUnitTest(EmployeeJdbcDao employeeDao) {
+ this.employeeDao = employeeDao;
+ }
+
+ @Test
+ public void whenAddEmployee_thenGetEmployee() throws SQLException {
+ Employee emp = new Employee(1, "john");
+ employeeDao.add(emp);
+ assertEquals(1, employeeDao.findAll().size());
+ }
+
+ @Test
+ public void whenGetEmployees_thenEmptyList() throws SQLException {
+ assertEquals(0, employeeDao.findAll().size());
+ }
+}
diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/extensions/EmployeeDatabaseSetupExtension.java b/testing-modules/junit-5/src/test/java/com/baeldung/extensions/EmployeeDatabaseSetupExtension.java
index 69e420b28a..f124703690 100644
--- a/testing-modules/junit-5/src/test/java/com/baeldung/extensions/EmployeeDatabaseSetupExtension.java
+++ b/testing-modules/junit-5/src/test/java/com/baeldung/extensions/EmployeeDatabaseSetupExtension.java
@@ -15,10 +15,20 @@ import com.baeldung.helpers.JdbcConnectionUtil;
public class EmployeeDatabaseSetupExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback {
- private Connection con = JdbcConnectionUtil.getConnection();
- private EmployeeJdbcDao employeeDao = new EmployeeJdbcDao(con);
+ private Connection con;
+ private EmployeeJdbcDao employeeDao;
private Savepoint savepoint;
+ public EmployeeDatabaseSetupExtension() {
+ con = JdbcConnectionUtil.getConnection();
+ employeeDao = new EmployeeJdbcDao(con);
+ }
+
+ public EmployeeDatabaseSetupExtension(String jdbcUrl, String driver, String username, String password) {
+ con = JdbcConnectionUtil.getConnection(jdbcUrl, driver, username, password);
+ employeeDao = new EmployeeJdbcDao(con);
+ }
+
@Override
public void afterAll(ExtensionContext context) throws SQLException {
if (con != null) {
diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/helpers/EmployeeJdbcDao.java b/testing-modules/junit-5/src/test/java/com/baeldung/helpers/EmployeeJdbcDao.java
index 7600f763cd..4b274cff39 100644
--- a/testing-modules/junit-5/src/test/java/com/baeldung/helpers/EmployeeJdbcDao.java
+++ b/testing-modules/junit-5/src/test/java/com/baeldung/helpers/EmployeeJdbcDao.java
@@ -19,7 +19,7 @@ public class EmployeeJdbcDao {
}
public void createTable() throws SQLException {
- String createQuery = "CREATE TABLE employees(id long primary key, firstName varchar(50))";
+ String createQuery = "CREATE TABLE IF NOT EXISTS employees(id long primary key, firstName varchar(50))";
PreparedStatement pstmt = con.prepareStatement(createQuery);
pstmt.execute();
diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/helpers/JdbcConnectionUtil.java b/testing-modules/junit-5/src/test/java/com/baeldung/helpers/JdbcConnectionUtil.java
index f380f9674c..ccba627234 100644
--- a/testing-modules/junit-5/src/test/java/com/baeldung/helpers/JdbcConnectionUtil.java
+++ b/testing-modules/junit-5/src/test/java/com/baeldung/helpers/JdbcConnectionUtil.java
@@ -11,22 +11,49 @@ public class JdbcConnectionUtil {
private static Connection con;
public static Connection getConnection() {
- if (con == null) {
+ if (con == null || isClosed(con)) {
try {
Properties props = new Properties();
props.load(JdbcConnectionUtil.class.getResourceAsStream("jdbc.properties"));
- Class.forName(props.getProperty("jdbc.driver"));
- con = DriverManager.getConnection(props.getProperty("jdbc.url"), props.getProperty("jdbc.user"), props.getProperty("jdbc.password"));
+
+ String jdbcUrl = props.getProperty("jdbc.url");
+ String driver = props.getProperty("jdbc.driver");
+ String username = props.getProperty("jdbc.user");
+ String password = props.getProperty("jdbc.password");
+ con = getConnection(jdbcUrl, driver, username, password);
return con;
} catch (IOException exc) {
exc.printStackTrace();
+ }
+
+ return null;
+ }
+ return con;
+ }
+
+ public static Connection getConnection(String jdbcUrl, String driver, String username, String password) {
+ if (con == null || isClosed(con)) {
+ try {
+ Class.forName(driver);
+ con = DriverManager.getConnection(jdbcUrl, username, password);
+ return con;
} catch (ClassNotFoundException exc) {
exc.printStackTrace();
} catch (SQLException exc) {
exc.printStackTrace();
}
+
return null;
}
+
return con;
}
+
+ private static boolean isClosed(Connection con) {
+ try {
+ return con.isClosed();
+ } catch (SQLException e) {
+ return true;
+ }
+ }
}
diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AssertionUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AssertionUnitTest.java
index d1d08c6e62..d225e4547e 100644
--- a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AssertionUnitTest.java
+++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AssertionUnitTest.java
@@ -34,7 +34,7 @@ public class AssertionUnitTest {
"heading",
() -> assertEquals(4, 2 * 2, "4 is 2 times 2"),
() -> assertEquals("java", "JAVA".toLowerCase()),
- () -> assertEquals(null, null, "null is equal to null")
+ () -> assertEquals((String) null, (String) null, "null is equal to null")
);
}
}