diff --git a/spring-jpa/pom.xml b/spring-jpa/pom.xml
index 6a67d44b48..960dcbc588 100644
--- a/spring-jpa/pom.xml
+++ b/spring-jpa/pom.xml
@@ -113,6 +113,11 @@
guava
${guava.version}
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+
@@ -180,6 +185,7 @@
21.0
3.5
+ 3.8.0
4.4.5
4.5.2
diff --git a/spring-jpa/src/main/java/org/baeldung/config/StudentJPAH2Config.java b/spring-jpa/src/main/java/org/baeldung/config/StudentJPAH2Config.java
new file mode 100644
index 0000000000..439c6cb602
--- /dev/null
+++ b/spring-jpa/src/main/java/org/baeldung/config/StudentJPAH2Config.java
@@ -0,0 +1,69 @@
+package org.baeldung.config;
+
+import java.util.Properties;
+
+import javax.persistence.EntityManagerFactory;
+import javax.sql.DataSource;
+
+import org.baeldung.extended.persistence.dao.ExtendedRepositoryImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+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.annotation.EnableTransactionManagement;
+
+@Configuration
+@EnableJpaRepositories(basePackages = "org.baeldung.extended.persistence.dao", repositoryBaseClass = ExtendedRepositoryImpl.class)
+@PropertySource("persistence-student-h2.properties")
+@EnableTransactionManagement
+public class StudentJPAH2Config {
+
+ @Autowired
+ private Environment env;
+
+ @Bean
+ public DataSource dataSource() {
+ final DriverManagerDataSource dataSource = new DriverManagerDataSource();
+ dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
+ dataSource.setUrl(env.getProperty("jdbc.url"));
+ dataSource.setUsername(env.getProperty("jdbc.user"));
+ dataSource.setPassword(env.getProperty("jdbc.pass"));
+
+ return dataSource;
+ }
+
+ @Bean
+ public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
+ final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
+ em.setDataSource(dataSource());
+ em.setPackagesToScan(new String[] { "org.baeldung.inmemory.persistence.model" });
+ em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
+ em.setJpaProperties(additionalProperties());
+ return em;
+ }
+
+ @Bean
+ JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
+ JpaTransactionManager transactionManager = new JpaTransactionManager();
+ transactionManager.setEntityManagerFactory(entityManagerFactory);
+ return transactionManager;
+ }
+
+ 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.show_sql", env.getProperty("hibernate.show_sql"));
+ hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", env.getProperty("hibernate.cache.use_second_level_cache"));
+ hibernateProperties.setProperty("hibernate.cache.use_query_cache", env.getProperty("hibernate.cache.use_query_cache"));
+
+ return hibernateProperties;
+ }
+}
diff --git a/spring-jpa/src/main/java/org/baeldung/config/StudentJpaConfig.java b/spring-jpa/src/main/java/org/baeldung/config/StudentJpaConfig.java
index a40f180a62..8021691716 100644
--- a/spring-jpa/src/main/java/org/baeldung/config/StudentJpaConfig.java
+++ b/spring-jpa/src/main/java/org/baeldung/config/StudentJpaConfig.java
@@ -18,7 +18,7 @@ import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
-@EnableJpaRepositories(basePackages = "org.baeldung.persistence.dao")
+@EnableJpaRepositories(basePackages = "org.baeldung.inmemory.persistence.dao")
@PropertySource("persistence-student.properties")
@EnableTransactionManagement
public class StudentJpaConfig {
@@ -41,7 +41,7 @@ public class StudentJpaConfig {
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
- em.setPackagesToScan(new String[] { "org.baeldung.persistence.model" });
+ em.setPackagesToScan(new String[] { "org.baeldung.inmemory.persistence.model" });
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
em.setJpaProperties(additionalProperties());
return em;
diff --git a/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepository.java b/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepository.java
new file mode 100644
index 0000000000..9c9c12029a
--- /dev/null
+++ b/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepository.java
@@ -0,0 +1,12 @@
+package org.baeldung.extended.persistence.dao;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.repository.NoRepositoryBean;
+
+@NoRepositoryBean
+public interface ExtendedRepository extends JpaRepository {
+ public List findByAttributeContainsText(String attributeName, String text);
+}
diff --git a/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepositoryImpl.java b/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepositoryImpl.java
new file mode 100644
index 0000000000..0dd32757d7
--- /dev/null
+++ b/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepositoryImpl.java
@@ -0,0 +1,36 @@
+package org.baeldung.extended.persistence.dao;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Root;
+import javax.transaction.Transactional;
+
+import org.springframework.data.jpa.repository.support.JpaEntityInformation;
+import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
+
+public class ExtendedRepositoryImpl extends SimpleJpaRepository implements ExtendedRepository {
+
+ private EntityManager entityManager;
+
+ public ExtendedRepositoryImpl(JpaEntityInformation entityInformation, EntityManager entityManager) {
+ super(entityInformation, entityManager);
+ this.entityManager = entityManager;
+ }
+
+ @Transactional
+ public List findByAttributeContainsText(String attributeName, String text) {
+ CriteriaBuilder builder = entityManager.getCriteriaBuilder();
+ CriteriaQuery query = builder.createQuery(getDomainClass());
+ Root root = query.from(getDomainClass());
+ query.select(root)
+ .where(builder.like(root. get(attributeName), "%" + text + "%"));
+ TypedQuery q = entityManager.createQuery(query);
+ return q.getResultList();
+ }
+
+}
diff --git a/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedStudentRepository.java b/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedStudentRepository.java
new file mode 100644
index 0000000000..7e2efc72bc
--- /dev/null
+++ b/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedStudentRepository.java
@@ -0,0 +1,6 @@
+package org.baeldung.extended.persistence.dao;
+
+import org.baeldung.inmemory.persistence.model.Student;
+
+public interface ExtendedStudentRepository extends ExtendedRepository {
+}
diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/dao/StudentRepository.java b/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/dao/StudentRepository.java
similarity index 57%
rename from spring-jpa/src/main/java/org/baeldung/persistence/dao/StudentRepository.java
rename to spring-jpa/src/main/java/org/baeldung/inmemory/persistence/dao/StudentRepository.java
index af484b442c..bfcf6f5cdc 100644
--- a/spring-jpa/src/main/java/org/baeldung/persistence/dao/StudentRepository.java
+++ b/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/dao/StudentRepository.java
@@ -1,8 +1,7 @@
-package org.baeldung.persistence.dao;
+package org.baeldung.inmemory.persistence.dao;
+import org.baeldung.inmemory.persistence.model.Student;
import org.springframework.data.jpa.repository.JpaRepository;
-import org.baeldung.persistence.model.Student;
-
public interface StudentRepository extends JpaRepository {
}
diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/model/Student.java b/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/model/Student.java
similarity index 91%
rename from spring-jpa/src/main/java/org/baeldung/persistence/model/Student.java
rename to spring-jpa/src/main/java/org/baeldung/inmemory/persistence/model/Student.java
index 437eeac5bb..b50fe9122e 100644
--- a/spring-jpa/src/main/java/org/baeldung/persistence/model/Student.java
+++ b/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/model/Student.java
@@ -1,4 +1,4 @@
-package org.baeldung.persistence.model;
+package org.baeldung.inmemory.persistence.model;
import javax.persistence.Entity;
import javax.persistence.Id;
diff --git a/spring-jpa/src/main/resources/persistence-student-h2.properties b/spring-jpa/src/main/resources/persistence-student-h2.properties
new file mode 100644
index 0000000000..e1d6bfa45a
--- /dev/null
+++ b/spring-jpa/src/main/resources/persistence-student-h2.properties
@@ -0,0 +1,12 @@
+# jdbc.X
+jdbc.driverClassName=org.h2.Driver
+jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
+jdbc.user=sa
+# jdbc.pass=
+
+# hibernate.X
+hibernate.dialect=org.hibernate.dialect.H2Dialect
+hibernate.show_sql=true
+hibernate.hbm2ddl.auto=create-drop
+hibernate.cache.use_second_level_cache=false
+hibernate.cache.use_query_cache=false
\ No newline at end of file
diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/repository/ExtendedStudentRepositoryIntegrationTest.java b/spring-jpa/src/test/java/org/baeldung/persistence/repository/ExtendedStudentRepositoryIntegrationTest.java
new file mode 100644
index 0000000000..0970daa0ee
--- /dev/null
+++ b/spring-jpa/src/test/java/org/baeldung/persistence/repository/ExtendedStudentRepositoryIntegrationTest.java
@@ -0,0 +1,39 @@
+package org.baeldung.persistence.repository;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.List;
+
+import javax.annotation.Resource;
+
+import org.baeldung.config.StudentJPAH2Config;
+import org.baeldung.extended.persistence.dao.ExtendedStudentRepository;
+import org.baeldung.inmemory.persistence.model.Student;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = { StudentJPAH2Config.class})
+public class ExtendedStudentRepositoryIntegrationTest {
+ @Resource
+ private ExtendedStudentRepository extendedStudentRepository;
+
+ @Before
+ public void setup(){
+ Student student = new Student(1, "john");
+ extendedStudentRepository.save(student);
+ Student student2 = new Student(2, "johnson");
+ extendedStudentRepository.save(student2);
+ Student student3 = new Student(3, "tom");
+ extendedStudentRepository.save(student3);
+ }
+
+ @Test
+ public void givenStudents_whenFindByName_thenGetOk(){
+ List students = extendedStudentRepository.findByAttributeContainsText("name", "john");
+ assertThat(students.size()).isEqualTo(2);
+ }
+}
diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java b/spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java
index 1fcc4be45d..8380ab5434 100644
--- a/spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java
+++ b/spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java
@@ -1,8 +1,8 @@
package org.baeldung.persistence.repository;
import org.baeldung.config.StudentJpaConfig;
-import org.baeldung.persistence.dao.StudentRepository;
-import org.baeldung.persistence.model.Student;
+import org.baeldung.inmemory.persistence.dao.StudentRepository;
+import org.baeldung.inmemory.persistence.model.Student;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;