Skip to content

Commit

Permalink
BAEL-6157 - Using records with JPA (eugenp#13626)
Browse files Browse the repository at this point in the history
* BAEL-6157 - Using records with JPA

* BAEL-6157 - Changing test class name

* BAEL-6157 - Changing test class name

* BAEL-6157 - Adding start-class to module
  • Loading branch information
abh1navv authored Mar 17, 2023
1 parent 1afb78d commit 22bd0db
Show file tree
Hide file tree
Showing 13 changed files with 292 additions and 0 deletions.
2 changes: 2 additions & 0 deletions spring-boot-modules/spring-boot-3/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@
<mapstruct.version>1.5.2.Final</mapstruct.version>
<springdoc.version>2.0.0</springdoc.version>
<maven-surefire-plugin.version>3.0.0-M7</maven-surefire-plugin.version>
<start-class>com.baeldung.sample.TodoApplication</start-class>

</properties>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.baeldung.recordswithjpa;

import com.baeldung.recordswithjpa.entity.Book;
import com.baeldung.recordswithjpa.records.BookRecord;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class QueryService {
@PersistenceContext
private EntityManager entityManager;

public List<BookRecord> findAllBooks() {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<BookRecord> query = cb.createQuery(BookRecord.class);
Root<Book> root = query.from(Book.class);
query.select(cb
.construct(BookRecord.class, root.get("id"), root.get("title"), root.get("author"), root.get("isbn")));
return entityManager.createQuery(query).getResultList();
}

public BookRecord findBookById(Long id) {
TypedQuery<BookRecord> query = entityManager
.createQuery("SELECT new com.baeldung.recordswithjpa.records.BookRecord(b.id, b.title, b.author, b.isbn) " +
"FROM Book b WHERE b.id = :id", BookRecord.class);
query.setParameter("id", id);
return query.getSingleResult();
}

public List<BookRecord> findAllBooksUsingMapping() {
Query query = entityManager.createNativeQuery("SELECT * FROM book", "BookRecordMapping");
return query.getResultList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.baeldung.recordswithjpa;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class RecordsAsJpaApplication {

public static void main(String[] args) {
SpringApplication.run(RecordsAsJpaApplication.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.baeldung.recordswithjpa.entity;

import com.baeldung.recordswithjpa.records.BookRecord;
import jakarta.persistence.*;

@SqlResultSetMapping(
name = "BookRecordMapping",
classes = @ConstructorResult(
targetClass = BookRecord.class,
columns = {
@ColumnResult(name = "id", type = Long.class),
@ColumnResult(name = "title", type = String.class),
@ColumnResult(name = "author", type = String.class),
@ColumnResult(name = "isbn", type = String.class)
}
)
)
@Entity
@Table(name = "book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String author;
private String isbn;

public Book() {
}

public Book(Long id, String title, String author, String isbn) {
this.id = id;
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;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.baeldung.recordswithjpa.records;

public record BookRecord(Long id, String title, String author, String isbn) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.baeldung.recordswithjpa.records;

public record CustomBookRecord(Long id, String title) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.baeldung.recordswithjpa.repository;

import com.baeldung.recordswithjpa.entity.Book;
import com.baeldung.recordswithjpa.records.BookRecord;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;

import java.util.List;

public interface BookRepository extends CrudRepository<Book, Long> {
List<BookRecord> findBookByAuthor(String author);

@Query("SELECT new com.baeldung.recordswithjpa.records.BookRecord(b.id, b.title, b.author, b.isbn) " +
"FROM Book b WHERE b.id = :id")
BookRecord findBookById(@Param("id") Long id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.baeldung.recordswithjpa.repository;

import com.baeldung.recordswithjpa.records.CustomBookRecord;

import java.util.List;

public interface CustomBookRepository {
List<CustomBookRecord> findAllBooks();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.baeldung.recordswithjpa.repository;

import com.baeldung.recordswithjpa.records.CustomBookRecord;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public class CustomBookRepositoryImpl implements CustomBookRepository {
private final JdbcTemplate jdbcTemplate;

public CustomBookRepositoryImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

public List<CustomBookRecord> findAllBooks() {
return jdbcTemplate.query("SELECT id, title FROM book", (rs, rowNum) -> new CustomBookRecord(rs.getLong("id"), rs.getString("title")));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.baeldung.recordswithjpa;

import com.baeldung.recordswithjpa.entity.Book;
import com.baeldung.recordswithjpa.records.BookRecord;
import com.baeldung.recordswithjpa.repository.BookRepository;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

public class QueryServiceIntegrationTest extends RecordsAsJpaIntegrationTest {

@Autowired
private QueryService queryService;


@Test
void findAllBooks() {
List<BookRecord> allBooks = queryService.findAllBooks();
assertEquals(3, allBooks.size());
}

@Test
void findBookById() {
BookRecord bookById = queryService.findBookById(1L);
assertEquals("The Lord of the Rings", bookById.title());
}

@Test
void findAllBooksUsingMapping() {
List<BookRecord> allBooksUsingMapping = queryService.findAllBooksUsingMapping();
assertEquals(3, allBooksUsingMapping.size());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.baeldung.recordswithjpa;

import com.baeldung.recordswithjpa.entity.Book;
import com.baeldung.recordswithjpa.repository.BookRepository;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class RecordsAsJpaIntegrationTest {
@Autowired
protected BookRepository bookRepository;

@BeforeEach
void setUp() {
Book book = new Book(1L,"The Lord of the Rings", "J.R.R. Tolkien", "978-0544003415");
Book book2 = new Book(2L,"The Hobbit", "J.R.R. Tolkien", "978-0547928227");
Book book3 = new Book(3L,"Harry Potter and the Philosopher's Stone", "J.K. Rowling", "978-0747532699");

bookRepository.save(book);
bookRepository.save(book2);
bookRepository.save(book3);
}

@AfterEach
void tearDown() {
bookRepository.deleteAll();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.baeldung.recordswithjpa.repository;

import com.baeldung.recordswithjpa.RecordsAsJpaIntegrationTest;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class BookRepositoryIntegrationTest extends RecordsAsJpaIntegrationTest {

@Test
void findBookByAuthor() {
assertEquals(2, bookRepository.findBookByAuthor("J.R.R. Tolkien").size());
}

@Test
void findBookById() {
assertEquals("The Lord of the Rings", bookRepository.findBookById(1L).title());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.baeldung.recordswithjpa.repository;

import com.baeldung.recordswithjpa.RecordsAsJpaIntegrationTest;
import com.baeldung.recordswithjpa.records.CustomBookRecord;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

class CustomBookRepositoryIntegrationTest extends RecordsAsJpaIntegrationTest {

@Autowired
private CustomBookRepository customBookRepository;

@Test
void findAllBooks() {
List<CustomBookRecord> allBooks = customBookRepository.findAllBooks();
assertEquals(3, allBooks.size());
}
}

0 comments on commit 22bd0db

Please sign in to comment.