1 Reply Latest reply on Sep 15, 2006 2:11 PM by jc7442

    Exception handling

    martinganserer

      Hello experts,

      could you please take a look at my code. I am really not sure if my exception handling is correct or maybe completely wrong.
      As you can see I catch every exception log what happened and throw a new RuntimeException!
      Could you give me a hand how I should implement exception handling in my DAO beans?


      @Stateless
      public class CustomerServiceBean implements CustomerService, CustomerServiceRemote
      {
       private @PersistenceContext(unitName = "order") EntityManager em;
       private static Logger logger = Logger.getLogger(Customer.class);
      
       /**
       * Persist customer object
       * @param customer the customer to persist
       * @return the persisted customer object
       * @throws GenericServiceException
       */
       @PermitAll
       public Customer persistCustomer(Customer customer) throws GenericServiceException
       {
       if(customer == null)
       {
       String errorMessage = "Can not persist empty object!";
       logger.warn(errorMessage);
       throw new GenericServiceException(errorMessage);
       }
      
       try
       {
       if(logger.isDebugEnabled())
       logger.debug("Persist customer " + customer.toString() + ".");
      
       em.persist(customer);
      
       if(logger.isDebugEnabled())
       logger.debug("Customer " + customer.toString() + " with id " + customer.getId() + " persisted!");
      
       return customer;
       }
       catch(Throwable e)
       {
       logger.error("Could not persist customer " + customer.toString(),e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       }
      
       /**
       * Merge customer object
       * @param customer the customer to persist
       * @return the merged customer object
       * @throws GenericServiceException
       */
       @PermitAll
       public Customer mergeCustomer(Customer customer) throws GenericServiceException
       {
       if(customer == null)
       {
       String errorMessage = "Can not merge empty object!";
       logger.warn(errorMessage);
       throw new GenericServiceException(errorMessage);
       }
      
       try
       {
       if(logger.isDebugEnabled())
       logger.debug("Merge customer " + customer.toString() + ".");
      
       return em.merge(customer);
      
       }
       catch(Throwable e)
       {
       logger.error("Could not merge customer " + customer.toString(),e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       }
      
       /**
       * Find customer
       * @param id
       * @return the customer object
       * @throws GenericServiceException
       */
       @PermitAll
       public Customer findCustomerById(int id) throws GenericServiceException
       {
       try
       {
       if(logger.isDebugEnabled())
       logger.debug("Find customer " + id);
      
       return em.find(Customer.class, id);
       }
       catch(Throwable e)
       {
       logger.error("Could not find customer " + id,e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       }
      
       /**
       * Find customer
       * @param id
       * @param mustExist if true an exception will be thrown if the object does not exist.
       * @return a customer object.
       * @throws GenericServiceException
       */
       @PermitAll
       public Customer findCustomerById(int id, boolean mustExist) throws GenericServiceException
       {
       try
       {
       if(logger.isDebugEnabled())
       logger.debug("Find customer " + id);
      
       if(mustExist)
       {
       Customer customer = new Customer(id);
       em.refresh(customer);
       return customer;
       }
       else
       return em.find(Customer.class, id);
       }
       catch(Throwable e)
       {
       logger.error("Could not find customer " + id,e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       }
      
       /**
       * Find customer
       * @param customer the customer to search for
       * @return the customer object
       * @throws GenericServiceException
       */
       @PermitAll
       public Customer findCustomerById(Customer customer) throws GenericServiceException
       {
       if(customer == null)
       {
       String errorMessage = "Can not search by using an empty object!";
       logger.warn(errorMessage);
       throw new GenericServiceException(errorMessage);
       }
      
       try
       {
       if(logger.isDebugEnabled())
       logger.debug("Find customer " + customer.getId());
      
       return em.find(Customer.class,customer.getId());
       }
       catch(Throwable e)
       {
       logger.error("Could not find customer " + customer.getId(),e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       }
      
       /**
       * Remove all customers
       * @return the number of removed customer objects
       * @throws GenericServiceException
       */
       @PermitAll
       public long removeAllCustomers() throws GenericServiceException
       {
       try
       {
       if(logger.isDebugEnabled())
       logger.debug("Remove all customer objects!");
      
       return em.createQuery("delete from Customer").executeUpdate();
       }
       catch(Throwable e)
       {
       logger.error("Could not remove all customer objects!",e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       }
      
       /**
       * Get all customers
       * @return a collection of customers objects
       * @throws GenericServiceException
       */
       @PermitAll
       public Collection<Customer> getAllCustomers() throws GenericServiceException
       {
       try
       {
       if(logger.isDebugEnabled())
       logger.debug("Find all customer objects!");
      
       return (Collection<Customer>) em.createQuery("from Customer").getResultList();
       }
       catch(Throwable e)
       {
       logger.error("Could not find customer objects!",e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       }
      
       /**
       * Get all customers
       * @param noOfObjects
       * @param startIndex
       * @return a collection of customer objects
       * @throws GenericServiceException
       */
       @PermitAll
       public Collection<Customer> getAllCustomers(int noOfObjects, int startIndex) throws GenericServiceException
       {
       try
       {
       if(logger.isDebugEnabled())
       logger.debug("Find all customer objects with paging!");
      
       Query query = em.createQuery("from Customer");
       query.setMaxResults(noOfObjects);
       query.setFirstResult(startIndex);
       return (Collection<Customer>) query.getResultList();
       }
       catch(Throwable e)
       {
       logger.error("Could not find customer objects with paging!",e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       }
      
       /**
       * Remove customer
       * @param id the identifier of the object to be removed
       * @throws GenericServiceException
       */
       @PermitAll
       public void removeCustomer(int id) throws GenericServiceException
       {
       Customer customer;
      
       try
       {
       if(logger.isDebugEnabled())
       logger.debug("Remove customer " + id);
      
       customer = em.find(Customer.class,id);
       }
       catch(Throwable e)
       {
       logger.error("Could not remove customer " + id,e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       if(customer == null)
       {
       String errorMessage = "Can not remove a non existing object!";
       logger.warn(errorMessage);
       throw new GenericServiceException(errorMessage);
       }
      
       try
       {
       em.remove(customer);
       }
       catch(Throwable e)
       {
       logger.error("Could not remove customer " + id,e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       }
      
       /**
       * Get customer
       * @param name
       * @return the customer object
       * @throws GenericServiceException
       */
       @PermitAll
       public Customer getCustomerByName(String name) throws GenericServiceException
       {
       try
       {
       if(logger.isDebugEnabled())
       logger.debug("Search for customer!");
      
       String ejbQL = " from Customer a where a.name = :param1";
       Query query = em.createQuery(ejbQL);
       query.setParameter("param1",name);
      
       return (Customer) query.getSingleResult();
       }
       catch(Throwable e)
       {
       logger.error("Could not search for customer!",e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       }
      
       /**
       * Search customer
       * @param name
       * @return a collection of customer objects
       * @throws GenericServiceException
       */
       @PermitAll
       public Collection<Customer> searchCustomerByName(String name) throws GenericServiceException
       {
       try
       {
       if(logger.isDebugEnabled())
       logger.debug("Search for customers!");
      
       String ejbQL = " from Customer a where a.name like :param1";
       Query query = em.createQuery(ejbQL);
       query.setParameter("param1",name);
      
       return (Collection<Customer>) query.getResultList();
       }
       catch(Throwable e)
       {
       logger.error("Could not search for customers!",e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       }
      
       /**
       * Search for customers objects via an ejb query string
       * @param ejbQL the ejb query string
       * @return a collection of customer objects
       * @throws GenericServiceException
       */
       @PermitAll
       public Collection<Customer> searchCustomers(String ejbQL) throws GenericServiceException
       {
       if(ejbQL == null || ejbQL.equals(""))
       {
       String errorMessage = "Query string must not be empty!";
       logger.warn(errorMessage);
       throw new GenericServiceException(errorMessage);
       }
      
       try
       {
       if(logger.isDebugEnabled())
       logger.debug("Search for customer objects!");
      
       return (Collection<Customer>) em.createQuery(ejbQL).getResultList();
       }
       catch(Throwable e)
       {
       logger.error("Could not search for customers by using query: " + ejbQL,e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       }
      
       /**
       * Search for customers objects via an ejb query string
       * @param ejbQL
       * @param noOfObjects
       * @param startIndex
       * @return a collection of customer objects
       * @throws GenericServiceException
       */
       @PermitAll
       public Collection<Customer> searchCustomers(String ejbQL, int noOfObjects, int startIndex) throws GenericServiceException
       {
       if(ejbQL == null || ejbQL.equals(""))
       {
       String errorMessage = "Query string must not be empty!";
       logger.warn(errorMessage);
       throw new GenericServiceException(errorMessage);
       }
      
       try
       {
       if(logger.isDebugEnabled())
       logger.debug("Search for customer objects!");
      
       Query query = em.createQuery(ejbQL);
       query.setMaxResults(noOfObjects);
       query.setFirstResult(startIndex);
       return (Collection<Customer>) query.getResultList();
       }
       catch(Throwable e)
       {
       logger.error("Could not search for customers by using query: " + ejbQL,e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       }
      
       /**
       * Check if customer already exists
       * @param id
       * @return true if the customer already exists
       * @throws GenericServiceException
       */
       @PermitAll
       public boolean checkCustomer(int id) throws GenericServiceException
       {
       try
       {
       if(logger.isDebugEnabled())
       logger.debug("Check customer " + id + "!");
      
       long counter = (Long) em.createQuery("select count(a) from Customer a where a.id = :param").setParameter("param",id).getSingleResult();
      
       if(counter == 0)
       return false;
      
       return true;
       }
       catch(Throwable e)
       {
       logger.error("Could not check customer!",e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       }
      
       /**
       * Remove a list of customers
       * @param customers a list of objects to be removed
       * @throws GenericServiceException
       */
       @PermitAll
       public void removeCustomers(Collection<Customer> customers) throws GenericServiceException
       {
       try
       {
       if(logger.isDebugEnabled())
       logger.debug("Remove a list of customers!");
      
       for(Customer listItem : customers)
       {
       Customer customer = em.find(Customer.class,listItem.getId());
       em.remove(customer);
       }
       }
       catch(Throwable e)
       {
       logger.error("Could not remove customers!",e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       }
      
       /**
       * Persist a list of customers
       * @param customers a list of objects to be persistet
       * @return a list of persisted customers
       * @throws GenericServiceException
       */
       @PermitAll
       public Collection<Customer> persistCustomers(Collection<Customer> customers) throws GenericServiceException
       {
       Collection<Customer> itemList = new ArrayList();
       try
       {
       if(logger.isDebugEnabled())
       logger.debug("Persist a list of customers!");
      
       for(Customer item : customers)
       {
       em.persist(item);
       itemList.add(item);
       }
       return itemList;
       }
       catch(Throwable e)
       {
       logger.error("Could not persist customers!",e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       }
      
       /**
       * Merge a list of customers
       * @param customers a list of objects to be merged
       * @return a list of merged customers
       * @throws GenericServiceException
       */
       @PermitAll
       public Collection<Customer> mergeCustomers(Collection<Customer> customers) throws GenericServiceException
       {
       Collection<Customer> itemList = new ArrayList();
       if(logger.isDebugEnabled())
       logger.debug("Merge a list of customers!");
      
       try
       {
       for(Customer item : customers)
       {
       em.merge(item);
       itemList.add(item);
       }
       return itemList;
       }
       catch(Throwable e)
       {
       logger.error("Could not merge customers!",e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       }
      
       /**
       * Count customers
       * @return the number of persistent customers
       * @throws GenericServiceException
       */
       @PermitAll
       @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
       public Long countCustomers() throws GenericServiceException
       {
       try
       {
       if(logger.isDebugEnabled())
       logger.debug("Count customers!");
      
       return (Long) em.createQuery("select count (a) from Customer a").getSingleResult();
       }
       catch(Throwable e)
       {
       logger.error("Could not count customers!",e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       }
      
       /**
       * Count customers
       * @param criteria the query criteria(s)
       * @return the number of persistent customers
       * @throws GenericServiceException
       */
       @PermitAll
       @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
       public Long countCustomers(String criteria) throws GenericServiceException
       {
       if(criteria == null)
       criteria = "";
       try
       {
       if(logger.isDebugEnabled())
       logger.debug("Count customers!");
      
       if(criteria.toLowerCase().contains("where"))
       return (Long) em.createQuery("select count (a) from Customer a " + criteria).getSingleResult();
       else
       return (Long) em.createQuery("select count (a) from Customer a where " + criteria).getSingleResult();
       }
       catch(Throwable e)
       {
       logger.error("Could not count customers by using criteria: " + criteria,e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       }
      
       /**
       * Get country of this customer
       * @param id
       * @return the country of this customer
       * @throws GenericServiceException
       */
       @PermitAll
       public Country getCountryOfCustomer(int id) throws GenericServiceException
       {
       try
       {
       if(logger.isDebugEnabled())
       logger.debug("Find country of customer " + id);
      
       return (Country) em.createQuery("select b from Customer a join a.country b where a.id =" + id).getSingleResult();
       }
       catch(Throwable e)
       {
       logger.error("Could not find country of customer " + id,e);
       throw new GenericServiceException(e.getMessage(),e.getCause());
       }
       }
      
      }


        • 1. Re: Exception handling
          jc7442

          First, I'm not an expert that's just my way to manage exception !

          I do not manage my exception in the same way as yours.

          First, if you want log exception and throw another exception, you may perhaps consider to use JBoss AOP interceptor in order not to make your source code more complex.

          Now my way to manage exception is the following (it's my solution, maybe that's not good):
          Usually I do not catch exception for my DAO (it means that if a runtime exception is thrown it may rollback the JTA transaction) and I have added an interceptor on all methods of remote session bean and MDB. This interceptor is in charge to log the exception and to modifiy throw a new exception (this exception as a ref on the logged exception. I often have swing client, I log exception on server side to be sure to have a log - if i just leave the exception go to client side, usualy client does not have in its classpath one of the chained exception).
          In some cases, when the exception thrown is a error case (not a bug in my code), in the session bean, I cacth the excpetion, log it and usualy throw an exception with an ApplicationException annotation with a rollback=false. Consequently the exception does not rollback the JTA transaction. This exception is not a Runtime consequently, invoker has to manage the exception.

          To summarize:
          - consider using JBoss AOP inteceptor
          - Consider using ApplicationException annotation
          You probably will have more flexibility for your exception management and a easier code to write.

          I'm interesting to know what's your feeling about that !