In the previous article, we learned how to create database queries using Spring Data JPA @NamedQuery and @NamedQueries annotations.
In this article, we will learn how to create database queries using @NamedNativeQuery
and @NamedNativeQueries
annotations. These annotations let you define the query in native SQL by losing the database platform
independence.
Let's develop a complete example to demonstrate the usage of @NamedNativeQuery
and @NamedNativeQueries
using
the Spring Boot application which quickly bootstraps with autoconfiguration.
There are many ways to create a Spring Boot application. You can refer below articles to create a Spring Boot application.
>>Create Spring Boot Project With Spring Initializer
<?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>net.guides.springboot2</groupId>
<artifactId>springboot-testing-examples</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot-testing-examples</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.4</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>17</java.version>
</properties>
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
The Spring Boot Maven plugin provides many convenient features:
main()
method to flag as a
runnable class.Spring Boot
dependencies. You can override any version you wish, but it will default to Boot’s chosen set of
versions.In this example, we store User
objects, annotated as a JPA entity.
import java.util.Date;
import jakarta.persistence.*;
@Entity
@Table(name = "users")
@NamedNativeQuery(name = "User.findByEmailAddress", query = "select * from users where email_address = ?1", resultClass = User.class)
@NamedNativeQueries(value = {
@NamedNativeQuery(name = "User.findByLastname", query = "select * from users where lastname = ?1", resultClass = User.class) })
public class User {
private long id;
private String firstname;
private String lastname;
private Date startDate;
private String emailAddress;
private int age;
private int active;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getActive() {
return active;
}
public void setActive(int active) {
this.active = active;
}
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
@Override
public String toString() {
return "User [id=" + id + ", firstname=" + firstname + ", lastname=" + lastname + ", startDate=" + startDate +
", emailAddress=" + emailAddress + ", age=" + age + ", active=" + active + "]";
}
}
User
class is annotated with @Entity
, indicating that it is a JPA entity.@Id
so that JPA will recognize
it as the object’s ID. The id
property is also annotated with @GeneratedValue
to indicate that the ID
should be generated
automatically.Specifies a named native SQL query. Query names are scoped to the persistence unit. The NamedNativeQuery
annotation can be applied to an entity or mapped superclass.
@Entity
@Table(name = "users")
@NamedNativeQuery(name = "User.findByEmailAddress", query = "select * from users where email_address = ?1", resultClass = User.class)
public class User {
}
Used to specify multiple native SQL-named queries. Query names are scoped to the persistence unit. The NamedNativeQueries
annotation can be applied to an entity or mapped
superclass.
@Entity
@Table(name = "users")
@NamedNativeQueries(value = {
@NamedNativeQuery(name = "User.findByLastname", query = "select * from users where lastname = ?1", resultClass = User.class) })
public class User {
}
package net.guides.springboot2.springboottestingexamples.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import net.guides.springboot2.springboottestingexamples.model.User;
/**
* UserRepository demonstrates the method name query generation.
*
* @author Ramesh Fadatare
*
*/
@Repository
public interface UserRepository extends JpaRepository < User, Long > {
User findByEmailAddress(String emailAddress);
List <User> findByLastname(String lastname);
}
Here you create an Application
class with all the components.
package net.guides.springboot2.springboottestingexamples;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import net.guides.springboot2.springboottestingexamples.model.User;
import net.guides.springboot2.springboottestingexamples.repository.UserRepository;
@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired
private UserRepository userRepository;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String...args) throws Exception {
User user = new User();
user.setActive(1);
user.setAge(28);
user.setEmailAddress("ramesh24@gmail.com");
user.setFirstname("Ramesh");
user.setLastname("Fadatare");
user.setStartDate(new Date());
user = userRepository.save(user);
System.out.println("-------------------------------------:: " + user.getId());
System.out.println(" ---------------@NamedNativeQuery ---------------------");
System.out.println("--------------findByEmailAddress -----------------");
User user2 = userRepository.findByEmailAddress("ramesh24@gmail.com");
System.out.println(user2.toString());
System.out.println(" ---------------@NamedNativeQueries ---------------------");
System.out.println("--------------findByLastname -----------------");
List < User > user3 = userRepository.findByLastname("Fadatare");
System.out.println(user3.get(0).toString());
}
}
Note that we have used UserRepository methods to demonstrate @NamedNativeQuery
and @NamedNativeQueries
annotations.
We are using Maven so we can run the application using ./mvnw spring-boot:run. Or you can build the JAR file with ./mvnw clean package. Then you can run the JAR file:
java -jar target/spring-data-jpa-example-0.1.0.jar