February 24th, 2023
Entities Relationships
With NamedQuery, we can reuse the query in multiple locations.
4.0.0
org.springframework.boot
spring-boot-starter-parent
3.0.2
com.brains.jpa.hibernate
jpa-hibernate-demo
0.0.1-SNAPSHOT
jpa-hibernate-demo
Demo project for Spring Boot
17
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-web
com.h2database
h2
runtime
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
org.projectlombok
lombok
spring.datasource.url=jdbc:h2:mem:testdb;NON_KEYWORDS=USER;DB_CLOSE_ON_EXIT=FALSE
spring.h2.console.enabled=true
spring.jpa.defer-datasource-initialization=true
# Turn Statistics ON
#spring.jpa.properties.hibernate.generate_statistics=true
logging.level.org.hibernate.stat=debug
#logging.level.root=trace
# Show all queries
spring.jpa.show-sql=true
# Format the queries
spring.jpa.properties.hibernate.format_sql=true
For writing multiple NamedQuery, we need to use the @NamedQueries
package com.brains.jpa.hibernate.jpahibernatedemo.entity;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import lombok.AccessLevel;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Data
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Course {
@Id
@GeneratedValue
private Long id;
private String name;
public Course(String name) {
this.name = name;
}
}
package com.brains.jpa.hibernate.jpahibernatedemo.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Data @NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class Passport {
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String number;
}
package com.brains.jpa.hibernate.jpahibernatedemo.entity;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Data @NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class Review {
@Id
@GeneratedValue
private Long id;
private String rating;
private String description;
}
package com.brains.jpa.hibernate.jpahibernatedemo.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Data @NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class Student {
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String name;
}
insert into course(id, name, created_date, last_updated_date)
values(10001, 'JPA in 5 steps', LOCALTIMESTAMP, LOCALTIMESTAMP);
insert into course(id, name, created_date, last_updated_date)
values(10002, 'JDBC in 10 steps', LOCALTIMESTAMP, LOCALTIMESTAMP);
insert into course(id, name, created_date, last_updated_date)
values(10003, 'JPQL in 50 steps', LOCALTIMESTAMP, LOCALTIMESTAMP);
insert into student(id, name)
values(20001,'Ranga');
insert into student(id, name)
values(20002,'Adam');
insert into student(id, name)
values(20003,'Jane');
insert into passport(id, number)
values(40001,'E12345');
insert into passport(id, number)
values(40002,'F212345');
insert into passport(id, number)
values(40003,'G12345');
insert into review(id, rating, description)
values(50001,'1', 'Great course');
insert into review(id, rating, description)
values(50002,'3', 'Nice course');
insert into review(id, rating, description)
values(50004,'5', 'Good you are writing');
Use NativeQueries when multiple rows are required to be updated/inserted. Or in case there the JPA is not supported and need to use the database functionality directly.
package com.brains.jpa.hibernate.jpahibernatedemo;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.brains.jpa.hibernate.jpahibernatedemo.entity.Course;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery;
import jakarta.transaction.Transactional;
@SpringBootTest(classes = JpaHibernateDemoApplication.class)
class JPQLTest {
@Autowired
EntityManager em;
private Logger logger = LoggerFactory.getLogger(this.getClass());
// @Test
void jpql_basic() {
Query query = em.createNamedQuery("query_get_all_courses");
List resultList = query.getResultList();
logger.info("list - jpql_basic: -> {}", resultList);
}
// @Test
void jpql_typed() {
TypedQuery query = em.createNamedQuery("query_get_all_courses", Course.class);
List resultList = query.getResultList();
logger.info("Course - jpql_typed: -> {}", resultList);
}
// @Test
void jpql_where() {
TypedQuery query = em.createNamedQuery("query_get_10_courses", Course.class);
List resultList = query.getResultList();
logger.info("Named Course: -> {}", resultList);
}
//@Test
void native_queries_basic() {
Query query = em.createNativeQuery("select * from course", Course.class);
List resultList = query.getResultList();
logger.info("list - native_basic: -> {}", resultList);
}
//@Test
void native_queries_with_param() {
Query query = em.createNativeQuery("select * from course where id = ?", Course.class);
query.setParameter(1, 10001L);
List resultList = query.getResultList();
logger.info("list - native_basic: -> {}", resultList);
}
// @Test
void native_queries_with_named_param() {
Query query = em.createNativeQuery("select * from course where id = :id", Course.class);
query.setParameter("id", 10002L);
List resultList = query.getResultList();
logger.info("list - native_basic: -> {}", resultList);
}
@Test
@Transactional
void native_queries_to_update() {
Query query = em.createNativeQuery("update course set last_updated_date = LOCALTIMESTAMP", Course.class);
int numOfRowsUpdated = query.executeUpdate();
logger.info("numOfRowsUpdated: -> {}", numOfRowsUpdated);
}
}
Leave a Reply