• Save
09 Application Design
Upcoming SlideShare
Loading in...5
×
 

09 Application Design

on

  • 1,471 views

 

Statistics

Views

Total Views
1,471
Slideshare-icon Views on SlideShare
1,408
Embed Views
63

Actions

Likes
1
Downloads
1
Comments
0

3 Embeds 63

http://ranjankumar.in 59
http://interopy.wordpress.com 2
http://www.slideshare.net 2

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    09 Application Design 09 Application Design Presentation Transcript

    • Designing layered applications
    • Hibernate appliction
      • Hibernate is intended to be used in just about any architectural
      • scenario like :
      • A swing clinet
      • Inside a servlet engine (can be used in any MVC frameworks)
      • Inside an EJB container
      • A lightweight containers like Spring
      • JMX server like JBoss
    • Designing layered applications
      • Layering helps you achieve separation of concerns, making code
      • more readable by grouping code that does similar things.
      • On the other hand layering carries a price: Each extra layer increases the
      • amount of code it takes to implement a simple piece of functionality –
      • and more code make the functionality itself more difficult to change.
      • “Best design” varies from application to application.
    • Hibernate appliction
      • Simple use case from CaveatEmptor application:
      • When a user places a bid on an item. CaveatEmptor must perform the
      • following tasks, all in a single request:
      • Check that the amount entered by the user is greater than the
      • maximum existing bid for the item.
      • Check that the auction hasn’t yet ended
      • Create anew bid for the item
      • If either of the checks fails, the user should be informed of the reason
      • for the failure;
      • If both checks are successful, the user should be informed that the new bid has been made. These checks are our bussiness rules.
      • If a filure occurs while accessing the database, the user should be informed that the system is currently unavilable.
    • Using Hibernate in a servlet engine
      • First, we need a way for our application to obtain new Session instances.
      • We will write a simple helper(or utitlity) class to handle configuration
      • and SessionFactory initialization and provide easy access to new
      • Sessions. A simple Hibernate utility class:
      public class HibernateUtil { private static final SessionFactory sessionFactory; static { try { Configuration cfg = new configuration(); sessionFactory = cfg.configure().buildSessionFactory(); } catch (Throwable ex) { ex.printStackTrace(System.out); throw new ExceptionInIntializerError(ex); } } public static Session getSession() throws HibernateException { return sessionFactory.openSession(); } }
    • Hibernate appliction
      • The SessionFactory is bound to static (and final) varibale. All our
      • threads can share this one constant, because SessionFactory
      • is threadsafe.
      • The SessionFactory is created in a static initializer block. This block
      • is executed when a classloader loads the class.
      • Our utility class has just one public method, a factory method for
      • new Sessions.(get Session())
    • Hibernate appliction
      • Writing a simple action servlet(Struts):
      • Implementing a simple use case in one execute() method
      • public void execute()
      • {
      • Long itemId = … // get value from request
      • Long userId = … // get value from request
      • BigDecimat bidAmount = … //get value from request
      • try
      • {
      • // get a new session using utility class and then start a databasetransaction
      • Session session = HibernateUtil.getSession();
      • Transaction tx = session.beginTransaction();
    • Hibernate appliction
      • // Load requested item
      • try {
      • Item item = (Item) session.load(Item.class,ItemId, LockMode.UPGRADE);
      • // check the autcion still valid
      • if (item.getEndDate().before(new Date()))
      • { …. // Forward to error page }
    • Hibernate appliction
      • // check amount of Bid
      • Query q = session.createQuery(“select max(b.amount)” +
      • “ from Bid b where b.item = ‘item”);
      • q.setEntitiy(“item”, item);
      • Bigdecimal maxBidAmount = (BigDecimal) q.uniqueResult();
      • if(maxBidAmount.compareTo(bidAmount) . 0) {
      • …… . // Forward to error page
      • ]
    • Hibernate appliction
      • // Add a new Bid to item
      • User bidder = (User) session.load(User.class, userId);
      • Bid newBid = new Bid(bidAmount,item,bidder);
      • item.addBid(newBid);
      • … . //place new bid in scope for next page
      • tx.commit();
      • … //Forward to showsucess.jsp page
      • …… catch() { }
      • finally{ session.close();
      • ……
    • Hibernate appliction
      • // Add a new Bid to item
      • User bidder = (User) session.load(User.class, userId);
      • Bid newBid = new Bid(bidAmount,item,bidder);
      • item.addBid(newBid);
      • … . //place new bid in scope for next page
      • tx.commit();
      • … //Forward to showsucess.jsp page
      • …… catch() { }
      • finally{ session.close();
      • ……
    • Hibernate appliction
      • The problem with this implementation are :
      • Lot of confusion with session,transaction and exception-handling
      • code, since this code is typically identical for all actions, we need
      • to centralize it (ex having execute() method of an abstract superclass
      • of our actions.
      • We also have problem with lazy initializtion if we access the bid on the
      • ShowSuccess.jsp page; By the time we get to the JSP the Hibenate
      • session is already closed, so we can’t access unfetched lazy associations.
    • Hibernate appliction
      • The problem with this implementation are :
      • Lot of confusion with session,transaction and exception-handling
      • code, since this code is typically identical for all actions, we need
      • to centralize it (ex having execute() method of an abstract superclass
      • of our actions.
      • We also have problem with lazy initializtion if we access the bid on the
      • ShowSuccess.jsp page; By the time we get to the JSP the Hibenate
      • session is already closed, so we can’t access unfetched lazy associations.
    • Hibernate appliction
      • Solution to this problem is “thread-local session patten” :
      • A thread-local session is a single session instance associated with a
      • particular request. It lets you implement a persistence context,
      • similar to the JTA notion of a transaction context. Any components
      • called in the same request will share the same session and pesistence
      • context.
      • It’s especially useful to include a JSP in the persistence context. The
      • JSP pulls information from the domain model by navigating the object
      • graph beginning at some persistent object in the session or request
      • scope
    • Hibernate appliction
      • As we already closed Hibernate session at the end of the action’s
      • execute method, Hibernate throws a LazyInitializationException
      • when the association is accessed---the database connection is
      • no longer available, and the object graph is detached,so Hibernate
      • can’t fetch the collection.
      • Solution :
      • Write the action to ensure that all needed associations are fully
      • initialized before forwarding to the view.
      • Best way here is to leave the session open until the view is
      • completely rendered.
    • Hibernate appliction
      • Thread-local session pattern :
      • It allows you to have a single Hibernate session per request, spanning
      • the view and potentially multiple action executes().
      • Java provides the ThreadLocal class for implementing thread scoped
      • variables. The ThreadLocal session pattern combines a ThreadLocal
      • with an interceptor or servlet filter that closes the Session at the end
      • of the request, after the view is rendered and just before the response
      • is sent to the client.
    • Hibernate appliction
      • An improved version of HibernateUtil using thread-local variables:
      • public class HibernateUtil {
      • private static final SessionFactory sessionFactory;
      • private static final ThreadLocal threadSession = new ThreadLocal();
      • private static final ThreadLocal threadTransaction = new ThreadLocal();
      • static {
      • // Initialize sessionFactory…
      • }
    • Hibernate appliction
      • public static Session getSession() {
      • Session s =(Session) threadSession.get();
      • // open a new session, if this thread has none yet
      • try {
      • if (s==null) {
      • s = sessionFactory.opensession();
      • threadSession.set(s);
      • }
      • } catch (HibernateException ex) {
      • throw new InfrastructureException(ex);
      • }
      • return s;
      • }
    • Hibernate appliction
      • public static void closeSession() {
      • try {
      • Session s = (Session) threadSession.get();
      • threadSession.set(null);
      • if ( s != null && s.isOpen())
      • s.close();
      • } catch (HibernateException ex) {
      • throw new InfrastructureException(ex);
      • }
      • }
    • Hibernate appliction
      • public static void beginTransation()
      • {
      • Transaction tx = (Transaction) threadTransaction.get();
      • try {
      • if (tx == null) {
      • tx = getSession().beginTransaction();
      • threadTransaction.set(tx);
      • }
      • } catch (HibernateException ex) {
      • throw new InfrastructureException(ex);
      • }
      • }
    • Hibernate appliction
      • public static void beginTransaction()
      • {
      • Transaction tx = (Transaction) threadTransaction.get();
      • try {
      • if (tx == null) {
      • tx = getSession().beginTransaction();
      • threadTransaction.set(tx);
      • }
      • } catch (HibernateException ex) {
      • throw new InfrastructureException(ex);
      • }
      • }
    • Hibernate appliction
      • public static void commitTransaction()
      • {
      • Transaction tx = (Transaction) threadTransaction.get();
      • try {
      • if ( tx != null & !tx.wasCommitted() && !tx.wasRolledBack())
      • tx.commit();
      • threadTransaction.set(null);
      • }
      • } catch (HibernateException ex) {
      • rollbackTransaction();
      • throw new InfrastructureException(ex);
      • }
      • }
    • Hibernate appliction
      • public static void rollbackTransaction()
      • {
      • Transaction tx = (Transaction) threadTransaction.get();
      • try {
      • threadTransaction.set(null);
      • if ( tx != null & !tx.wasCommitted() && !tx.wasRolledBack())
      • tx.rollback();
      • }
      • } catch (HibernateException ex) {
      • throw new InfrastructureException(ex);
      • } finally {
      • closeSession(;
      • }
      • }
    • Hibernate appliction
      • The doFilter() method closes the Hibernate Session
      • public void doFilter(ServletRequest request, ServletResponse response,
      • FilterChain chain)
      • throws IOException, ServletException {
      • try {
      • chain.doFilter(request,response);
      • HibernateUtil.commitTransaction();
      • }
      • finally {
      • HibenateUtil.commitTransaction();
      • } finally {
      • HibernateUtil.closeSession();
      • }
      • }
    • Hibernate appliction
      • We don’t start a database transaction or open a session until an action
      • requests one.
      • Any subsequent actions, and finally the view, reuse the same session and
      • transaction.
      • After all actions(servlets) and the view are executed, we commit any
      • pending database transaction.
    • Hibernate appliction
      • We can simplify our action’s execute() method to the following :
      • public void execute() {
      • // Get values from request
      • try {
      • HibernateUtil.beginTransaction();
      • Session session = HibernateUtil.getSession();
      • //Load requested item
      • //check auction still valid
      • //check amount of Bid
      • //Add new bid to Item
      • //place new bid in scope for new page
      • //Forward to showsuccess.jsp page
      • } catch (HibernateException ex) {
      • throw new InfrastructureException(ex);
      • } catch (Exceptionex) {
      • // Throw aplication specific exception
      • }}
    • Hibernate appliction
      • DAO (Data Access Objects)
      • DAO defines an interface to persistence operations (CRUD and finder
      • methods) relating to a particular persistent entity; it advises you to
      • group code that relates to persistence of that entity.
      • A simple DAO abstracting item-related persistence operations:
    • Hibernate appliction
      • public class ItemDAO {
      • public ItemDAO() {
      • HibernateUtil.beginTransaction();
      • }
      • // ********************************************************** //
      • public Item getItemById(Long itemId, boolean lock)
      • throws InfrastructureException {
      • Session session = HibernateUtil.getSession();
      • Item item = null;
      • try {
      • if (lock) {
      • item = (Item) session.load(Item.class, itemId, LockMode.UPGRADE);
      • } else {
      • item = (Item) session.load(Item.class, itemId);
      • }
      • } catch (HibernateException ex) {
      • throw new InfrastructureException(ex);
      • }
      • return item;
      • }
    • Hibernate appliction
      • public Bid getMaxBid(Long itemId)
      • throws InfrastructureException {
      • Bid maxBidAmount = null;
      • try {
      • // Note the creative where-clause subselect expression...
      • Query q = HibernateUtil.getSession().getNamedQuery("minBid");
      • q.setLong("itemid", itemId.longValue());
      • maxBidAmount = (Bid) q.uniqueResult();
      • }
      • catch (HibernateException ex) {
      • throw new InfrastructureException(ex);
      • }
      • return maxBidAmount;
      • }
    • Hibernate appliction
      • public class UserDAO {
      • public UserDAO() {
      • HibernateUtil.beginTransaction();
      • }
      • // ********************************************************** //
      • public User getUserById(Long userId, boolean lock)
      • throws InfrastructureException {
      • Session session = HibernateUtil.getSession();
      • User user = null;
      • try {
      • if (lock) {
      • user = (User) session.load(User.class, userId, LockMode.UPGRADE);
      • } else {
      • user = (User) session.load(User.class, userId);
      • }
      • } catch (HibernateException ex) {
      • throw new InfrastructureException(ex);
      • }
      • return user;
      • }
    • Hibernate appliction
      • Further simplify our action code :
      • public void execute() {
      • //Get values from request
      • try { ItemDAO itemDAO = new ItemDAO();
      • UserDAO userDAO = new UserDAO();
      • if (itemDAO.getMaxBidAmount(itemId). compareTo
      • (bidAmount) > 0)
      • throw new BusinessException(“Bid amount too low”);
      • Item item = itemDAO.getItemByID(itemId);
      • Bid newBid = item.placeBid(userDAO.getUserById(userId),
      • bidAmount);
      • // place new bid in scope for next page
      • // forward to showsuccess.jsp page
      • } catch (BusinessException ex) {
      • // forward to error page
      • } catch (Exception ex ) {
      • // Throw application specific exception
      • }}
    • Hibernate appliction
      • The session façade pattern
      • A session façade is an EJB session bean that acts as the external
      • interface to some business-oriented software component.
      • The use of a session bean lets you take advantage of
      • EJB declarative transaction
      • security
      • and provides coarse-grained services
    • Hibernate appliction
      • Few changes in HibernateUtil class :
      • Hibernate SessionFactory is kept in the JNDI registry rather than
      • in a static variable. Its for consistency with how other similar objects
      • (such as JTA UserTransaction) are hadled in an EJB environement.
      • public static SessionFactory getSessionFactory() {
      • SessionFactory sessions = null;
      • try { Context ctx = new InitialContext();
      • String jndiName = “java:hibernate/HibernateFactory”;
      • sessions = (SessionFactory) ctx.lookup(jndiName);
      • } catch (NamingException ex) {
      • throw new InfrastructureException(ex); }
      • return sessions;
      • }
    • Hibernate appliction
      • The remote interface of our session façade is :
      • public interface CaveatEmptorFacade extends javax.ejb.EJBObjec
      • {
      • public Bid bifForItem( Long userId, Long itemId,
      • BigDecimal bidAmount)
      • throws RemoteException;
      • }
    • Hibernate appliction
      • The bean implementation class is as follows :
      • public class CaveatEmptorFacadeBean implements
      • javax.ejb.SessionBean {
      • … .
      • public Bid bidForitem(Long userId, Long itemId,
      • BigDecimal bidAmoun) throws RemoteException
      • Bid newBid = null;
      • try {
      • ItemDAO itemDAO = new ItemDAO();
      • UserDAO userDAO = new userDAO();
      • BigDecimal currentMaxAmmount =
      • itemDAO.getMaxBidAmount(itemId);
      • BigDecimal currentMinAmount =
      • itemDAO.getMinBidAmount(itemId);
      • Item item = itemDAO.getItemById(itemId);
      • User user = userDAo,getUserById(userId);
      • newBid = item.placeBid(user, newAmount, currentMaxAmount,
      • currentMinAmount();
      • HibernateUtil.commitTransaction();
      • } finally { HibernateUtil.closeSession(); }
      • return newBid; }
    • Audit Logging
      • An audit log is a database table that contains information about changes made to other data, specifically about the event that results in the chage.
      • For example, we might record information about creating and update events for auction Items. The information that’s recorded usually includes the user, the date and time of the event, what type of event occurred, and the item that was changed.
      • Audit logs are often handled using database trigger, however it is not portable across databases.
    • Audit Logging
      • You need to perform several steps to implement audit logging:
      • 1. Mark the persistent classes for which you want to enable
      • logging.
      • 2. Define the information that should be logged : user,date, time,
      • type of modification and so on.
      • 3. Tie it all together with a Hibernate Interceptor that automatically
      • creates the audit trail for you.
      • Refer to : caveatemptorsrcjavaorghibernateauctionpersistenceaudit