A simple Spring Boot, Spring Data JPA, Spring GraphQL application to demonstrate the Classic N+1 Database query problem along with solution using both JPA JPQL @Query, and JPA @EntityGraph.
Make sure that you have JDK 21 installed and the current version is set to 21 in your path and IDE. SDKMAN is a very nice tool to manage multiple version of SDKs including Java, Spring Boot, Maven and many others.
NOTE
You need to have thedocker
anddocker compose
(ordocker-compose
) CLI applications on your path. The minimum supported Docker Compose version is2.2.0
.
You can build and run the application using the following commands from the application root directory:
# clean, and run the app
./mvnw clean spring-boot:run
The application's database is seeded with some test data: a couple of Countries, each Country with a couple of States and each State with a couple of Cities.
Once the application comes up, open the browser and hit http://localhost:8080/graphiql?path=/graphql for GraphiQL gui console and run GraphQL queries. The following are some sample queries:
# Query all data for all countries: N +1 queries
query AllCountries {
allCountries {
name
states {
name
cities {
name
}
}
}
}
# Query all data for all countries: JPQL- Single query
query AllCountriesSingleQuery {
allCountriesSingleQuery {
name
}
}
# Query all data for a country by name: EntityGrapg single query
query CountryByNameEntityGraph {
countryByNameSingleQuery(name: "India") {
name
states {
name
cities {
name
}
}
}
}
NOTE
You can check your application logs for the generated SQL.
For further reference, please consider the following sections:
- Official Apache Maven documentation
- Spring Boot Maven Plugin Reference Guide
- Create an OCI image
- Spring Boot Testcontainers support
- Testcontainers Postgres Module Reference Guide
- Spring for GraphQL
- Spring Data JPA
- Docker Compose Support
- Testcontainers
- Flyway Migration
- Spring Web
- Spring Boot Actuator
The following guides illustrate how to use some features concretely:
This project contains a Docker Compose file named compose.yaml
.
In this file, the following services have been defined:
- postgres:
postgres:latest
Please review the tags of the used images and set them to the same as you're running in production.
This project uses Testcontainers at development time.
Testcontainers has been configured to use the following Docker images:
Please review the tags of the used images and set them to the same as you're running in production.