TL;DR
Panache trims JPA boilerplate in Quarkus. Implement PanacheRepository〈 T〉 (or PanacheRepositoryBase〈 T, ID〉 ) to get a fluent CRUD/query API, paging & sorting via PanacheQuery, and fewer lines everywhere.
🔸 WHY PANACHE (REPO PATTERN)?
▪️ Less boilerplate vs plain JPA: ready-made CRUD & query helpers
▪️ Clear separation: your domain stays lean, repos encapsulate DB access
▪️ First-class paging, sorting, projections via PanacheQuery
🔸 QUICK SETUP
〈 !-- pom.xml --〉
〈 dependency〉
〈 groupId〉 io.quarkus〈 /groupId〉
〈 artifactId〉 quarkus-hibernate-orm-panache〈 /artifactId〉
〈 /dependency〉
〈 dependency〉
〈 groupId〉 io.quarkus〈 /groupId〉
〈 artifactId〉 quarkus-jdbc-postgresql〈 /artifactId〉
〈 /dependency〉
// Entity
@Entity
public class Book {
@Id @GeneratedValue Long id;
String title;
String author;
LocalDate publishedOn;
}
// Repository
@ApplicationScoped
public class BookRepository implements PanacheRepository〈 Book〉 { }
Docs: Quarkus Panache guide & javadoc for the full API. (Quarkus)
🔸 PANACHE REPOSITORY: THE ESSENTIAL METHODS
PanacheRepository〈 T〉 extends the full API from PanacheRepositoryBase〈 T, ID〉 . Below are the core families you’ll use daily (multiple overloads exist). See javadoc for the exhaustive list. (Javadoc)
Create & Update
▪️ persist(entity) / persist(entities…)
▪️ persistAndFlush(entity)
▪️ flush() (force sync)
▪️ isPersistent(entity) (managed?)
Read by id
▪️ findById(id) / findByIdOptional(id)
Delete
▪️ delete(entity)
▪️ deleteById(id)
▪️ deleteAll()
▪️ delete("status", Status.OLD) / delete("name like ?1", pattern) (simplified JPQL) (Stack Overflow)
Count
▪️ count()
▪️ count("author", author) / count("title like ?1", pattern)
List/Stream everything (for small sets)
▪️ listAll() / listAll(Sort.by("publishedOn").descending())
▪️ streamAll()
Query (simplified JPQL / named / params)
▪️ find(query, params…) → returns PanacheQuery〈 T〉
▪️ find(query, Sort, params…)
▪️ list(query, params…) / stream(query, params…)
▪️ findAll() / findAll(Sort)
Paging & Sorting with PanacheQuery
PanacheQuery〈 Book〉 q = Book.find("author", "Pratchett")
.page(Page.of(0, 20))
.sort(Sort.by("publishedOn").descending());
List〈 Book〉 page = q.list(); // current page
long total = q.count(); // total items
Tip: prefer PanacheQuery + page() for large datasets; use list/stream only for small tables. (Quarkus)
🔸 EXAMPLES YOU’LL REUSE
// Create
@Transactional
public Book add(Book b) {
persist(b); // managed; id filled after flush
return b;
}
// Read + paging
public List〈 Book〉 latestBy(String author, int page, int size) {
return find("author", author)
.page(Page.of(page, size))
.sort(Sort.by("publishedOn").descending())
.list();
}
// Update (managed entity)
@Transactional
public void rename(long id, String newTitle) {
Book b = findById(id);
if (b != null) b.title = newTitle; // dirty checking on flush
}
// Delete by query
@Transactional
public long purgeOld(LocalDate before) {
return delete("publishedOn 〈 ?1", before);
}
🔸 TAKEAWAYS
▪️ Implement PanacheRepository〈 T〉 to get a rich, fluent CRUD & query API fast
▪️ Use find(…) → PanacheQuery for paging/sorting; avoid listAll() on big tables
▪️ Embrace simplified JPQL strings ("author", value) for concise queries
▪️ Remember transactions (@Transactional) for write ops
#Quarkus #JPA #Hibernate #Panache #Java #JakartaEE #Backend #ORM #CleanCode #JavaEE #DevTips
Go further with Java certification:
Java👇
Spring👇