Handling Dao exceptions in service layer

牧云@^-^@ 提交于 2019-11-28 17:55:26

When we create a layered application, there is always a user layer and another used layer. For this case UI layer -> uses service Layer -> uses DAO layer.

Now its very subjective and open to interpretations. But the objective should be a good degree of decoupling. To achieve this, one way out is the define generic layer specific exceptions say PersistentException, ServiceException etc. These exception will wrap the actual layer specific exception.

For example say if there is some error on database side (Constraint violation etc), wrap that in PersistentException and let service layer handle that (as to how to convey this to UI layer in a generic way)

Now since the integration between service layer and DAO layer is contractual (interface based), the DAO layer is free to change the implementation to anything as long as it obeys the interface contract. So if you change the implementation which throws some new exceptions, those new exceptions can be wrapped in PersistentException and Service layer remains unaffected.

Yes. its a good idea to create your own independant exceptions for each layer.

For example, if you are using a particular DAO implementation, you should wrap the implementation specific exception to your own generic exception and throw it forward to Service Layer.

However, you need to be sensitive in creating your own hierarchy of exception such that it shouldn't be an overhead to application development as well as its able to maintain the information required in the Service Layer. Most of the times, custom error codes with generic exception suffice this.

Something like this can be used to simulate implementation specific exception and thrown to Service layer.

class AppDAOException extends Exception {
    public final static int _FAIL_TO_INSERT = 1;
    public final static int _UPDATE_FAILED = 2;
    public final static int _SQL_ERROR = 3;
    private int errorCode;
    public AppDAOException(int errorCode) {
        this.errorCode = errorCode;
    }
    public getErrorCode() {
        return errorCode;
    }
}

Throwing from DAO implementation:

try {
   //code here
} catch (some.impl.SQLSyntaxException e) {
   throw new AppDAOException (AppDAOException._SQL_ERROR );
}

About leakage of concern: You may not want your service layer to bother about all the exceptions - such as:

} catch(NoRowExistsException e) {
    return null;
} finally {
   //release resources
}

So the call has to be taken based on application needs.

Your DAO layer already leaks into the service layer when you do operations like:

userDAO.persist(user);

Exceptions, being a part of the API just like operation should be considered in the same way.

try {
    userDAO.persist(user);
} catch (DAOException e) {
    // looks fine to me
}

Leakage can happen with runtime exceptions, or when you rethrow exceptions

try {
    userDAO.persist(user);
} catch (SQLException e) {
    // sql implementation exposed
}

But even this sounds better than "layer independent" exceptions

Good question..!! Handling exceptions at the UI layer (for example, actions layer if you are using struts) is the good approach.Making exceptions generic is not a good way to deal with this issue. Every layer should have however their specific exceptions as generic. for example, DAO layer may have custom exception handlers like DavaSavingException, IOException etc..

So the approach is throw exception from DAO to service layer and again throw it to UI layer and catch in UI specific classes.

However things are too diplomatic depending upon your applications/needs.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!