Hibernate JPQL SELECT tutorial
last modified July 16, 2020
Hibernate JPQL SELECT tutorial shows how to execute JPQL SELECT statements in Hibernate. We use MySQL database.
Hibernate
Hibernate is an object-relational mapping tool for the Java programming language. It provides a framework for mapping an object-oriented domain model to a relational database.
JPQL
Java Persistence Query Language (JPQL) is a platform-independent object-oriented query language defined as part of the Java Persistence API (JPA) specification. JPQL is used to make queries against entities stored in a relational database. JPQL is inspired by SQL.
JPQL is object-oriented. In JPQL we work with entities and collection of entities, while in SQL we work with columns and rows.
JPQL SELECT statement has the following syntax:
SELECT {select clause} FROM {from clause} [WHERE {where clause}] [ORDER BY {order by clause}] [GROUP BY {group by clause}] [HAVING {having clause}]
The WHERE
, ORDER BY
, GROUP BY
, and
HAVING
clauses are optional.
Hibernate JPQL SELECT example
The following application executes a couple of JPQL SELECT statements.
DROP TABLE IF EXISTS cities; CREATE TABLE cities(id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100), population INT); INSERT INTO cities(name, population) VALUES('Bratislava', 432000); INSERT INTO cities(name, population) VALUES('Budapest', 1759000); INSERT INTO cities(name, population) VALUES('Prague', 1280000); INSERT INTO cities(name, population) VALUES('Warsaw', 1748000); INSERT INTO cities(name, population) VALUES('Los Angeles', 3971000); INSERT INTO cities(name, population) VALUES('New York', 8550000); INSERT INTO cities(name, population) VALUES('Edinburgh', 464000); INSERT INTO cities(name, population) VALUES('Berlin', 3671000);
This is SQL to create a cities
table in MySQL.
$ tree . ├── nbactions.xml ├── pom.xml └── src ├── main │ ├── java │ │ └── com │ │ └── zetcode │ │ ├── HibernateJpqlSelect.java │ │ └── model │ │ └── City.java │ └── resources │ ├── log4j2.xml │ └── META-INF │ └── persistence.xml └── test └── java
This is the project structure.
<?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> <groupId>com.zetcode</groupId> <artifactId>HibernateJpqlSelect</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.45</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.2.8.Final</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.10.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.5.0</version> <configuration> <mainClass>com.zetcode.HibernateJpqlSelect</mainClass> </configuration> </plugin> </plugins> </build> </project>
This is the Maven build file. The mysql-connector-java
is a MySQL driver,
the hibernate-core
brings the core Hibernate functionality, and
the log4j-slf4j-impl
is a simple logging facade to the Log4j2 library.
<?xml version="1.0" encoding="UTF-8"?> <Configuration> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d [%t] %-5level %logger - %m%n" /> </Console> </Appenders> <Loggers> <!-- Log everything in Hibernate --> <Logger name="org.hibernate" level="error" additivity="false"> <AppenderRef ref="Console" /> </Logger> <!-- Log SQL statements --> <Logger name="org.hibernate.SQL" level="error" additivity="false"> <AppenderRef ref="Console" /> </Logger> <!-- Log custom packages --> <Logger name="com.zetcode" level="error" additivity="false"> <AppenderRef ref="Console" /> </Logger> <Root level="error"> <AppenderRef ref="Console" /> </Root> </Loggers> </Configuration>
The log4j2.xml
file is a configuration file for Log4j2.
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> <persistence-unit name="my-pu" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <properties> <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/testdb?useSSL=false"/> <property name="javax.persistence.jdbc.user" value="testuser"/> <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> <property name="javax.persistence.jdbc.password" value="test623"/> <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/> </properties> </persistence-unit> </persistence>
The persistence.xml
file is a standard configuration file in JPA.
It has to be included in the META-INF
directory inside the JAR file
that contains the entity beans. The persistence.xml
file must
define a persistence-unit with a unique name in the current scoped classloader.
The provider attribute specifies the underlying implementation of the JPA
EntityManager.
We provide configuration options for the MySQL connection. The
hibernate.dialect
is set to MySQL Hibernate dialect.
package com.zetcode.model; import java.util.Objects; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "cities") public class City { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; private int population; public City() { } public City(String name, int population) { this.name = name; this.population = population; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPopulation() { return population; } public void setPopulation(int population) { this.population = population; } @Override public int hashCode() { int hash = 7; hash = 79 * hash + Objects.hashCode(this.id); hash = 79 * hash + Objects.hashCode(this.name); hash = 79 * hash + this.population; return hash; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final City other = (City) obj; if (this.population != other.population) { return false; } if (!Objects.equals(this.name, other.name)) { return false; } return Objects.equals(this.id, other.id); } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("City{id=").append(id).append(", name=") .append(name).append(", population=") .append(population).append("}"); return builder.toString(); } }
This is the City
entity.
@Entity @Table(name = "cities") public class City {
The @Entity
annotation specifies that the class is an entity.
The @Table
annotation specifies the primary table for the annotated entity.
@Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id;
The @Id
annotation specifies the primary key of an entity while the
@GeneratedValue
provides for the specification of generation strategies
for the values of primary keys.
package com.zetcode; import com.zetcode.model.City; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import javax.persistence.Query; public class HibernateJpqlSelect { private static final String PERSISTENCE_UNIT_NAME = "my-pu"; public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory( PERSISTENCE_UNIT_NAME); EntityManager entityManager = emf.createEntityManager(); try { entityManager.getTransaction().begin(); String qlQuery = "SELECT c FROM City c"; Query query = entityManager.createQuery(qlQuery); List<City> cities = query.getResultList(); cities.stream().forEach((x) -> System.out.println(x)); String qlQuery2 = "SELECT COUNT(c) FROM City c"; Query query2 = entityManager.createQuery(qlQuery2); Long nOfCities = (Long) query2.getSingleResult(); System.out.printf("There are %d cities%n", nOfCities); String qlQuery3 = "SELECT c.name FROM City c WHERE c.population=1759000"; Query query3 = entityManager.createQuery(qlQuery3); List<String> names = query3.getResultList(); names.stream().forEach((x) -> System.out.println(x)); String qlQuery4 = "SELECT c FROM City c ORDER BY population DESC"; Query query4 = entityManager.createQuery(qlQuery4); List<City> cities2 = query4.getResultList(); cities2.stream().forEach((x) -> System.out.println(x)); String qlQuery5 = "SELECT SUM(c.population) FROM City c"; Query query5 = entityManager.createQuery(qlQuery5); Long popSum = (Long) query5.getSingleResult(); System.out.printf("Sum of city populations %d%n", popSum); entityManager.getTransaction().commit(); } finally { entityManager.close(); emf.close(); } } }
The example runs five JPQL SELECT statements.
EntityManagerFactory emf = Persistence.createEntityManagerFactory( PERSISTENCE_UNIT_NAME); EntityManager entityManager = emf.createEntityManager();
An EntityManager
is created from an EntityManagerFactory
.
It is an interface to interact with the persistence context.
String qlQuery = "SELECT c FROM City c"; Query query = entityManager.createQuery(qlQuery); List<City> cities = query.getResultList(); cities.stream().forEach((x) -> System.out.println(x));
The SELECT c FROM City c
is a JPQL query that returns all cities.
A Query
is created with EntityManager's
createQuery()
.
From a Query
we get the result with getResultList()
.
String qlQuery2 = "SELECT COUNT(c) FROM City c";
With SELECT COUNT(c) FROM City c
, we get the number of City
entities.
String qlQuery3 = "SELECT c.name FROM City c WHERE c.population=1759000";
With SELECT c.name FROM City c WHERE c.population=1759000
, we select an entity
whose population is equal to 1759000
.
String qlQuery4 = "SELECT c FROM City c ORDER BY population DESC";
With SELECT c FROM City c ORDER BY population DESC
, we have a list of entities
ordered by population in descending order.
String qlQuery5 = "SELECT SUM(c.population) FROM City c";
With SELECT SUM(c.population) FROM City c
, we get the sum of all
city populations.
$ mvn exec:java -q City{id=1, name=Bratislava, population=432000} City{id=2, name=Budapest, population=1759000} City{id=3, name=Prague, population=1280000} City{id=4, name=Warsaw, population=1748000} City{id=5, name=Los Angeles, population=3971000} City{id=6, name=New York, population=8550000} City{id=7, name=Edinburgh, population=464000} City{id=8, name=Berlin, population=3671000} There are 8 cities Budapest City{id=6, name=New York, population=8550000} City{id=5, name=Los Angeles, population=3971000} City{id=8, name=Berlin, population=3671000} City{id=2, name=Budapest, population=1759000} City{id=4, name=Warsaw, population=1748000} City{id=3, name=Prague, population=1280000} City{id=7, name=Edinburgh, population=464000} City{id=1, name=Bratislava, population=432000} Sum of city populations 21875000
In this tutorial, we have used JPQL SELECT statements in Hibernate.