Skip to content

Commit 7bf6004

Browse files
committed
fix broken code examples, and make 'em more readable
Signed-off-by: Gavin King <[email protected]>
1 parent 7002ee8 commit 7bf6004

File tree

2 files changed

+58
-36
lines changed

2 files changed

+58
-36
lines changed

documentation/src/main/asciidoc/introduction/Introduction.adoc

Lines changed: 56 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -447,10 +447,14 @@ We might start with something like this, a mix of UI and persistence logic:
447447

448448
[source,java]
449449
----
450-
@Path("/") @Produces("application/json")
450+
@Path("/")
451+
@Produces("application/json")
451452
public class BookResource {
452453
453-
@GET @Path("book/{isbn}")
454+
private final SessionFactory sessionfactory = .... ;
455+
456+
@GET
457+
@Path("book/{isbn}")
454458
public Book getBook(String isbn) {
455459
var book = sessionFactory.fromTransaction(session -> session.find(Book.class, isbn));
456460
return book == null ? Response.status(404).build() : book;
@@ -473,18 +477,25 @@ Let's now consider a slightly more complicated case.
473477

474478
[source,java]
475479
----
476-
@Path("/") @Produces("application/json")
480+
@Path("/")
481+
@Produces("application/json")
477482
public class BookResource {
478483
private static final int RESULTS_PER_PAGE = 20;
479484
480-
@GET @Path("books/{titlePattern}/{page:\\d+}")
481-
public List<Book> findBooks(String titlePattern, int page) {
482-
var books = sessionFactory.fromTransaction(session -> {
483-
return session.createSelectionQuery("from Book where title like ?1 order by title", Book.class)
484-
.setParameter(1, titlePattern)
485-
.setPage(Page.page(RESULTS_PER_PAGE, page))
486-
.getResultList();
487-
});
485+
private final SessionFactory sessionfactory = .... ;
486+
487+
@GET
488+
@Path("books/{titlePattern}/{pageNumber:\\d+}")
489+
public List<Book> findBooks(String titlePattern, int pageNumber) {
490+
var page = Page.page(RESULTS_PER_PAGE, pageNumber);
491+
var books =
492+
sessionFactory.fromTransaction(session -> {
493+
var findBooksByTitle = "from Book where title like ?1 order by title";
494+
return session.createSelectionQuery(findBooksByTitle, Book.class)
495+
.setParameter(1, titlePattern)
496+
.setPage(page)
497+
.getResultList();
498+
});
488499
return books.isEmpty() ? Response.status(404).build() : books;
489500
}
490501
@@ -498,9 +509,9 @@ Let's hit the code with our favorite thing, the Extract Method refactoring. We o
498509

499510
[source,java]
500511
----
501-
static List<Book> findBooksTitled(Session session,
502-
String titlePattern, Page page) {
503-
return session.createSelectionQuery("from Book where title like ?1 order by title", Book.class)
512+
static List<Book> findBooksTitled(Session session, String titlePattern, Page page) {
513+
var findBooksByTitle = "from Book where title like ?1 order by title";
514+
return session.createSelectionQuery(findBooksByTitle, Book.class)
504515
.setParameter(1, titlePattern)
505516
.setPage(page)
506517
.getResultList();
@@ -522,13 +533,13 @@ We need a place to put the annotation, so let's move our query method to a new c
522533
query = "from Book where title like :title order by title")
523534
class Queries {
524535
525-
static List<Book> findBooksTitled(Session session,
526-
String titlePattern, Page page) {
536+
static List<Book> findBooksTitled(Session session, String titlePattern, Page page) {
527537
return session.createQuery(Queries_._findBooksByTitle_) //type safe reference to the named query
528538
.setParameter("title", titlePattern)
529539
.setPage(page)
530540
.getResultList();
531541
}
542+
532543
}
533544
----
534545

@@ -546,11 +557,13 @@ Whatever the case, the code which orchestrates a unit of work usually just calls
546557
[source,java]
547558
----
548559
@GET
549-
@Path("books/{titlePattern}")
550-
public List<Book> findBooks(String titlePattern) {
551-
var books = sessionFactory.fromTransaction(session ->
552-
Queries.findBooksTitled(session, titlePattern,
553-
Page.page(RESULTS_PER_PAGE, page)));
560+
@Path("books/{titlePattern}/{pageNumber:\\d+}")
561+
public List<Book> findBooks(String titlePattern, int pageNumber) {
562+
var page = Page.page(RESULTS_PER_PAGE, pageNumber);
563+
var books =
564+
sessionFactory.fromTransaction(session ->
565+
// call handwritten query method
566+
Queries.findBooksTitled(session, titlePattern, page));
554567
return books.isEmpty() ? Response.status(404).build() : books;
555568
}
556569
----
@@ -567,7 +580,9 @@ Suppose we simplify `Queries` to just the following:
567580

568581
[source,java]
569582
----
583+
// a sort of proto-repository, this interface is never implemented
570584
interface Queries {
585+
// a HQL query method with a generated static "implementation"
571586
@HQL("where title like :title order by title")
572587
List<Book> findBooksTitled(String title, Page page);
573588
}
@@ -579,11 +594,13 @@ We can call it just like we were previously calling our handwritten version:
579594
[source,java]
580595
----
581596
@GET
582-
@Path("books/{titlePattern}")
583-
public List<Book> findBooks(String titlePattern) {
584-
var books = sessionFactory.fromTransaction(session ->
585-
Queries_.findBooksTitled(session, titlePattern,
586-
Page.page(RESULTS_PER_PAGE, page)));
597+
@Path("books/{titlePattern}/{pageNumber:\\d+}")
598+
public List<Book> findBooks(String titlePattern, int pageNumber) {
599+
var page = Page.page(RESULTS_PER_PAGE, pageNumber);
600+
var books =
601+
sessionFactory.fromTransaction(session ->
602+
// call the generated query method "implementation"
603+
Queries_.findBooksTitled(session, titlePattern, page));
587604
return books.isEmpty() ? Response.status(404).build() : books;
588605
}
589606
----
@@ -592,32 +609,37 @@ In this case, the quantity of code eliminated is pretty trivial.
592609
The real value is in improved type safety.
593610
We now find out about errors in assignments of arguments to query parameters at compile time.
594611

595-
This is all quite nice so far, but at this point you're probably wondering whether we could use dependency injection to obtain an _instance_ of the `Queries` interface.
612+
This is all quite nice so far, but at this point you're probably wondering whether we could use dependency injection to obtain an _instance_ of the `Queries` interface, and have this object take care of obtaining its own `Session`.
596613
Well, indeed we can.
597614
What we need to do is indicate the kind of session the `Queries` interface depends on, by adding a method to retrieve the session.
615+
Observe, again, that we're _still_ not attempting to hide the `Session` from the client code.
598616

599617
[source,java]
600618
----
619+
// a true repository interface with generated implementation
601620
interface Queries {
602-
EntityManager entityManager();
621+
// declare the kind of session backing this repository
622+
Session session();
603623
624+
// a HQL query method with a generated implementation
604625
@HQL("where title like :title order by title")
605626
List<Book> findBooksTitled(String title, Page page);
606627
}
607628
----
608629

609-
The `Queries` interface is now considered a _repository_, and we may use CDI to inject the repository implementation generated by Hibernate Processor:
630+
The `Queries` interface is now considered a _repository_, and we may use CDI to inject the repository implementation generated by Hibernate Processor.
631+
Also, since I guess we're now working in some sort of container environment, we'll let the container manage transactions for us.
610632

611633
[source,java]
612634
----
613-
@Inject Queries queries;
635+
@Inject Queries queries; // inject the repository
614636
615637
@GET
616-
@Path("books/{titlePattern}")
638+
@Path("books/{titlePattern}/{pageNumber:\\d+}")
617639
@Transactional
618-
public List<Book> findBooks(String titlePattern) {
619-
var books = queries.findBooksTitled(session, titlePattern,
620-
Page.page(RESULTS_PER_PAGE, page));
640+
public List<Book> findBooks(String titlePattern, int pageNumber) {
641+
var page = Page.page(RESULTS_PER_PAGE, pageNumber);
642+
var books = queries.findBooksTitled(session, titlePattern, page); // call the repository method
621643
return books.isEmpty() ? Response.status(404).build() : books;
622644
}
623645
----

documentation/src/main/asciidoc/introduction/Processor.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,8 +424,8 @@ What if we would like to inject a `Queries` object instead of calling its constr
424424
[%unbreakable]
425425
[TIP]
426426
====
427-
As you <<architecture,recall>>, we don't think these things really need to be container-managed objects.
428-
But if you _want_ them to beif you're allergic to calling constructors, for some reasonthen:
427+
As you <<organizing-persistence,recall>>, we don't think these things really need to be container-managed objects.
428+
But if you _want_ them to be--if you're allergic to calling constructors, for some reason--then:
429429
430430
- placing `jakarta.inject` on the build path will cause an `@Inject` annotation to be added to the constructor of `Queries_`, and
431431
- placing `jakarta.enterprise.context` on the build path will cause a `@Dependent` annotation to be added to the `Queries_` class.

0 commit comments

Comments
 (0)