Ending Conversations
The "Confirm" button is bound to the action method confirm()
of HotelBookingAction
.
<h:commandButton value="Confirm"
action="#{hotelBooking.confirm}"
id="confirm"/>
The confirm()
method is tagged with the @End
annotation,
which ends the long-running conversation and results in all state associated with
the conversation being destroyed at the end of the request.
Since the pages.xml
file specifies a redirect for this action, the state
will not be destroyed
until after the redirect completes. Note that even the success message
that we create using the built-in facesMessages
component is transparently
propagated across the redirect!
@End
public void confirm()
{
if (booking==null || hotel==null) return "main";
em.persist(booking);
facesMessages.add("Thank you, #{user.name}, your confimation number " +
"for #{hotel.name} is #{booking.id}");
log.info("New booking: #{booking.id} for #{user.username}");
events.raiseEvent("bookingConfirmed");
}
@End
public void cancel() {}
@Destroy @Remove
public void destroy() {}
}
When the conversation state is finally destroyed, Seam calls the @Destroy
method,
which results in removal of the SFSB.
Notice that the HotelBookingAction.confirm()
method
raises a bookingConfirmed
event before it finishes. The
event mechanism allows Seam components to communicate with each other
without direct coupling. In this case, the BookingListAction
component captures the bookingConfirmed
event and refreshes
the existing booking list for the current user.
public class BookingListAction implements BookingList, Serializable
{
... ...
@Factory
@Observer("bookingConfirmed")
public void getBookings()
{
bookings = em.createQuery("from Booking b where b.user.username = " +
":username order by b.checkinDate")
.setParameter("username", user.getUsername())
.getResultList();
}
}