Move code to common module - Spring Data JPA (#15733)
* JAVA-30484: Move code to new module - Spring Data JPA * JAVA-30484: remove the duplicate code from the old modules.
This commit is contained in:
parent
f13baaf5d2
commit
f7c541f9d0
@ -82,7 +82,6 @@
|
|||||||
<module>spring-data-jpa-annotations</module>
|
<module>spring-data-jpa-annotations</module>
|
||||||
<module>spring-data-jpa-annotations-2</module>
|
<module>spring-data-jpa-annotations-2</module>
|
||||||
<module>spring-data-jpa-crud</module>
|
<module>spring-data-jpa-crud</module>
|
||||||
<module>spring-data-jpa-crud-2</module>
|
|
||||||
<module>spring-data-jpa-enterprise</module>
|
<module>spring-data-jpa-enterprise</module>
|
||||||
<module>spring-data-jpa-enterprise-2</module>
|
<module>spring-data-jpa-enterprise-2</module>
|
||||||
<module>spring-data-jpa-filtering</module>
|
<module>spring-data-jpa-filtering</module>
|
||||||
@ -93,6 +92,7 @@
|
|||||||
<module>spring-data-jpa-repo-2</module>
|
<module>spring-data-jpa-repo-2</module>
|
||||||
<module>spring-data-jpa-repo-4</module>
|
<module>spring-data-jpa-repo-4</module>
|
||||||
<module>spring-data-jdbc</module>
|
<module>spring-data-jdbc</module>
|
||||||
|
<module>spring-data-jpa-simple</module>
|
||||||
<module>spring-data-keyvalue</module>
|
<module>spring-data-keyvalue</module>
|
||||||
<module>spring-data-mongodb</module>
|
<module>spring-data-mongodb</module>
|
||||||
<module>spring-data-mongodb-2</module>
|
<module>spring-data-mongodb-2</module>
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
## Spring Data JPA - CRUD
|
|
||||||
|
|
||||||
This module contains articles about CRUD operations in Spring Data JPA
|
|
||||||
|
|
||||||
### Relevant Articles:
|
|
||||||
- [Generate Database Schema with Spring Data JPA](https://www.baeldung.com/spring-data-jpa-generate-db-schema)
|
|
||||||
- More articles: [[<--prev]](/persistence-modules/spring-data-jpa-crud)
|
|
||||||
|
|
||||||
### Eclipse Config
|
|
||||||
After importing the project into Eclipse, you may see the following error:
|
|
||||||
"No persistence xml file found in project"
|
|
||||||
|
|
||||||
This can be ignored:
|
|
||||||
- Project -> Properties -> Java Persistance -> JPA -> Error/Warnings -> Select Ignore on "No persistence xml file found in project"
|
|
||||||
Or:
|
|
||||||
- Eclipse -> Preferences - Validation - disable the "Build" execution of the JPA Validator
|
|
@ -1,32 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<artifactId>spring-data-jpa-crud-2</artifactId>
|
|
||||||
<name>spring-data-jpa-crud-2</name>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>com.baeldung</groupId>
|
|
||||||
<artifactId>parent-boot-2</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
<relativePath>../../parent-boot-2</relativePath>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.h2database</groupId>
|
|
||||||
<artifactId>h2</artifactId>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
@ -1,72 +0,0 @@
|
|||||||
package com.baeldung.schemageneration;
|
|
||||||
|
|
||||||
import com.baeldung.schemageneration.model.Account;
|
|
||||||
import com.baeldung.schemageneration.model.AccountSetting;
|
|
||||||
import com.baeldung.schemageneration.repository.AccountRepository;
|
|
||||||
import com.baeldung.schemageneration.repository.AccountSettingRepository;
|
|
||||||
import org.junit.After;
|
|
||||||
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.test.context.junit4.SpringRunner;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
|
||||||
@SpringBootTest(classes = AccountApplication.class)
|
|
||||||
public class AccountRepositoryIntegrationTest {
|
|
||||||
|
|
||||||
private static final String USER_NAME = "Eduard";
|
|
||||||
private static final String USER_EMAIL_ADDRESS = "eduard@gmx.com";
|
|
||||||
private static final String ACCOUNT_SETTING_NAME = "Timezone";
|
|
||||||
private static final String ACCOUNT_SETTING_VALUE = "UTC+02";
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private AccountRepository accountRepository;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private AccountSettingRepository accountSettingRepository;
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() {
|
|
||||||
accountRepository.deleteAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenNewAccount_whenSave_thenSuccess() {
|
|
||||||
Account account = new Account(USER_NAME, USER_EMAIL_ADDRESS);
|
|
||||||
accountRepository.save(account);
|
|
||||||
|
|
||||||
assertEquals(1, accountRepository.count());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenSavedAccount_whenFindByName_thenFound() {
|
|
||||||
Account account = new Account(USER_NAME, USER_EMAIL_ADDRESS);
|
|
||||||
accountRepository.save(account);
|
|
||||||
|
|
||||||
Account accountFound = accountRepository.findByName(USER_NAME);
|
|
||||||
|
|
||||||
assertNotNull(accountFound);
|
|
||||||
assertEquals(USER_NAME, accountFound.getName());
|
|
||||||
assertEquals(USER_EMAIL_ADDRESS, accountFound.getEmailAddress());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenSavedAccount_whenAccountSettingIsAdded_thenPersisted() {
|
|
||||||
Account account = new Account(USER_NAME, USER_EMAIL_ADDRESS);
|
|
||||||
account.addAccountSetting(new AccountSetting(ACCOUNT_SETTING_NAME, ACCOUNT_SETTING_VALUE));
|
|
||||||
accountRepository.save(account);
|
|
||||||
|
|
||||||
Account accountFound = accountRepository.findByName(USER_NAME);
|
|
||||||
assertNotNull(accountFound);
|
|
||||||
AccountSetting accountSetting = accountSettingRepository.findByAccountId(accountFound.getId());
|
|
||||||
|
|
||||||
assertNotNull(accountSetting);
|
|
||||||
assertEquals(ACCOUNT_SETTING_NAME, accountSetting.getSettingName());
|
|
||||||
assertEquals(ACCOUNT_SETTING_VALUE, accountSetting.getSettingValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -8,9 +8,7 @@ This module contains articles about Spring Data JPA used in enterprise applicati
|
|||||||
- [DB Integration Tests with Spring Boot and Testcontainers](https://www.baeldung.com/spring-boot-testcontainers-integration-test)
|
- [DB Integration Tests with Spring Boot and Testcontainers](https://www.baeldung.com/spring-boot-testcontainers-integration-test)
|
||||||
- [A Guide to Spring’s Open Session in View](https://www.baeldung.com/spring-open-session-in-view)
|
- [A Guide to Spring’s Open Session in View](https://www.baeldung.com/spring-open-session-in-view)
|
||||||
- [Partial Data Update With Spring Data](https://www.baeldung.com/spring-data-partial-update)
|
- [Partial Data Update With Spring Data](https://www.baeldung.com/spring-data-partial-update)
|
||||||
- [Spring Data JPA @Modifying Annotation](https://www.baeldung.com/spring-data-jpa-modifying-annotation)
|
|
||||||
- [Spring JPA – Multiple Databases](https://www.baeldung.com/spring-data-jpa-multiple-databases)
|
- [Spring JPA – Multiple Databases](https://www.baeldung.com/spring-data-jpa-multiple-databases)
|
||||||
- [Pagination and Sorting using Spring Data JPA](https://www.baeldung.com/spring-data-jpa-pagination-sorting)
|
|
||||||
|
|
||||||
### Eclipse Config
|
### Eclipse Config
|
||||||
After importing the project into Eclipse, you may see the following error:
|
After importing the project into Eclipse, you may see the following error:
|
||||||
|
@ -6,7 +6,6 @@ This module contains articles about filtering data using Spring Data JPA
|
|||||||
- [An Advanced Tagging Implementation with JPA](https://www.baeldung.com/jpa-tagging-advanced)
|
- [An Advanced Tagging Implementation with JPA](https://www.baeldung.com/jpa-tagging-advanced)
|
||||||
- [A Simple Tagging Implementation with JPA](https://www.baeldung.com/jpa-tagging)
|
- [A Simple Tagging Implementation with JPA](https://www.baeldung.com/jpa-tagging)
|
||||||
- [Spring Data JPA and Null Parameters](https://www.baeldung.com/spring-data-jpa-null-parameters)
|
- [Spring Data JPA and Null Parameters](https://www.baeldung.com/spring-data-jpa-null-parameters)
|
||||||
- [Spring Data JPA Projections](https://www.baeldung.com/spring-data-jpa-projections)
|
|
||||||
|
|
||||||
### Eclipse Config
|
### Eclipse Config
|
||||||
After importing the project into Eclipse, you may see the following error:
|
After importing the project into Eclipse, you may see the following error:
|
||||||
|
@ -4,7 +4,6 @@ This module contains articles about querying data using Spring Data JPA .
|
|||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [Spring Data JPA @Query](https://www.baeldung.com/spring-data-jpa-query)
|
|
||||||
- [Use Criteria Queries in a Spring Data Application](https://www.baeldung.com/spring-data-criteria-queries)
|
- [Use Criteria Queries in a Spring Data Application](https://www.baeldung.com/spring-data-criteria-queries)
|
||||||
- [Hibernate Pagination](https://www.baeldung.com/hibernate-pagination)
|
- [Hibernate Pagination](https://www.baeldung.com/hibernate-pagination)
|
||||||
- [Sorting with Hibernate](https://www.baeldung.com/hibernate-sort)
|
- [Sorting with Hibernate](https://www.baeldung.com/hibernate-sort)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.baeldung.derivedquery;
|
package com.baeldung;
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
@ -4,7 +4,6 @@ This module contains articles about querying data using Spring Data JPA
|
|||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [The Exists Query in Spring Data](https://www.baeldung.com/spring-data-exists-query)
|
- [The Exists Query in Spring Data](https://www.baeldung.com/spring-data-exists-query)
|
||||||
- [Customizing the Result of JPA Queries with Aggregation Functions](https://www.baeldung.com/jpa-queries-custom-result-with-aggregation-functions)
|
|
||||||
- [Limiting Query Results With JPA and Spring Data JPA](https://www.baeldung.com/jpa-limit-query-results)
|
- [Limiting Query Results With JPA and Spring Data JPA](https://www.baeldung.com/jpa-limit-query-results)
|
||||||
- [Sorting Query Results with Spring Data](https://www.baeldung.com/spring-data-sorting)
|
- [Sorting Query Results with Spring Data](https://www.baeldung.com/spring-data-sorting)
|
||||||
- [Spring Data JPA Query by Example](https://www.baeldung.com/spring-data-query-by-example)
|
- [Spring Data JPA Query by Example](https://www.baeldung.com/spring-data-query-by-example)
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
This module contains articles about Spring Data JPA.
|
This module contains articles about Spring Data JPA.
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [New CRUD Repository Interfaces in Spring Data 3](https://www.baeldung.com/spring-data-3-crud-repository-interfaces)
|
|
||||||
- [How to Persist a List of String in JPA?](https://www.baeldung.com/java-jpa-persist-string-list)
|
- [How to Persist a List of String in JPA?](https://www.baeldung.com/java-jpa-persist-string-list)
|
||||||
- [Hibernate Natural IDs in Spring Boot](https://www.baeldung.com/spring-boot-hibernate-natural-ids)
|
- [Hibernate Natural IDs in Spring Boot](https://www.baeldung.com/spring-boot-hibernate-natural-ids)
|
||||||
- [Correct Use of flush() in JPA](https://www.baeldung.com/spring-jpa-flush)
|
- [Correct Use of flush() in JPA](https://www.baeldung.com/spring-jpa-flush)
|
||||||
|
@ -10,14 +10,14 @@ import org.springframework.boot.test.context.SpringBootTest;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
public class LibraryIntegrationTest {
|
class LibraryIntegrationTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private LibraryRepository libraryRepository;
|
private LibraryRepository libraryRepository;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Transactional
|
@Transactional
|
||||||
public void givenLibrary_whenGetAddressesAndGetBooks_thenGetListOfItems(){
|
void givenLibrary_whenGetAddressesAndGetBooks_thenGetListOfItems(){
|
||||||
Library library = new Library();
|
Library library = new Library();
|
||||||
library.setAddresses(Arrays.asList("Address 1", "Address 2"));
|
library.setAddresses(Arrays.asList("Address 1", "Address 2"));
|
||||||
library.setBooks(Arrays.asList("Book 1", "Book 2"));
|
library.setBooks(Arrays.asList("Book 1", "Book 2"));
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
This module contains articles about repositories in Spring Data JPA
|
This module contains articles about repositories in Spring Data JPA
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Introduction to Spring Data JPA](https://www.baeldung.com/the-persistence-layer-with-spring-data-jpa)
|
|
||||||
- [Case Insensitive Queries with Spring Data Repository](https://www.baeldung.com/spring-data-case-insensitive-queries)
|
- [Case Insensitive Queries with Spring Data Repository](https://www.baeldung.com/spring-data-case-insensitive-queries)
|
||||||
- [Derived Query Methods in Spring Data JPA Repositories](https://www.baeldung.com/spring-data-derived-queries)
|
|
||||||
- [Spring Data – CrudRepository save() Method](https://www.baeldung.com/spring-data-crud-repository-save)
|
- [Spring Data – CrudRepository save() Method](https://www.baeldung.com/spring-data-crud-repository-save)
|
||||||
- [Spring Data JPA – Adding a Method in All Repositories](https://www.baeldung.com/spring-data-jpa-method-in-all-repositories)
|
- [Spring Data JPA – Adding a Method in All Repositories](https://www.baeldung.com/spring-data-jpa-method-in-all-repositories)
|
||||||
- [Spring Data Composable Repositories](https://www.baeldung.com/spring-data-composable-repositories)
|
- [Spring Data Composable Repositories](https://www.baeldung.com/spring-data-composable-repositories)
|
||||||
|
@ -1,172 +0,0 @@
|
|||||||
package com.baeldung.derivedquery.repository;
|
|
||||||
|
|
||||||
import com.baeldung.derivedquery.QueryApplication;
|
|
||||||
import com.baeldung.derivedquery.entity.User;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
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.test.context.junit4.SpringRunner;
|
|
||||||
|
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
|
||||||
@SpringBootTest(classes = QueryApplication.class)
|
|
||||||
public class UserRepositoryIntegrationTest {
|
|
||||||
|
|
||||||
private static final String USER_NAME_ADAM = "Adam";
|
|
||||||
private static final String USER_NAME_EVE = "Eve";
|
|
||||||
private static final ZonedDateTime BIRTHDATE = ZonedDateTime.now();
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private UserRepository userRepository;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
|
|
||||||
User user1 = new User(USER_NAME_ADAM, 25, BIRTHDATE, true);
|
|
||||||
User user2 = new User(USER_NAME_ADAM, 20, BIRTHDATE, false);
|
|
||||||
User user3 = new User(USER_NAME_EVE, 20, BIRTHDATE, true);
|
|
||||||
User user4 = new User(null, 30, BIRTHDATE, false);
|
|
||||||
|
|
||||||
userRepository.saveAll(Arrays.asList(user1, user2, user3, user4));
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() {
|
|
||||||
|
|
||||||
userRepository.deleteAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenFindByName_thenReturnsCorrectResult() {
|
|
||||||
|
|
||||||
assertEquals(2, userRepository.findByName(USER_NAME_ADAM).size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenFindByNameIsNull_thenReturnsCorrectResult() {
|
|
||||||
|
|
||||||
assertEquals(1, userRepository.findByNameIsNull().size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenFindByNameNot_thenReturnsCorrectResult() {
|
|
||||||
|
|
||||||
assertEquals(USER_NAME_EVE, userRepository.findByNameNot(USER_NAME_ADAM).get(0).getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenFindByNameStartingWith_thenReturnsCorrectResult() {
|
|
||||||
|
|
||||||
assertEquals(2, userRepository.findByNameStartingWith("A").size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenFindByNameEndingWith_thenReturnsCorrectResult() {
|
|
||||||
|
|
||||||
assertEquals(1, userRepository.findByNameEndingWith("e").size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenByNameContaining_thenReturnsCorrectResult() {
|
|
||||||
|
|
||||||
assertEquals(1, userRepository.findByNameContaining("v").size());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenByNameLike_thenReturnsCorrectResult() {
|
|
||||||
|
|
||||||
assertEquals(2, userRepository.findByNameEndingWith("m").size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenByAgeLessThan_thenReturnsCorrectResult() {
|
|
||||||
|
|
||||||
assertEquals(2, userRepository.findByAgeLessThan(25).size());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenByAgeLessThanEqual_thenReturnsCorrectResult() {
|
|
||||||
|
|
||||||
assertEquals(3, userRepository.findByAgeLessThanEqual(25).size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenByAgeGreaterThan_thenReturnsCorrectResult() {
|
|
||||||
|
|
||||||
assertEquals(1, userRepository.findByAgeGreaterThan(25).size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenByAgeGreaterThanEqual_thenReturnsCorrectResult() {
|
|
||||||
|
|
||||||
assertEquals(2, userRepository.findByAgeGreaterThanEqual(25).size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenByAgeBetween_thenReturnsCorrectResult() {
|
|
||||||
|
|
||||||
assertEquals(4, userRepository.findByAgeBetween(20, 30).size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenByBirthDateAfter_thenReturnsCorrectResult() {
|
|
||||||
|
|
||||||
final ZonedDateTime yesterday = BIRTHDATE.minusDays(1);
|
|
||||||
assertEquals(4, userRepository.findByBirthDateAfter(yesterday).size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenByBirthDateBefore_thenReturnsCorrectResult() {
|
|
||||||
|
|
||||||
final ZonedDateTime yesterday = BIRTHDATE.minusDays(1);
|
|
||||||
assertEquals(0, userRepository.findByBirthDateBefore(yesterday).size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenByActiveTrue_thenReturnsCorrectResult() {
|
|
||||||
|
|
||||||
assertEquals(2, userRepository.findByActiveTrue().size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenByActiveFalse_thenReturnsCorrectResult() {
|
|
||||||
|
|
||||||
assertEquals(2, userRepository.findByActiveFalse().size());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenByAgeIn_thenReturnsCorrectResult() {
|
|
||||||
|
|
||||||
final List<Integer> ages = Arrays.asList(20, 25);
|
|
||||||
assertEquals(3, userRepository.findByAgeIn(ages).size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenByNameOrAge() {
|
|
||||||
|
|
||||||
assertEquals(3, userRepository.findByNameOrAge(USER_NAME_ADAM, 20).size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenByNameOrAgeAndActive() {
|
|
||||||
|
|
||||||
assertEquals(2, userRepository.findByNameOrAgeAndActive(USER_NAME_ADAM, 20, false).size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenByNameOrderByName() {
|
|
||||||
|
|
||||||
assertEquals(2, userRepository.findByNameOrderByName(USER_NAME_ADAM).size());
|
|
||||||
}
|
|
||||||
}
|
|
20
persistence-modules/spring-data-jpa-simple/README.md
Normal file
20
persistence-modules/spring-data-jpa-simple/README.md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
### Spring Data JPA Articles that are also part of the e-book
|
||||||
|
|
||||||
|
This module contains articles about Spring Data JPA that are also part of an Ebook.
|
||||||
|
|
||||||
|
|
||||||
|
### NOTE:
|
||||||
|
|
||||||
|
Since this is a module tied to an e-book, it should **not** be moved or used to store the code for any further article.
|
||||||
|
|
||||||
|
### Relevant Articles
|
||||||
|
- [Introduction to Spring Data JPA](https://www.baeldung.com/the-persistence-layer-with-spring-data-jpa)
|
||||||
|
- [Customizing the Result of JPA Queries with Aggregation Functions](https://www.baeldung.com/jpa-queries-custom-result-with-aggregation-functions)
|
||||||
|
- [CrudRepository, JpaRepository, and PagingAndSortingRepository in Spring Data](https://www.baeldung.com/spring-data-repositories)
|
||||||
|
- [New CRUD Repository Interfaces in Spring Data 3](https://www.baeldung.com/spring-data-3-crud-repository-interfaces)
|
||||||
|
- [Derived Query Methods in Spring Data JPA Repositories](https://www.baeldung.com/spring-data-derived-queries)
|
||||||
|
- [Spring Data JPA @Query](https://www.baeldung.com/spring-data-jpa-query)
|
||||||
|
- [Spring Data JPA Projections](https://www.baeldung.com/spring-data-jpa-projections)
|
||||||
|
- [Spring Data JPA @Modifying Annotation](https://www.baeldung.com/spring-data-jpa-modifying-annotation)
|
||||||
|
- [Generate Database Schema with Spring Data JPA](https://www.baeldung.com/spring-data-jpa-generate-db-schema)
|
||||||
|
- [Pagination and Sorting using Spring Data JPA](https://www.baeldung.com/spring-data-jpa-pagination-sorting)
|
88
persistence-modules/spring-data-jpa-simple/pom.xml
Normal file
88
persistence-modules/spring-data-jpa-simple/pom.xml
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>spring-data-jpa-simple</artifactId>
|
||||||
|
<name>spring-data-jpa-simple</name>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-boot-3</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../../parent-boot-3</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jdbc</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-oxm</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>${guava.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.xml.bind</groupId>
|
||||||
|
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||||
|
<version>${jakarta.xml.bind.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate.orm</groupId>
|
||||||
|
<artifactId>hibernate-ant</artifactId>
|
||||||
|
<version>${hibernate.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<hibernate.version>6.4.2.Final</hibernate.version>
|
||||||
|
<jakarta.xml.bind.version>4.0.0</jakarta.xml.bind.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>repackage</id>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.baeldung.jpa.aggregation;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.PropertySource;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@PropertySource("classpath:aggregation.properties")
|
||||||
|
@Configuration
|
||||||
|
public class AggregationApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(AggregationApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,9 +1,10 @@
|
|||||||
package com.baeldung.aggregation.model;
|
package com.baeldung.jpa.aggregation.model;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
import jakarta.persistence.ManyToOne;
|
import jakarta.persistence.ManyToOne;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class Comment {
|
public class Comment {
|
@ -1,13 +1,15 @@
|
|||||||
package com.baeldung.aggregation.model;
|
package com.baeldung.jpa.aggregation.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
import jakarta.persistence.OneToMany;
|
import jakarta.persistence.OneToMany;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class Post {
|
public class Post {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
private Integer id;
|
private Integer id;
|
||||||
private String title;
|
private String title;
|
@ -1,4 +1,4 @@
|
|||||||
package com.baeldung.aggregation.model.custom;
|
package com.baeldung.jpa.aggregation.model.custom;
|
||||||
|
|
||||||
public class CommentCount {
|
public class CommentCount {
|
||||||
private Integer year;
|
private Integer year;
|
@ -1,4 +1,4 @@
|
|||||||
package com.baeldung.aggregation.model.custom;
|
package com.baeldung.jpa.aggregation.model.custom;
|
||||||
|
|
||||||
public interface ICommentCount {
|
public interface ICommentCount {
|
||||||
|
|
@ -1,13 +1,14 @@
|
|||||||
package com.baeldung.aggregation.repository;
|
package com.baeldung.jpa.aggregation.repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.baeldung.aggregation.model.Comment;
|
|
||||||
import com.baeldung.aggregation.model.custom.CommentCount;
|
|
||||||
import com.baeldung.aggregation.model.custom.ICommentCount;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import java.util.List;
|
import com.baeldung.jpa.aggregation.model.Comment;
|
||||||
|
import com.baeldung.jpa.aggregation.model.custom.CommentCount;
|
||||||
|
import com.baeldung.jpa.aggregation.model.custom.ICommentCount;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public interface CommentRepository extends JpaRepository<Comment, Integer> {
|
public interface CommentRepository extends JpaRepository<Comment, Integer> {
|
||||||
@ -15,7 +16,7 @@ public interface CommentRepository extends JpaRepository<Comment, Integer> {
|
|||||||
@Query("SELECT c.year, COUNT(c.year) FROM Comment AS c GROUP BY c.year ORDER BY c.year DESC")
|
@Query("SELECT c.year, COUNT(c.year) FROM Comment AS c GROUP BY c.year ORDER BY c.year DESC")
|
||||||
List<Object[]> countTotalCommentsByYear();
|
List<Object[]> countTotalCommentsByYear();
|
||||||
|
|
||||||
@Query("SELECT new com.baeldung.aggregation.model.custom.CommentCount(c.year, COUNT(c.year)) FROM Comment AS c GROUP BY c.year ORDER BY c.year DESC")
|
@Query("SELECT new com.baeldung.jpa.aggregation.model.custom.CommentCount(c.year, COUNT(c.year)) FROM Comment AS c GROUP BY c.year ORDER BY c.year DESC")
|
||||||
List<CommentCount> countTotalCommentsByYearClass();
|
List<CommentCount> countTotalCommentsByYearClass();
|
||||||
|
|
||||||
@Query("SELECT c.year AS yearComment, COUNT(c.year) AS totalComment FROM Comment AS c GROUP BY c.year ORDER BY c.year DESC")
|
@Query("SELECT c.year AS yearComment, COUNT(c.year) AS totalComment FROM Comment AS c GROUP BY c.year ORDER BY c.year DESC")
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.baeldung.jpa.modifying;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||||
|
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableJpaRepositories("com.baeldung.jpa.modifying")
|
||||||
|
@EntityScan("com.baeldung.jpa.modifying")
|
||||||
|
public class ModifyingApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(ModifyingApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.baeldung.jpa.modifying.dao;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
import com.baeldung.jpa.modifying.model.User;
|
||||||
|
|
||||||
|
public interface UserRepository extends JpaRepository<User, Integer> {
|
||||||
|
|
||||||
|
Stream<User> findAllByName(String name);
|
||||||
|
|
||||||
|
void deleteAllByCreationDateAfter(LocalDate date);
|
||||||
|
|
||||||
|
@Query("select u from User u where u.email like '%@gmail.com'")
|
||||||
|
List<User> findUsersWithGmailAddress();
|
||||||
|
|
||||||
|
@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 not null default 0", nativeQuery = true)
|
||||||
|
void addDeletedColumn();
|
||||||
|
|
||||||
|
@Query("delete User u where u.active = false")
|
||||||
|
int deleteDeactivatedUsersWithNoModifyingAnnotation();
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
package com.baeldung.jpa.modifying.model;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,138 @@
|
|||||||
|
package com.baeldung.jpa.modifying.model;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.OneToMany;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
|
@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<Possession> 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<Possession> getPossessionList() {
|
||||||
|
return possessionList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPossessionList(List<Possession> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.baeldung.jpa.paginationsorting;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication(scanBasePackages = "com.baeldung.jpa.paginationsorting")
|
||||||
|
public class PaginationSortingApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(PaginationSortingApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package com.baeldung.jpa.paginationsorting;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
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.PlatformTransactionManager;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@PropertySource({ "classpath:pagination-sorting-db.properties" })
|
||||||
|
@EnableJpaRepositories(basePackages = "com.baeldung.jpa.paginationsorting", entityManagerFactoryRef = "productEntityManager", transactionManagerRef = "productTransactionManager")
|
||||||
|
public class PersistenceProductConfiguration {
|
||||||
|
private final Environment env;
|
||||||
|
|
||||||
|
public PersistenceProductConfiguration(Environment env) {
|
||||||
|
this.env = env;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public LocalContainerEntityManagerFactoryBean productEntityManager() {
|
||||||
|
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
|
||||||
|
em.setDataSource(productDataSource());
|
||||||
|
em.setPackagesToScan("com.baeldung.jpa.paginationsorting");
|
||||||
|
|
||||||
|
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
|
||||||
|
em.setJpaVendorAdapter(vendorAdapter);
|
||||||
|
final HashMap<String, Object> properties = new HashMap<String, Object>();
|
||||||
|
properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
|
||||||
|
properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
|
||||||
|
em.setJpaPropertyMap(properties);
|
||||||
|
|
||||||
|
return em;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public DataSource productDataSource() {
|
||||||
|
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
|
||||||
|
dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
|
||||||
|
dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("product.jdbc.url")));
|
||||||
|
dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
|
||||||
|
dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));
|
||||||
|
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PlatformTransactionManager productTransactionManager() {
|
||||||
|
final JpaTransactionManager transactionManager = new JpaTransactionManager();
|
||||||
|
transactionManager.setEntityManagerFactory(productEntityManager().getObject());
|
||||||
|
return transactionManager;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package com.baeldung.jpa.paginationsorting.model;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(schema = "products")
|
||||||
|
public class Product {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private double price;
|
||||||
|
|
||||||
|
public Product() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Product(int id, String name, double price) {
|
||||||
|
super();
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Product from(int id, String name, double price) {
|
||||||
|
return new Product(id, name, price);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 double getPrice() {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrice(final double price) {
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("Product [name=")
|
||||||
|
.append(name)
|
||||||
|
.append(", id=")
|
||||||
|
.append(id)
|
||||||
|
.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.baeldung.jpa.paginationsorting.repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||||
|
|
||||||
|
import com.baeldung.jpa.paginationsorting.model.Product;
|
||||||
|
|
||||||
|
public interface ProductRepository extends PagingAndSortingRepository<Product, Integer>, CrudRepository<Product, Integer> {
|
||||||
|
|
||||||
|
List<Product> findAllByPrice(double price, Pageable pageable);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.baeldung.jpa.projection;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class ProjectionApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(ProjectionApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
package com.baeldung.projection.model;
|
package com.baeldung.jpa.projection.model;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import javax.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
import javax.persistence.OneToOne;
|
import jakarta.persistence.OneToOne;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class Address {
|
public class Address {
|
@ -1,8 +1,8 @@
|
|||||||
package com.baeldung.projection.model;
|
package com.baeldung.jpa.projection.model;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import javax.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
import javax.persistence.OneToOne;
|
import jakarta.persistence.OneToOne;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class Person {
|
public class Person {
|
@ -1,11 +1,12 @@
|
|||||||
package com.baeldung.projection.repository;
|
package com.baeldung.jpa.projection.repository;
|
||||||
|
|
||||||
import com.baeldung.projection.view.AddressView;
|
|
||||||
import com.baeldung.projection.model.Address;
|
|
||||||
import org.springframework.data.repository.Repository;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.data.repository.Repository;
|
||||||
|
|
||||||
|
import com.baeldung.jpa.projection.model.Address;
|
||||||
|
import com.baeldung.jpa.projection.view.AddressView;
|
||||||
|
|
||||||
public interface AddressRepository extends Repository<Address, Long> {
|
public interface AddressRepository extends Repository<Address, Long> {
|
||||||
List<AddressView> getAddressByState(String state);
|
List<AddressView> getAddressByState(String state);
|
||||||
}
|
}
|
@ -1,10 +1,11 @@
|
|||||||
package com.baeldung.projection.repository;
|
package com.baeldung.jpa.projection.repository;
|
||||||
|
|
||||||
import com.baeldung.projection.model.Person;
|
|
||||||
import com.baeldung.projection.view.PersonDto;
|
|
||||||
import com.baeldung.projection.view.PersonView;
|
|
||||||
import org.springframework.data.repository.Repository;
|
import org.springframework.data.repository.Repository;
|
||||||
|
|
||||||
|
import com.baeldung.jpa.projection.model.Person;
|
||||||
|
import com.baeldung.jpa.projection.view.PersonDto;
|
||||||
|
import com.baeldung.jpa.projection.view.PersonView;
|
||||||
|
|
||||||
public interface PersonRepository extends Repository<Person, Long> {
|
public interface PersonRepository extends Repository<Person, Long> {
|
||||||
PersonView findByLastName(String lastName);
|
PersonView findByLastName(String lastName);
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package com.baeldung.projection.view;
|
package com.baeldung.jpa.projection.view;
|
||||||
|
|
||||||
public interface AddressView {
|
public interface AddressView {
|
||||||
String getZipCode();
|
String getZipCode();
|
@ -1,4 +1,4 @@
|
|||||||
package com.baeldung.projection.view;
|
package com.baeldung.jpa.projection.view;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package com.baeldung.projection.view;
|
package com.baeldung.jpa.projection.view;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
|
@ -1,9 +1,11 @@
|
|||||||
package com.baeldung.spring.data.jpa.query;
|
package com.baeldung.jpa.query;
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
|
//@ComponentScan("com.baeldung.jpa.query")
|
||||||
|
//@EnableJpaRepositories("com.baeldung.jpa.query")
|
||||||
public class QueryApplication {
|
public class QueryApplication {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
@ -1,10 +1,15 @@
|
|||||||
package com.baeldung.spring.data.jpa.query;
|
package com.baeldung.jpa.query;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "users")
|
@Table(name = "users")
|
||||||
public class User {
|
public class User {
|
@ -1,4 +1,7 @@
|
|||||||
package com.baeldung.spring.data.jpa.query;
|
package com.baeldung.jpa.query;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
@ -7,10 +10,9 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
|||||||
import org.springframework.data.jpa.repository.Modifying;
|
import org.springframework.data.jpa.repository.Modifying;
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import java.util.Collection;
|
@Repository
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface UserRepository extends JpaRepository<User, Integer>, UserRepositoryCustom {
|
public interface UserRepository extends JpaRepository<User, Integer>, UserRepositoryCustom {
|
||||||
@Query("SELECT u FROM User u WHERE u.status = 1")
|
@Query("SELECT u FROM User u WHERE u.status = 1")
|
||||||
Collection<User> findAllActiveUsers();
|
Collection<User> findAllActiveUsers();
|
@ -1,4 +1,4 @@
|
|||||||
package com.baeldung.spring.data.jpa.query;
|
package com.baeldung.jpa.query;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
@ -1,8 +1,5 @@
|
|||||||
package com.baeldung.spring.data.jpa.query;
|
package com.baeldung.jpa.query;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
import jakarta.persistence.PersistenceContext;
|
|
||||||
import jakarta.persistence.criteria.*;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -10,6 +7,14 @@ import java.util.Set;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
import jakarta.persistence.PersistenceContext;
|
||||||
|
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||||
|
import jakarta.persistence.criteria.CriteriaQuery;
|
||||||
|
import jakarta.persistence.criteria.Path;
|
||||||
|
import jakarta.persistence.criteria.Predicate;
|
||||||
|
import jakarta.persistence.criteria.Root;
|
||||||
|
|
||||||
public class UserRepositoryCustomImpl implements UserRepositoryCustom {
|
public class UserRepositoryCustomImpl implements UserRepositoryCustom {
|
||||||
@PersistenceContext
|
@PersistenceContext
|
||||||
private EntityManager entityManager;
|
private EntityManager entityManager;
|
@ -1,9 +1,11 @@
|
|||||||
package com.baeldung.schemageneration;
|
package com.baeldung.jpa.schemageneration;
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.context.annotation.PropertySource;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
|
@PropertySource("classpath:schema-generation.properties")
|
||||||
public class AccountApplication {
|
public class AccountApplication {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
@ -1,7 +1,9 @@
|
|||||||
package com.baeldung.schemageneration;
|
package com.baeldung.jpa.schemageneration;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import com.baeldung.schemageneration.model.Account;
|
|
||||||
import com.baeldung.schemageneration.model.AccountSetting;
|
|
||||||
import org.hibernate.boot.Metadata;
|
import org.hibernate.boot.Metadata;
|
||||||
import org.hibernate.boot.MetadataSources;
|
import org.hibernate.boot.MetadataSources;
|
||||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||||
@ -10,9 +12,8 @@ import org.hibernate.cfg.Environment;
|
|||||||
import org.hibernate.tool.hbm2ddl.SchemaExport;
|
import org.hibernate.tool.hbm2ddl.SchemaExport;
|
||||||
import org.hibernate.tool.schema.TargetType;
|
import org.hibernate.tool.schema.TargetType;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import com.baeldung.jpa.schemageneration.model.Account;
|
||||||
import java.util.HashMap;
|
import com.baeldung.jpa.schemageneration.model.AccountSetting;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class HibernateUtil {
|
public class HibernateUtil {
|
||||||
|
|
||||||
@ -21,7 +22,7 @@ public class HibernateUtil {
|
|||||||
* Creation commands are exported into the create.sql file.
|
* Creation commands are exported into the create.sql file.
|
||||||
*/
|
*/
|
||||||
public static void generateSchema() {
|
public static void generateSchema() {
|
||||||
Map<String, String> settings = new HashMap<>();
|
Map<String, Object> settings = new HashMap<>();
|
||||||
settings.put(Environment.URL, "jdbc:h2:mem:schema");
|
settings.put(Environment.URL, "jdbc:h2:mem:schema");
|
||||||
|
|
||||||
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(settings).build();
|
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(settings).build();
|
@ -1,15 +1,16 @@
|
|||||||
package com.baeldung.schemageneration.model;
|
package com.baeldung.jpa.schemageneration.model;
|
||||||
|
|
||||||
import javax.persistence.CascadeType;
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.OneToMany;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import jakarta.persistence.CascadeType;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.OneToMany;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "accounts")
|
@Table(name = "accounts")
|
||||||
public class Account {
|
public class Account {
|
@ -1,12 +1,12 @@
|
|||||||
package com.baeldung.schemageneration.model;
|
package com.baeldung.jpa.schemageneration.model;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import jakarta.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import javax.persistence.GeneratedValue;
|
import jakarta.persistence.GeneratedValue;
|
||||||
import javax.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
import javax.persistence.JoinColumn;
|
import jakarta.persistence.JoinColumn;
|
||||||
import javax.persistence.ManyToOne;
|
import jakarta.persistence.ManyToOne;
|
||||||
import javax.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "account_settings")
|
@Table(name = "account_settings")
|
@ -1,8 +1,9 @@
|
|||||||
package com.baeldung.schemageneration.repository;
|
package com.baeldung.jpa.schemageneration.repository;
|
||||||
|
|
||||||
import com.baeldung.schemageneration.model.Account;
|
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
|
||||||
|
import com.baeldung.jpa.schemageneration.model.Account;
|
||||||
|
|
||||||
public interface AccountRepository extends CrudRepository<Account, Long> {
|
public interface AccountRepository extends CrudRepository<Account, Long> {
|
||||||
Account findByName(String name);
|
Account findByName(String name);
|
||||||
}
|
}
|
@ -1,8 +1,10 @@
|
|||||||
package com.baeldung.schemageneration.repository;
|
package com.baeldung.jpa.schemageneration.repository;
|
||||||
|
|
||||||
import com.baeldung.schemageneration.model.AccountSetting;
|
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
|
||||||
|
import com.baeldung.jpa.schemageneration.model.AccountSetting;
|
||||||
|
|
||||||
public interface AccountSettingRepository extends CrudRepository<AccountSetting, Long> {
|
public interface AccountSettingRepository extends CrudRepository<AccountSetting, Long> {
|
||||||
|
|
||||||
AccountSetting findByAccountId(Long accountId);
|
AccountSetting findByAccountId(Long accountId);
|
||||||
}
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.baeldung.jpa.simple;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableJpaRepositories("com.baeldung.jpa.simple.repository")
|
||||||
|
public class JpaApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(JpaApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
package com.baeldung.jpa.simple.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.Configuration;
|
||||||
|
import org.springframework.context.annotation.PropertySource;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
|
||||||
|
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
|
||||||
|
@PropertySource("classpath:persistence.properties")
|
||||||
|
@EnableTransactionManagement
|
||||||
|
//@ImportResource("classpath*:*springDataConfig.xml")
|
||||||
|
public class PersistenceConfig {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private Environment env;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
|
||||||
|
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
|
||||||
|
em.setDataSource(dataSource());
|
||||||
|
em.setPackagesToScan("com.baeldung.jpa.simple.entity");
|
||||||
|
|
||||||
|
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
|
||||||
|
em.setJpaVendorAdapter(vendorAdapter);
|
||||||
|
em.setJpaProperties(additionalProperties());
|
||||||
|
|
||||||
|
return em;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public DataSource dataSource() {
|
||||||
|
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
|
||||||
|
dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
|
||||||
|
dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
|
||||||
|
dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
|
||||||
|
dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));
|
||||||
|
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PlatformTransactionManager transactionManager() {
|
||||||
|
final 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"));
|
||||||
|
|
||||||
|
return hibernateProperties;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package com.baeldung.jpa.simple.entity;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Book {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
private String title;
|
||||||
|
private String author;
|
||||||
|
private String isbn;
|
||||||
|
|
||||||
|
public Book() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Book(String title, String author, String isbn) {
|
||||||
|
this.title = title;
|
||||||
|
this.author = author;
|
||||||
|
this.isbn = isbn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthor() {
|
||||||
|
return author;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthor(String author) {
|
||||||
|
this.author = author;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIsbn() {
|
||||||
|
return isbn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsbn(String isbn) {
|
||||||
|
this.isbn = isbn;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
package com.baeldung.jpa.simple.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.baeldung.derivedquery.entity;
|
package com.baeldung.jpa.simple.entity;
|
||||||
|
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
|
|
@ -1,10 +1,11 @@
|
|||||||
package com.baeldung.spring.data.jpa.listrepositories.repository;
|
package com.baeldung.jpa.simple.repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.baeldung.spring.data.jpa.listrepositories.entity.Book;
|
|
||||||
import org.springframework.data.repository.ListCrudRepository;
|
import org.springframework.data.repository.ListCrudRepository;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import java.util.List;
|
import com.baeldung.jpa.simple.entity.Book;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public interface BookListRepository extends ListCrudRepository<Book, Long> {
|
public interface BookListRepository extends ListCrudRepository<Book, Long> {
|
@ -1,12 +1,13 @@
|
|||||||
package com.baeldung.spring.data.jpa.listrepositories.repository;
|
package com.baeldung.jpa.simple.repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.baeldung.spring.data.jpa.listrepositories.entity.Book;
|
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.repository.ListCrudRepository;
|
import org.springframework.data.repository.ListCrudRepository;
|
||||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import java.util.List;
|
import com.baeldung.jpa.simple.entity.Book;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public interface BookPagingAndSortingRepository extends PagingAndSortingRepository<Book, Long>, ListCrudRepository<Book, Long> {
|
public interface BookPagingAndSortingRepository extends PagingAndSortingRepository<Book, Long>, ListCrudRepository<Book, Long> {
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.baeldung.jpa.simple.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
|
||||||
|
import com.baeldung.jpa.simple.entity.Foo;
|
||||||
|
|
||||||
|
public interface IFooDAO extends JpaRepository<Foo, Long> {
|
||||||
|
|
||||||
|
Foo findByName(String name);
|
||||||
|
|
||||||
|
@Query("SELECT f FROM Foo f WHERE LOWER(f.name) = LOWER(:name)")
|
||||||
|
Foo retrieveByName(@Param("name") String name);
|
||||||
|
}
|
@ -1,15 +1,14 @@
|
|||||||
package com.baeldung.derivedquery.repository;
|
package com.baeldung.jpa.simple.repository;
|
||||||
|
|
||||||
import com.baeldung.derivedquery.entity.User;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.Query;
|
|
||||||
import org.springframework.data.repository.query.Param;
|
|
||||||
|
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface UserRepository extends JpaRepository<User, Integer> {
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import com.baeldung.jpa.simple.entity.User;
|
||||||
|
|
||||||
|
public interface UserRepository extends JpaRepository<User, Integer>, UserRepositoryCustom {
|
||||||
|
|
||||||
List<User> findByName(String name);
|
List<User> findByName(String name);
|
||||||
|
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.baeldung.jpa.simple.repository;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import com.baeldung.jpa.simple.entity.User;
|
||||||
|
|
||||||
|
public interface UserRepositoryCustom {
|
||||||
|
|
||||||
|
List<User> findUserByEmails(Set<String> emails);
|
||||||
|
|
||||||
|
List<User> findAllUsersByPredicates(Collection<Predicate<User>> predicates);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package com.baeldung.jpa.simple.repository;
|
||||||
|
|
||||||
|
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 com.baeldung.jpa.simple.entity.User;
|
||||||
|
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
import jakarta.persistence.PersistenceContext;
|
||||||
|
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||||
|
import jakarta.persistence.criteria.CriteriaQuery;
|
||||||
|
import jakarta.persistence.criteria.Path;
|
||||||
|
import jakarta.persistence.criteria.Predicate;
|
||||||
|
import jakarta.persistence.criteria.Root;
|
||||||
|
|
||||||
|
public class UserRepositoryCustomImpl implements UserRepositoryCustom {
|
||||||
|
|
||||||
|
@PersistenceContext
|
||||||
|
private EntityManager entityManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<User> findUserByEmails(Set<String> emails) {
|
||||||
|
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<User> query = cb.createQuery(User.class);
|
||||||
|
Root<User> user = query.from(User.class);
|
||||||
|
|
||||||
|
Path<String> emailPath = user.get("email");
|
||||||
|
|
||||||
|
List<Predicate> 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<User> findAllUsersByPredicates(Collection<java.util.function.Predicate<User>> predicates) {
|
||||||
|
List<User> allUsers = entityManager.createQuery("select u from User u", User.class)
|
||||||
|
.getResultList();
|
||||||
|
Stream<User> allUsersStream = allUsers.stream();
|
||||||
|
for (java.util.function.Predicate<User> predicate : predicates) {
|
||||||
|
allUsersStream = allUsersStream.filter(predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return allUsersStream.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.baeldung.jpa.simple.service;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.baeldung.jpa.simple.entity.Foo;
|
||||||
|
import com.baeldung.jpa.simple.repository.IFooDAO;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class FooService implements IFooService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IFooDAO dao;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Foo create(Foo foo) {
|
||||||
|
return dao.save(foo);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.baeldung.jpa.simple.service;
|
||||||
|
|
||||||
|
import com.baeldung.jpa.simple.entity.Foo;
|
||||||
|
|
||||||
|
public interface IFooService {
|
||||||
|
Foo create(Foo foo);
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
spring.jpa.show-sql=false
|
||||||
|
spring.jpa.defer-datasource-initialization=true
|
||||||
|
spring.jpa.properties.hibernate.globally_quoted_identifiers=true
|
@ -0,0 +1,6 @@
|
|||||||
|
spring.jpa.show-sql=false
|
||||||
|
spring.jpa.defer-datasource-initialization=true
|
||||||
|
#MySql
|
||||||
|
#spring.datasource.url=jdbc:mysql://localhost:3306/baeldung
|
||||||
|
#spring.datasource.username=baeldung
|
||||||
|
#spring.datasource.password=baeldung
|
@ -0,0 +1,8 @@
|
|||||||
|
insert into Users(name, creation_date, last_login_date, active, age, email, status)
|
||||||
|
values('John', PARSEDATETIME('01/01/2018', 'dd/MM/yyyy'), PARSEDATETIME('01/01/2020', 'dd/MM/yyyy'), 1, 23, 'john@email.com', 1);
|
||||||
|
|
||||||
|
insert into Users(name, creation_date, last_login_date, active, age, email, status)
|
||||||
|
values('Bob', PARSEDATETIME('02/02/2019', 'dd/MM/yyyy'), PARSEDATETIME('02/02/2020', 'dd/MM/yyyy'), 1, 56, 'bob@email.com', 1);
|
||||||
|
|
||||||
|
insert into Users(name, creation_date, last_login_date, active, age, email, status)
|
||||||
|
values('Cindy', PARSEDATETIME('02/02/2019', 'dd/MM/yyyy'), PARSEDATETIME('02/02/2020', 'dd/MM/yyyy'), 1, 18, 'cindy@email.com', 0);
|
@ -0,0 +1,6 @@
|
|||||||
|
# jdbc.X
|
||||||
|
jdbc.driverClassName=org.h2.Driver
|
||||||
|
product.jdbc.url=jdbc:h2:mem:spring_jpa_product;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS PRODUCTS
|
||||||
|
jdbc.user=sa
|
||||||
|
jdbc.pass=sa
|
||||||
|
hibernate.hbm2ddl.auto=create-drop
|
@ -0,0 +1,9 @@
|
|||||||
|
# jdbc.X
|
||||||
|
jdbc.driverClassName=org.h2.Driver
|
||||||
|
jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
|
||||||
|
jdbc.user=sa
|
||||||
|
jdbc.pass=sa
|
||||||
|
|
||||||
|
# hibernate.X
|
||||||
|
hibernate.hbm2ddl.auto=create-drop
|
||||||
|
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
|
||||||
|
xsi:schemaLocation="
|
||||||
|
http://www.springframework.org/schema/beans
|
||||||
|
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
|
http://www.springframework.org/schema/data/jpa
|
||||||
|
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"
|
||||||
|
>
|
||||||
|
<jpa:repositories base-package="com.baeldung.jpa.simple.repository"/>
|
||||||
|
</beans>
|
@ -1,23 +1,28 @@
|
|||||||
package com.baeldung.aggregation;
|
package com.baeldung.jpa.aggregation;
|
||||||
|
|
||||||
import com.baeldung.aggregation.model.custom.CommentCount;
|
|
||||||
import com.baeldung.aggregation.model.custom.ICommentCount;
|
|
||||||
import com.baeldung.aggregation.repository.CommentRepository;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
|
||||||
import org.springframework.test.context.jdbc.Sql;
|
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigurationPackage;
|
||||||
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.jdbc.Sql;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
import com.baeldung.jpa.aggregation.model.custom.CommentCount;
|
||||||
|
import com.baeldung.jpa.aggregation.model.custom.ICommentCount;
|
||||||
|
import com.baeldung.jpa.aggregation.repository.CommentRepository;
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@DataJpaTest(showSql = false)
|
@DataJpaTest(showSql = false)
|
||||||
@Sql(scripts = "/test-aggregation-data.sql")
|
@Sql(scripts = "/test-aggregation-data.sql")
|
||||||
|
@AutoConfigurationPackage(basePackages = "com.baeldung.jpa.aggregation")
|
||||||
|
@ContextConfiguration(classes = AggregationApplication.class)
|
||||||
public class SpringDataAggregateIntegrationTest {
|
public class SpringDataAggregateIntegrationTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
@ -0,0 +1,212 @@
|
|||||||
|
package com.baeldung.jpa.modifying;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
|
import org.springframework.data.mapping.PropertyReferenceException;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import com.baeldung.jpa.modifying.dao.UserRepository;
|
||||||
|
import com.baeldung.jpa.modifying.model.User;
|
||||||
|
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
import jakarta.persistence.Query;
|
||||||
|
|
||||||
|
@SpringBootTest(classes= ModifyingApplication.class)
|
||||||
|
class UserRepositoryCommonIntegrationTest {
|
||||||
|
|
||||||
|
final String USER_EMAIL = "email@example.com";
|
||||||
|
final String USER_EMAIL2 = "email2@example.com";
|
||||||
|
final String USER_EMAIL3 = "email3@example.com";
|
||||||
|
final String USER_EMAIL4 = "email4@example.com";
|
||||||
|
final Integer INACTIVE_STATUS = 0;
|
||||||
|
final Integer ACTIVE_STATUS = 1;
|
||||||
|
final String USER_NAME_ADAM = "Adam";
|
||||||
|
final String USER_NAME_PETER = "Peter";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected UserRepository userRepository;
|
||||||
|
@Autowired
|
||||||
|
private EntityManager entityManager;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Transactional
|
||||||
|
void givenUsersWithSameNameInDB_WhenFindAllByName_ThenReturnStreamOfUsers() {
|
||||||
|
User user1 = new User();
|
||||||
|
user1.setName(USER_NAME_ADAM);
|
||||||
|
user1.setEmail(USER_EMAIL);
|
||||||
|
userRepository.save(user1);
|
||||||
|
|
||||||
|
User user2 = new User();
|
||||||
|
user2.setName(USER_NAME_ADAM);
|
||||||
|
user2.setEmail(USER_EMAIL2);
|
||||||
|
userRepository.save(user2);
|
||||||
|
|
||||||
|
User user3 = new User();
|
||||||
|
user3.setName(USER_NAME_ADAM);
|
||||||
|
user3.setEmail(USER_EMAIL3);
|
||||||
|
userRepository.save(user3);
|
||||||
|
|
||||||
|
User user4 = new User();
|
||||||
|
user4.setName("SAMPLE");
|
||||||
|
user4.setEmail(USER_EMAIL4);
|
||||||
|
userRepository.save(user4);
|
||||||
|
|
||||||
|
try (Stream<User> foundUsersStream = userRepository.findAllByName(USER_NAME_ADAM)) {
|
||||||
|
assertThat(foundUsersStream.count()).isEqualTo(3l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenUsersInDB_WhenFindAllWithSortByName_ThenReturnUsersSorted() {
|
||||||
|
userRepository.save(new User(USER_NAME_ADAM, LocalDate.now(), USER_EMAIL, ACTIVE_STATUS));
|
||||||
|
userRepository.save(new User(USER_NAME_PETER, LocalDate.now(), USER_EMAIL2, ACTIVE_STATUS));
|
||||||
|
userRepository.save(new User("SAMPLE", LocalDate.now(), USER_EMAIL3, INACTIVE_STATUS));
|
||||||
|
|
||||||
|
List<User> usersSortByName = userRepository.findAll(Sort.by(Sort.Direction.ASC, "name"));
|
||||||
|
|
||||||
|
assertThat(usersSortByName.get(0)
|
||||||
|
.getName()).isEqualTo(USER_NAME_ADAM);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenUsersInDB_WhenFindAllSortWithFunction_ThenThrowException() {
|
||||||
|
userRepository.save(new User(USER_NAME_ADAM, LocalDate.now(), USER_EMAIL, ACTIVE_STATUS));
|
||||||
|
userRepository.save(new User(USER_NAME_PETER, LocalDate.now(), USER_EMAIL2, ACTIVE_STATUS));
|
||||||
|
userRepository.save(new User("SAMPLE", LocalDate.now(), USER_EMAIL3, INACTIVE_STATUS));
|
||||||
|
|
||||||
|
userRepository.findAll(Sort.by(Sort.Direction.ASC, "name"));
|
||||||
|
|
||||||
|
assertThrows(PropertyReferenceException.class, () -> userRepository.findAll(Sort.by("LENGTH(name)")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Transactional
|
||||||
|
void givenTwoUsers_whenFindByNameUsr01_ThenUserUsr01() {
|
||||||
|
User usr01 = new User("usr01", LocalDate.now(), "usr01@baeldung.com", 1);
|
||||||
|
User usr02 = new User("usr02", LocalDate.now(), "usr02@baeldung.com", 1);
|
||||||
|
|
||||||
|
userRepository.save(usr01);
|
||||||
|
userRepository.save(usr02);
|
||||||
|
|
||||||
|
try (Stream<User> users = userRepository.findAllByName("usr01")) {
|
||||||
|
assertTrue(users.allMatch(usr -> usr.equals(usr01)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Transactional
|
||||||
|
void givenTwoUsers_whenFindByNameUsr00_ThenNoUsers() {
|
||||||
|
User usr01 = new User("usr01", LocalDate.now(), "usr01@baeldung.com", 1);
|
||||||
|
User usr02 = new User("usr02", LocalDate.now(), "usr02@baeldung.com", 1);
|
||||||
|
|
||||||
|
userRepository.save(usr01);
|
||||||
|
userRepository.save(usr02);
|
||||||
|
|
||||||
|
try (Stream<User> users = userRepository.findAllByName("usr00")) {
|
||||||
|
assertEquals(0, users.count());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenTwoUsers_whenFindUsersWithGmailAddress_ThenUserUsr02() {
|
||||||
|
User usr01 = new User("usr01", LocalDate.now(), "usr01@baeldung.com", 1);
|
||||||
|
User usr02 = new User("usr02", LocalDate.now(), "usr02@gmail.com", 1);
|
||||||
|
|
||||||
|
userRepository.save(usr01);
|
||||||
|
userRepository.save(usr02);
|
||||||
|
|
||||||
|
List<User> users = userRepository.findUsersWithGmailAddress();
|
||||||
|
assertEquals(1, users.size());
|
||||||
|
assertEquals(usr02, users.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Transactional
|
||||||
|
void givenTwoUsers_whenDeleteAllByCreationDateAfter_ThenOneUserRemains() {
|
||||||
|
User usr01 = new User("usr01", LocalDate.of(2018, 1, 1), "usr01@baeldung.com", 1);
|
||||||
|
User usr02 = new User("usr02", LocalDate.of(2018, 6, 1), "usr02@baeldung.com", 1);
|
||||||
|
|
||||||
|
userRepository.save(usr01);
|
||||||
|
userRepository.save(usr02);
|
||||||
|
|
||||||
|
userRepository.deleteAllByCreationDateAfter(LocalDate.of(2018, 5, 1));
|
||||||
|
|
||||||
|
List<User> users = userRepository.findAll();
|
||||||
|
|
||||||
|
assertEquals(1, users.size());
|
||||||
|
assertEquals(usr01, users.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Transactional
|
||||||
|
void givenTwoUsers_whenDeleteDeactivatedUsers_ThenUserUsr02Deleted() {
|
||||||
|
User usr01 = new User("usr01", LocalDate.of(2018, 1, 1), "usr01@baeldung.com", 1);
|
||||||
|
usr01.setLastLoginDate(LocalDate.now());
|
||||||
|
User usr02 = new User("usr02", LocalDate.of(2018, 6, 1), "usr02@baeldung.com", 0);
|
||||||
|
usr02.setLastLoginDate(LocalDate.of(2018, 7, 20));
|
||||||
|
usr02.setActive(false);
|
||||||
|
|
||||||
|
userRepository.save(usr01);
|
||||||
|
userRepository.save(usr02);
|
||||||
|
|
||||||
|
int deletedUsersCount = userRepository.deleteDeactivatedUsers();
|
||||||
|
|
||||||
|
List<User> users = userRepository.findAll();
|
||||||
|
assertEquals(1, users.size());
|
||||||
|
assertEquals(usr01, users.get(0));
|
||||||
|
assertEquals(1, deletedUsersCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Transactional
|
||||||
|
void givenTwoUsers_whenDeleteDeactivatedUsersWithNoModifyingAnnotation_ThenException() {
|
||||||
|
User usr01 = new User("usr01", LocalDate.of(2018, 1, 1), "usr01@baeldung.com", 1);
|
||||||
|
usr01.setLastLoginDate(LocalDate.now());
|
||||||
|
User usr02 = new User("usr02", LocalDate.of(2018, 6, 1), "usr02@baeldung.com", 0);
|
||||||
|
usr02.setLastLoginDate(LocalDate.of(2018, 7, 20));
|
||||||
|
usr02.setActive(false);
|
||||||
|
|
||||||
|
userRepository.save(usr01);
|
||||||
|
userRepository.save(usr02);
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> userRepository.deleteDeactivatedUsersWithNoModifyingAnnotation())
|
||||||
|
.isInstanceOf(InvalidDataAccessApiUsageException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Transactional
|
||||||
|
void givenTwoUsers_whenAddDeletedColumn_ThenUsersHaveDeletedColumn() {
|
||||||
|
User usr01 = new User("usr01", LocalDate.of(2018, 1, 1), "usr01@baeldung.com", 1);
|
||||||
|
usr01.setLastLoginDate(LocalDate.now());
|
||||||
|
User usr02 = new User("usr02", LocalDate.of(2018, 6, 1), "usr02@baeldung.org", 1);
|
||||||
|
usr02.setLastLoginDate(LocalDate.of(2018, 7, 20));
|
||||||
|
usr02.setActive(false);
|
||||||
|
|
||||||
|
userRepository.save(usr01);
|
||||||
|
userRepository.save(usr02);
|
||||||
|
|
||||||
|
userRepository.addDeletedColumn();
|
||||||
|
|
||||||
|
Query nativeQuery = entityManager.createNativeQuery("select deleted from USERS where NAME = 'usr01'");
|
||||||
|
assertEquals(0, nativeQuery.getResultList().get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void cleanUp() {
|
||||||
|
userRepository.deleteAll();
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.baeldung.multipledb;
|
package com.baeldung.jpa.paginationsorting;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.hasSize;
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
@ -9,33 +9,30 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
|
||||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import com.baeldung.multipledb.dao.product.ProductRepository;
|
import com.baeldung.jpa.paginationsorting.model.Product;
|
||||||
import com.baeldung.multipledb.model.product.Product;
|
import com.baeldung.jpa.paginationsorting.repository.ProductRepository;
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
@SpringBootTest(classes = PaginationSortingApplication.class)
|
||||||
@SpringBootTest(classes=MultipleDbApplication.class)
|
|
||||||
@EnableTransactionManagement
|
@EnableTransactionManagement
|
||||||
public class ProductRepositoryIntegrationTest {
|
class ProductRepositoryIntegrationTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ProductRepository productRepository;
|
private ProductRepository productRepository;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
@Transactional("productTransactionManager")
|
@Transactional("productTransactionManager")
|
||||||
public void setUp() {
|
void setUp() {
|
||||||
productRepository.save(Product.from(1001, "Book", 21));
|
productRepository.save(Product.from(1001, "Book", 21));
|
||||||
productRepository.save(Product.from(1002, "Coffee", 10));
|
productRepository.save(Product.from(1002, "Coffee", 10));
|
||||||
productRepository.save(Product.from(1003, "Jeans", 30));
|
productRepository.save(Product.from(1003, "Jeans", 30));
|
||||||
@ -44,7 +41,7 @@ public class ProductRepositoryIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenRequestingFirstPageOfSizeTwo_ThenReturnFirstPage() {
|
void whenRequestingFirstPageOfSizeTwo_ThenReturnFirstPage() {
|
||||||
Pageable pageRequest = PageRequest.of(0, 2);
|
Pageable pageRequest = PageRequest.of(0, 2);
|
||||||
|
|
||||||
Page<Product> result = productRepository.findAll(pageRequest);
|
Page<Product> result = productRepository.findAll(pageRequest);
|
||||||
@ -57,7 +54,7 @@ public class ProductRepositoryIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenRequestingSecondPageOfSizeTwo_ThenReturnSecondPage() {
|
void whenRequestingSecondPageOfSizeTwo_ThenReturnSecondPage() {
|
||||||
Pageable pageRequest = PageRequest.of(1, 2);
|
Pageable pageRequest = PageRequest.of(1, 2);
|
||||||
|
|
||||||
Page<Product> result = productRepository.findAll(pageRequest);
|
Page<Product> result = productRepository.findAll(pageRequest);
|
||||||
@ -70,7 +67,7 @@ public class ProductRepositoryIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenRequestingLastPage_ThenReturnLastPageWithRemData() {
|
void whenRequestingLastPage_ThenReturnLastPageWithRemData() {
|
||||||
Pageable pageRequest = PageRequest.of(2, 2);
|
Pageable pageRequest = PageRequest.of(2, 2);
|
||||||
|
|
||||||
Page<Product> result = productRepository.findAll(pageRequest);
|
Page<Product> result = productRepository.findAll(pageRequest);
|
||||||
@ -83,7 +80,7 @@ public class ProductRepositoryIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenSortingByNameAscAndPaging_ThenReturnSortedPagedResult() {
|
void whenSortingByNameAscAndPaging_ThenReturnSortedPagedResult() {
|
||||||
Pageable pageRequest = PageRequest.of(0, 3, Sort.by("name"));
|
Pageable pageRequest = PageRequest.of(0, 3, Sort.by("name"));
|
||||||
|
|
||||||
Page<Product> result = productRepository.findAll(pageRequest);
|
Page<Product> result = productRepository.findAll(pageRequest);
|
||||||
@ -97,7 +94,7 @@ public class ProductRepositoryIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenSortingByPriceDescAndPaging_ThenReturnSortedPagedResult() {
|
void whenSortingByPriceDescAndPaging_ThenReturnSortedPagedResult() {
|
||||||
Pageable pageRequest = PageRequest.of(0, 3, Sort.by("price")
|
Pageable pageRequest = PageRequest.of(0, 3, Sort.by("price")
|
||||||
.descending());
|
.descending());
|
||||||
|
|
||||||
@ -112,7 +109,7 @@ public class ProductRepositoryIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenSortingByPriceDescAndNameAscAndPaging_ThenReturnSortedPagedResult() {
|
void whenSortingByPriceDescAndNameAscAndPaging_ThenReturnSortedPagedResult() {
|
||||||
Pageable pageRequest = PageRequest.of(0, 5, Sort.by("price")
|
Pageable pageRequest = PageRequest.of(0, 5, Sort.by("price")
|
||||||
.descending()
|
.descending()
|
||||||
.and(Sort.by("name")));
|
.and(Sort.by("name")));
|
||||||
@ -128,7 +125,7 @@ public class ProductRepositoryIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenRequestingFirstPageOfSizeTwoUsingCustomMethod_ThenReturnFirstPage() {
|
void whenRequestingFirstPageOfSizeTwoUsingCustomMethod_ThenReturnFirstPage() {
|
||||||
Pageable pageRequest = PageRequest.of(0, 2);
|
Pageable pageRequest = PageRequest.of(0, 2);
|
||||||
|
|
||||||
List<Product> result = productRepository.findAllByPrice(10, pageRequest);
|
List<Product> result = productRepository.findAllByPrice(10, pageRequest);
|
@ -1,23 +1,26 @@
|
|||||||
package com.baeldung.projection;
|
package com.baeldung.jpa.projection;
|
||||||
|
|
||||||
import com.baeldung.projection.model.Person;
|
|
||||||
import com.baeldung.projection.repository.AddressRepository;
|
|
||||||
import com.baeldung.projection.repository.PersonRepository;
|
|
||||||
import com.baeldung.projection.view.AddressView;
|
|
||||||
import com.baeldung.projection.view.PersonDto;
|
|
||||||
import com.baeldung.projection.view.PersonView;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
|
||||||
import org.springframework.test.context.jdbc.Sql;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.AFTER_TEST_METHOD;
|
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.AFTER_TEST_METHOD;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigurationPackage;
|
||||||
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
|
import org.springframework.test.context.jdbc.Sql;
|
||||||
|
|
||||||
|
import com.baeldung.jpa.projection.model.Person;
|
||||||
|
import com.baeldung.jpa.projection.repository.AddressRepository;
|
||||||
|
import com.baeldung.jpa.projection.repository.PersonRepository;
|
||||||
|
import com.baeldung.jpa.projection.view.AddressView;
|
||||||
|
import com.baeldung.jpa.projection.view.PersonDto;
|
||||||
|
import com.baeldung.jpa.projection.view.PersonView;
|
||||||
|
|
||||||
@DataJpaTest
|
@DataJpaTest
|
||||||
@Sql(scripts = "/projection-insert-data.sql")
|
@Sql(scripts = "/projection-insert-data.sql")
|
||||||
@Sql(scripts = "/projection-clean-up-data.sql", executionPhase = AFTER_TEST_METHOD)
|
@Sql(scripts = "/projection-clean-up-data.sql", executionPhase = AFTER_TEST_METHOD)
|
||||||
public class JpaProjectionIntegrationTest {
|
@AutoConfigurationPackage(basePackages = "com.baeldung.jpa.projection")
|
||||||
|
class JpaProjectionIntegrationTest {
|
||||||
@Autowired
|
@Autowired
|
||||||
private AddressRepository addressRepository;
|
private AddressRepository addressRepository;
|
||||||
|
|
||||||
@ -25,7 +28,7 @@ public class JpaProjectionIntegrationTest {
|
|||||||
private PersonRepository personRepository;
|
private PersonRepository personRepository;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenUsingClosedProjections_thenViewWithRequiredPropertiesIsReturned() {
|
void whenUsingClosedProjections_thenViewWithRequiredPropertiesIsReturned() {
|
||||||
AddressView addressView = addressRepository.getAddressByState("CA").get(0);
|
AddressView addressView = addressRepository.getAddressByState("CA").get(0);
|
||||||
assertThat(addressView.getZipCode()).isEqualTo("90001");
|
assertThat(addressView.getZipCode()).isEqualTo("90001");
|
||||||
|
|
||||||
@ -35,20 +38,20 @@ public class JpaProjectionIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenUsingOpenProjections_thenViewWithRequiredPropertiesIsReturned() {
|
void whenUsingOpenProjections_thenViewWithRequiredPropertiesIsReturned() {
|
||||||
PersonView personView = personRepository.findByLastName("Doe");
|
PersonView personView = personRepository.findByLastName("Doe");
|
||||||
assertThat(personView.getFullName()).isEqualTo("John Doe");
|
assertThat(personView.getFullName()).isEqualTo("John Doe");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenUsingClassBasedProjections_thenDtoWithRequiredPropertiesIsReturned() {
|
void whenUsingClassBasedProjections_thenDtoWithRequiredPropertiesIsReturned() {
|
||||||
PersonDto personDto = personRepository.findByFirstName("John");
|
PersonDto personDto = personRepository.findByFirstName("John");
|
||||||
assertThat(personDto.getFirstName()).isEqualTo("John");
|
assertThat(personDto.getFirstName()).isEqualTo("John");
|
||||||
assertThat(personDto.getLastName()).isEqualTo("Doe");
|
assertThat(personDto.getLastName()).isEqualTo("Doe");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenUsingDynamicProjections_thenObjectWithRequiredPropertiesIsReturned() {
|
void whenUsingDynamicProjections_thenObjectWithRequiredPropertiesIsReturned() {
|
||||||
Person person = personRepository.findByLastName("Doe", Person.class);
|
Person person = personRepository.findByLastName("Doe", Person.class);
|
||||||
PersonView personView = personRepository.findByLastName("Doe", PersonView.class);
|
PersonView personView = personRepository.findByLastName("Doe", PersonView.class);
|
||||||
PersonDto personDto = personRepository.findByLastName("Doe", PersonDto.class);
|
PersonDto personDto = personRepository.findByLastName("Doe", PersonDto.class);
|
@ -1,26 +1,25 @@
|
|||||||
package com.baeldung.spring.data.jpa.query;
|
package com.baeldung.jpa.query;
|
||||||
|
|
||||||
import org.junit.Test;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import org.junit.runner.RunWith;
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigurationPackage;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.data.jpa.domain.JpaSort;
|
import org.springframework.data.jpa.domain.JpaSort;
|
||||||
import org.springframework.data.mapping.PropertyReferenceException;
|
import org.springframework.data.mapping.PropertyReferenceException;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
|
||||||
@DataJpaTest(properties = "spring.sql.init.data-locations=classpath:insert_users.sql", showSql = false)
|
@DataJpaTest(properties = "spring.sql.init.data-locations=classpath:insert_users.sql", showSql = false)
|
||||||
public class UserRepositoryIntegrationTest {
|
@AutoConfigurationPackage(basePackages = "com.baeldung.jpa.query")
|
||||||
|
class UserQueryRepositoryIntegrationTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserRepository userRepository;
|
private UserRepository userRepository;
|
||||||
@ -40,47 +39,43 @@ public class UserRepositoryIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
public void whenFindAllSortedByNameThenAllSorted() {
|
public void whenFindAllSortedByNameThenAllSorted() {
|
||||||
List<User> allUsersSortedByName = userRepository.findAll(Sort.by(Sort.Direction.ASC, "name"));
|
List<User> allUsersSortedByName = userRepository.findAll(Sort.by(Sort.Direction.ASC, "name"));
|
||||||
assertThat(allUsersSortedByName)
|
assertThat(allUsersSortedByName).extracting("name")
|
||||||
.extracting("name")
|
.containsSequence("Bob", "Cindy", "John");
|
||||||
.containsSequence("Bob", "Cindy", "John");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenFindAllSortedByNameLengthThenException() {
|
public void whenFindAllSortedByNameLengthThenException() {
|
||||||
assertThatThrownBy(() -> userRepository.findAll(Sort.by("LENGTH(name)")))
|
assertThatThrownBy(() -> userRepository.findAll(Sort.by("LENGTH(name)"))).isInstanceOf(PropertyReferenceException.class);
|
||||||
.isInstanceOf(PropertyReferenceException.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenFindAllUsersSortedByNameThenAllSorted() {
|
public void whenFindAllUsersSortedByNameThenAllSorted() {
|
||||||
List<User> allUsersSortedByName = userRepository.findAllUsers(Sort.by(Sort.Direction.ASC, "name"));
|
List<User> allUsersSortedByName = userRepository.findAllUsers(Sort.by(Sort.Direction.ASC, "name"));
|
||||||
assertThat(allUsersSortedByName)
|
assertThat(allUsersSortedByName).extracting("name")
|
||||||
.extracting("name")
|
.containsSequence("Bob", "Cindy", "John");
|
||||||
.containsSequence("Bob", "Cindy", "John");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenFindAllUsersSortedByNameLengthThenAllSorted() {
|
public void whenFindAllUsersSortedByNameLengthThenAllSorted() {
|
||||||
List<User> allUsersSortedByName = userRepository.findAllUsers(JpaSort.unsafe("LENGTH(name)"));
|
List<User> allUsersSortedByName = userRepository.findAllUsers(JpaSort.unsafe("LENGTH(name)"));
|
||||||
assertThat(allUsersSortedByName)
|
assertThat(allUsersSortedByName).extracting("name")
|
||||||
.extracting("name")
|
.containsSequence("Bob", "John", "Cindy");
|
||||||
.containsSequence("Bob", "John", "Cindy");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenFindAllUsersWithPaginationThenPaginated() {
|
public void whenFindAllUsersWithPaginationThenPaginated() {
|
||||||
Page<User> page = userRepository.findAllUsersWithPagination(PageRequest.of(0, 1));
|
Page<User> page = userRepository.findAllUsersWithPagination(PageRequest.of(0, 1));
|
||||||
assertThat(page.stream().map(User::getId))
|
assertThat(page.stream()
|
||||||
.hasSize(1)
|
.map(User::getId)).hasSize(1)
|
||||||
.containsOnly(1);
|
.containsOnly(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenFindAllUsersWithPaginationNativeThenPaginated() {
|
public void whenFindAllUsersWithPaginationNativeThenPaginated() {
|
||||||
Page<User> page = userRepository.findAllUsersWithPaginationNative(PageRequest.of(1, 1));
|
Page<User> page = userRepository.findAllUsersWithPaginationNative(PageRequest.of(1, 1));
|
||||||
assertThat(page.stream().map(User::getId))
|
assertThat(page.stream()
|
||||||
.hasSize(1)
|
.map(User::getId)).hasSize(1)
|
||||||
.containsOnly(2);
|
.containsOnly(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -126,9 +121,8 @@ public class UserRepositoryIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
public void whenFindUserByNameListThenAllFound() {
|
public void whenFindUserByNameListThenAllFound() {
|
||||||
List<User> users = userRepository.findUserByNameList(Arrays.asList("Bob", "Cindy"));
|
List<User> users = userRepository.findUserByNameList(Arrays.asList("Bob", "Cindy"));
|
||||||
assertThat(users)
|
assertThat(users).extracting("name")
|
||||||
.extracting("name")
|
.containsOnly("Bob", "Cindy");
|
||||||
.containsOnly("Bob", "Cindy");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
@ -1,22 +1,24 @@
|
|||||||
package com.baeldung.spring.data.jpa.listrepositories.repository;
|
package com.baeldung.jpa.simple;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.baeldung.spring.data.jpa.listrepositories.entity.Book;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import com.baeldung.jpa.simple.entity.Book;
|
||||||
import java.util.List;
|
import com.baeldung.jpa.simple.repository.BookListRepository;
|
||||||
|
|
||||||
@SpringBootTest
|
@SpringBootTest(classes = JpaApplication.class)
|
||||||
public class BookListRepositoryIntegrationTest {
|
class BookListRepositoryIntegrationTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private BookListRepository bookListRepository;
|
private BookListRepository bookListRepository;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenDbContainsBooks_whenFindBooksByAuthor_thenReturnBooksByAuthor() {
|
void givenDbContainsBooks_whenFindBooksByAuthor_thenReturnBooksByAuthor() {
|
||||||
Book book1 = new Book("Spring Data", "John Doe", "1234567890");
|
Book book1 = new Book("Spring Data", "John Doe", "1234567890");
|
||||||
Book book2 = new Book("Spring Data 2", "John Doe", "1234567891");
|
Book book2 = new Book("Spring Data 2", "John Doe", "1234567891");
|
||||||
Book book3 = new Book("Spring Data 3", "John Doe", "1234567892");
|
Book book3 = new Book("Spring Data 3", "John Doe", "1234567892");
|
@ -1,7 +1,8 @@
|
|||||||
package com.baeldung.spring.data.jpa.listrepositories.repository;
|
package com.baeldung.jpa.simple;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.baeldung.spring.data.jpa.listrepositories.entity.Book;
|
|
||||||
import com.baeldung.spring.data.jpa.listrepositories.repository.BookPagingAndSortingRepository;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -10,17 +11,17 @@ import org.springframework.data.domain.PageRequest;
|
|||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import com.baeldung.jpa.simple.entity.Book;
|
||||||
import java.util.List;
|
import com.baeldung.jpa.simple.repository.BookPagingAndSortingRepository;
|
||||||
|
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
public class BookPagingAndSortingRepositoryIntegrationTest {
|
class BookPagingAndSortingRepositoryIntegrationTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private BookPagingAndSortingRepository bookPagingAndSortingRepository;
|
private BookPagingAndSortingRepository bookPagingAndSortingRepository;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenDbContainsBooks_whenfindBooksByAuthor_thenReturnBooksByAuthor() {
|
void givenDbContainsBooks_whenfindBooksByAuthor_thenReturnBooksByAuthor() {
|
||||||
Book book1 = new Book("Spring Data", "John Miller", "1234567890");
|
Book book1 = new Book("Spring Data", "John Miller", "1234567890");
|
||||||
Book book2 = new Book("Spring Data 2", "John Miller", "1234567891");
|
Book book2 = new Book("Spring Data 2", "John Miller", "1234567891");
|
||||||
Book book3 = new Book("Spring Data 3", "John Miller", "1234567892");
|
Book book3 = new Book("Spring Data 3", "John Miller", "1234567892");
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.baeldung.jpa.simple;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.dao.DataIntegrityViolationException;
|
||||||
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
import com.baeldung.jpa.simple.entity.Foo;
|
||||||
|
import com.baeldung.jpa.simple.service.IFooService;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@ContextConfiguration(classes = { JpaApplication.class})
|
||||||
|
@DirtiesContext
|
||||||
|
public class FooServiceIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IFooService service;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
@Test(expected = DataIntegrityViolationException.class)
|
||||||
|
public final void whenInvalidEntityIsCreated_thenDataException() {
|
||||||
|
service.create(new Foo());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,191 @@
|
|||||||
|
package com.baeldung.jpa.simple;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
|
|
||||||
|
import com.baeldung.jpa.simple.entity.User;
|
||||||
|
import com.baeldung.jpa.simple.repository.UserRepository;
|
||||||
|
|
||||||
|
@ExtendWith(SpringExtension.class)
|
||||||
|
@SpringBootTest(classes = JpaApplication.class)
|
||||||
|
class UserRepositoryIntegrationTest {
|
||||||
|
|
||||||
|
private static final String USER_NAME_ADAM = "Adam";
|
||||||
|
private static final String USER_NAME_EVE = "Eve";
|
||||||
|
private static final ZonedDateTime BIRTHDATE = ZonedDateTime.now();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserRepository userRepository;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setUp() {
|
||||||
|
|
||||||
|
User user1 = new User(USER_NAME_ADAM, 25, BIRTHDATE, true);
|
||||||
|
User user2 = new User(USER_NAME_ADAM, 20, BIRTHDATE, false);
|
||||||
|
User user3 = new User(USER_NAME_EVE, 20, BIRTHDATE, true);
|
||||||
|
User user4 = new User(null, 30, BIRTHDATE, false);
|
||||||
|
|
||||||
|
userRepository.saveAll(Arrays.asList(user1, user2, user3, user4));
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void tearDown() {
|
||||||
|
|
||||||
|
userRepository.deleteAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenFindByName_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(2, userRepository.findByName(USER_NAME_ADAM)
|
||||||
|
.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenFindByNameIsNull_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(1, userRepository.findByNameIsNull()
|
||||||
|
.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenFindByNameNot_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(USER_NAME_EVE, userRepository.findByNameNot(USER_NAME_ADAM)
|
||||||
|
.get(0)
|
||||||
|
.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenFindByNameStartingWith_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(2, userRepository.findByNameStartingWith("A")
|
||||||
|
.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenFindByNameEndingWith_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(1, userRepository.findByNameEndingWith("e")
|
||||||
|
.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenByNameContaining_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(1, userRepository.findByNameContaining("v")
|
||||||
|
.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenByNameLike_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(2, userRepository.findByNameEndingWith("m")
|
||||||
|
.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenByAgeLessThan_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(2, userRepository.findByAgeLessThan(25)
|
||||||
|
.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenByAgeLessThanEqual_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(3, userRepository.findByAgeLessThanEqual(25)
|
||||||
|
.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenByAgeGreaterThan_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(1, userRepository.findByAgeGreaterThan(25)
|
||||||
|
.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenByAgeGreaterThanEqual_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(2, userRepository.findByAgeGreaterThanEqual(25)
|
||||||
|
.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenByAgeBetween_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(4, userRepository.findByAgeBetween(20, 30)
|
||||||
|
.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenByBirthDateAfter_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
final ZonedDateTime yesterday = BIRTHDATE.minusDays(1);
|
||||||
|
assertEquals(4, userRepository.findByBirthDateAfter(yesterday)
|
||||||
|
.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenByBirthDateBefore_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
final ZonedDateTime yesterday = BIRTHDATE.minusDays(1);
|
||||||
|
assertEquals(0, userRepository.findByBirthDateBefore(yesterday)
|
||||||
|
.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenByActiveTrue_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(2, userRepository.findByActiveTrue()
|
||||||
|
.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenByActiveFalse_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(2, userRepository.findByActiveFalse()
|
||||||
|
.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenByAgeIn_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
final List<Integer> ages = Arrays.asList(20, 25);
|
||||||
|
assertEquals(3, userRepository.findByAgeIn(ages)
|
||||||
|
.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenByNameOrAge() {
|
||||||
|
|
||||||
|
assertEquals(3, userRepository.findByNameOrAge(USER_NAME_ADAM, 20)
|
||||||
|
.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenByNameOrAgeAndActive() {
|
||||||
|
|
||||||
|
assertEquals(2, userRepository.findByNameOrAgeAndActive(USER_NAME_ADAM, 20, false)
|
||||||
|
.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenByNameOrderByName() {
|
||||||
|
|
||||||
|
assertEquals(2, userRepository.findByNameOrderByName(USER_NAME_ADAM)
|
||||||
|
.size());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration scan="true" scanPeriod="15 seconds" debug="false">
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>[%d{ISO8601}]-[%thread] %-5level %logger - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
Loading…
x
Reference in New Issue
Block a user