Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple CRUD operations Exception design

I am developing a very small test to simulate a 3 layered system so I can understand how Exceptions work. At the same time I would like to come up with a reasonable approach so I can use this design as further reference for similar operations in other applications.

I have been reading through different articles on the topic and it seems that there is a huge controversy over using checked or unchecked exceptions which is making me doubt about my final design.

I won’t go through the arguments used to criticize or support checked/unchecked exceptions because probably they are all well known but rather I will present my design looking for some advices in how to improve it and make it (as long as possible) similar to a real application.

The system is in charge to perform basic CRUD operations in a relational DB (lets say MySQL) using JDBC. I have the following: a presentation layer, a service layer and a persistence layer.

Based on this answer Handling Dao exceptions in service layer it makes sense for me not to expose specific layer implemantation and decouple the layers. So I decided to create my custom exceptions and wrap them into a Base Exception per layer so I can translate specific layer exceptions (i.e SQLException) into general layer exceptions (i.e PersistentException, BusinessException). And if later on the implementation changes I can simply wrap the new one into the base exception expected by the higher layer. So I have the following exceptions:

com.user.persistent.exceptions
    |_ PersistentException
    |_ ExistingUserException
    |_ Some more..

com.user.business.exceptions
    |_ BusinessException
    |_ somemore....

From Josh Bloch’s book Effective Java: “Use checked exceptions for conditions from which the caller can reasonably be expected to recover.” I am also not that sure but I believe a user can recover from a SQLExeption (i.e A user by mistake provides an existing ID, he can re-type the right one ) so I decided to make the previous exceptions checked exceptions. Here is an overview of how the classes look like:

Persistence Layer.

public interface UserDAO 
{
    public void create(User team) throws PersistentException;
}

//Implementation in DefaultUserDAO.java
@Override
    public void create(User team) throws PersistentException 
    {       
        try
        {
            System.out.println("Attempting to create an user - yikes the user already exists!");
            throw new SQLIntegrityConstraintViolationException();           
        }
        catch(SQLIntegrityConstraintViolationException e)
        {
            throw new ExistingUserException(e);
        }
        catch (SQLException e) 
        {
            throw new PersistentException(e);
        } 
        finally 
        {
            //close connection
        }
    }

Service Layer:

public interface UserService 
{
    void create(User user) throws BusinessException;
}

//Implementation of UserService
@Override
public void create(User user) throws BusinessException 
{
    System.out.println("Doing some business logic before persisting the user..");

    try 
    {
        userDao.create(user);
    } 
    catch (PersistentException e) 
    {
        throw new BusinessException(e);
    }

}

Presentation

    try 
    {
        userService.create(user);
    } catch (BusinessException e) 
    {   
        e.printStackTrace();
    }

Now the following points make me feel unsure about this design.

  1. I like the idea of having the compiler verifying if clients of the method catch/throw the declared exceptions when using checked exceptions. However, at the same time I think this approach leads to clutter code to handle all the exceptions. Not sure if it is because I am not making proper usage of exceptions or because checked exceptions really lead to clutter code.
  2. I also like the idea of decoupling layers by wrapping specific layer exceptions into General ones. But, I can see a lot of new classes being created for every possible exception instead of just throwing an existing java exception.
  3. I can also see that a lot the existing code on this application is devoted to handle exceptions and a small portion of it is devoted to the actual objective of the system.

These are actually my main concerns and make me wonder if this is really a good design. I would like to hear your opinions about it (and perhaps some small snippets of sample code). Can you guys give me some hints on how can I possibly improve it? In a way I can achieve decoupling between layers and avoid leaking layer specific concerns..

like image 691
Bartzilla Avatar asked Dec 22 '12 17:12

Bartzilla


People also ask

What is CRUD design?

CRUD Meaning: CRUD is an acronym that comes from the world of computer programming and refers to the four functions that are considered necessary to implement a persistent storage application: create, read, update and delete.

How do you handle exceptions in Microservices?

First, we need to set up the capability of throwing exceptions on core banking service errors. Open core banking service and follow the steps. Create a common exception class where we going to extend RuntimeException. After that, we can create custom runtime exceptions to use with this API.

Which is not a method of CrudRepository to perform CRUD operations in Spring data JPA?

CrudRepository does not provide any method for pagination and sorting. JpaRepository extends PagingAndSortingRepository. It provides all the methods for implementing the pagination.


1 Answers

I believe your application should not handle SQL exceptions when the development is complete. So, you should not catch exceptions like SQLException. Or if you are forced to catch them, then just rethrow RuntimeException. From my honour experience creating your own exceptions only makes sence if you develop some sort of library for someone else. And even in this case in many cases you may use existing exceptions. Try to develop without creating your exceptions. Create them only when you realize that you can't do without them.

like image 97
Stepan Yakovenko Avatar answered Sep 27 '22 21:09

Stepan Yakovenko