Port of schuchert.wikispaces.com


JPA_Tutorial_3_FAQ

JPA_Tutorial_3_FAQ

JPA Tutorial 3 - FAQ

What did we learn/observe so far (mid-day)?

What did we learn/observe so far (end of day)?

//What else have you learned today?//

//Day 3 - Tutorial #3 Questions//

//What else have you learned today?//

//Notes for Brett://

s

These tests are in LibraryTest.java

    @Test
    public void patronHasNumberOfOverdueBooks() {
        final Patron p = createPatron();
        final Book b1 = createBook();
        final Book b2 = createBook();
        library.checkout(p.getId(), CURRENT_DATE, b1.getId());
        int numOfBooks;
        numOfBooks = library.getNumberOfOverdueBooksOfPatron(p, CURRENT_PLUS_14);
        assertEquals(0, numOfBooks);
        library.checkout(p.getId(), CURRENT_PLUS_8, b2.getId());
        numOfBooks = library.getNumberOfOverdueBooksOfPatron(p, CURRENT_PLUS_15);
        assertEquals(1, numOfBooks);
        library.returnBook(CURRENT_PLUS_8, b1.getId());
        numOfBooks = library.getNumberOfOverdueBooksOfPatron(p, CURRENT_PLUS_15);
        assertEquals(0, numOfBooks);
    }

    // My change
    @Test
    public void patronCannotCheckoutWithOverdueBooks() {
        final Patron p = createPatron();
        final Book b1 = createBook();
        library.checkout(p.getId(), CURRENT_DATE, b1.getId());

        final Book b2 = createBook();
        try {
            library.checkout(p.getId(), CURRENT_PLUS_15, b2.getId());
            fail(String.format("1. Should have thrown exception: %s", PatronHasOverdueBooks.class
                    .getName()));
        }
        catch (PatronHasOverdueBooks e) {
            assertEquals(1, e.getNumberOfOverdueBooks());
            final Book b3 = createBook();
            library.checkout(p.getId(), CURRENT_DATE, b2.getId());
            try {
                library.checkout(p.getId(), CURRENT_PLUS_15, b3.getId());
                fail(String.format("2. Should have thrown exception: %s",
                        PatronHasOverdueBooks.class.getName()));
            }
            catch (PatronHasOverdueBooks e1) {
                assertEquals(2, e1.getNumberOfOverdueBooks());
            }
            int numOfBooks = library.getNumberOfOverdueBooksOfPatron(p, CURRENT_PLUS_14);
            assertEquals(0, numOfBooks);
        }
    }

And here are the changes in project:

There is a new exception class called: PatronHasOverdueBooks Here it is:

package exception;

/**
 * Thrown when a Patron attempts checkout while he has overdue books.
 */
public class PatronHasOverdueBooks extends RuntimeException {
    private static final long serialVersionUID = 7328551028997485470L;
    private final int numberOfOverdueBooks;
    public PatronHasOverdueBooks(final int numberOfOverdueBooks) {
        this.numberOfOverdueBooks = numberOfOverdueBooks;
    }
    public int getNumberOfOverdueBooks() {
        return this.numberOfOverdueBooks;
    }

}

In Library class, I added to the checkout method a validation for overdue books:

    public void checkout(final Long patronId, final Date checkoutDate, final Long... bookIds) {
        ...
        // Checking number of overdue books of the Patron
        int booksOverdue = getNumberOfOverdueBooksOfPatron(p, checkoutDate);
        if (booksOverdue != 0) {
            throw new PatronHasOverdueBooks(booksOverdue);
        }

        ...
    }

Also, in Library class, the new method: getNumberOfOverdueBooksOfPatron

    public int getNumberOfOverdueBooksOfPatron(final Patron patron, final Date compareDate) {
        return getLoanDao().numberOfOverdueBookOfPatron(patron, compareDate);
    }

LoanDao can return the number of overdue books of specific Patron:

    /**
     * Return number of overdue books of this patron
     *
     * @param patron
     * @param compareDate
     * @return int - The number of overdue books
     */
    public int numberOfOverdueBookOfPatron(final Patron patron, final Date compareDate) {
        final Query query = getEm().createNamedQuery("Loan.overdueBooksOfPatron");
        query.setParameter("date", compareDate);
        query.setParameter("patron", patron);

        return query.getResultList().size();

    }

It uses a new named-query. One of the parameter is the Patron (not the patron’s id). I wanted to see how the join works …

@NamedQuery(name = "Loan.overdueBooksOfPatron", query = "SELECT l.book FROM Loan l WHERE l.dueDate < :date AND l.patron = :patron")

Comments

" Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.