I have few questions like
Which is the right place to handle a Hibernate RuntimeException.
DAO Layer?
ServiceLayer?
For instance, I have saveCustomer and the transaction fails, how can I inform the user through Exceptions?
I'm using the OpenSessionInView pattern, which will commit the transaction only after the view is rendered. In this case, if the transaction fails, How can I inform the user about this?
Generally it's a good idea to handle exceptions at the point in your code where you have the most information on how to handle them (or generate an appropriate error message with enough information). In the j2ee apps I've developed I usually have a transactional service layer that stitches together various DAO calls and I usually handle hibernate-specific runtime exceptions and all other data-related exceptions in the service layer. That said, if there's a pile of logic within a DAO where something bad could go wrong, it's probably not a bad idea idea to catch it there, add some error message context, and then rethrow it up the chain.
If an exception happens within your transaction you can either leave it uncaught or rethrow it with some additional context. This way your transaction manager knows to rollback the transaction. Always have an exception handler set up in your view/controller layer to handle any application-specific runtime exceptions that were thrown from your service layer calls. Inspect them for additional error messages and then use them to inform the user appropriately.
As far as I know, the default behavior when an exception is thrown out of a transaction it should rollback and not get committed at all. The answer to #2 really answers this one as well, i.e., if you've wrapped all your view layer's service calls in try/catch blocks or configure one globally via your web framework you shouldn't have a problem notifying the user that something bad-wrong happened.
This article (Best Practices for Exception Handling) has a decent overview on exception handling in general that you may also find useful.
Catch the exception where you can do something with the exception. If you catch it in DAO layer, then the information specific to dao layer needs to be extracted. e.g. if it is can not insert null value, then log the field details where it is failing. Once done, then the service layer can do business related processing of the exception directly or in wrapped format. You can see these common mistakes in exception handling. This is not applicable to specific hibernate example but in general to all.
Related
I am writing an application where I am confused how to communicate between the business layer and service layer. Let me clear my point by giving example:
createStusdentRecord is method in service layer, I am calling this from business layer. now approach 1 : Create different custom exceptions and throw if some data is missing etc, and on success return studentid, let the business layer handle these exception.
Approach 2 : Create one class SMD ( status message and data ) and handle all exception in service layer. Return this SMD to business layer, with no exception handling in business layer.
Which approach is better and why?
What should be approach when we expose web-services?
I would go with Approach 1. Assuming these truly exceptional conditions that the caller can handle.
I like exceptions because then there is a way to find out why something failed. Hiding all errors or just returning a boolean for success/fail is a bad practice.
The point is to try to hide as much internal stuff as possible to hide implementation details as well as stuff the other layers don't know about (or want to know about) but balance that with enough information if there is a problem.
Student s = dao.createStudent(...)
If the given parameters are invalid do you throw an exception? Maybe depends why they are invalid. Perhaps it's a good idea to make custom Exceptions for concepts such as "A Student with these parameters already exists". However, something like "parameter is invalid" might be a better choice to use one of the JDK built in exceptions like "IllegalArgumentException".
Furthermore, I would make all your custom Exceptions subclass a parent "DaoException" so client code that only cares about success/fail catch catch the parent, but something that wants more fine grained control can always catch subclasses.
Lets say we have two classes Connector and Main. First one has method connect(); and another has actionListener() at the button. The Connector.connect() may throw an exception. I'm not sure where is the proper place to handle this; in Connector or in Main in general? If we programming android, is it the same place to put logs ?
Edit:
Great article covering above problem:
https://today.java.net/pub/a/today/2003/12/04/exceptions.html
It would be much better to throw the exception to the user level if you want the user to know about the exact exception. Otherwise if it is not that important and the exception can be recovered then you can handle it in Connector itself and return some value representing error.
If the exception being thrown from the Connector is not inline with the abstraction level of Main method, then wrap it around an exception that is inline with the caller's abstraction level.
Throw early and catch late is the general rule for exception handling.
Depends on the kind of actions of the handler. If you need to show a message to the user, handle the exception in the view layer (guess it´s Connector in your case). If you need to do actions with the database (for example, a rollbak), handle it in the persistence layer.
I wonder if I always have to use try-catch-error blocks that clutter the code a lot, if I want to catch an error.
Or can I somehow define a global error catcher?
Especially regarding Java EE Webapps.
For every unhandled ex I'd like to log to a specific file, and display a general error page to the user.
I thought I might achieve that with aspects. But for aspects to catch on #AfterThrowing, I too have to introduce try-catch blocks. And as there is no central class for the backing-facades, I would have to surround every backing method with trycatches.
Then the aspect would take them, but I need something to catch without explicit throws exceptions.
How could I to that?
You are looking for the declare soft construct. This will wrap the given exception in a SoftException (an AspectJ-specific RuntimeException) so that it does not need to be explicitly handled. Then you can handle all of these exceptions with some AfterThrowing advice.
declare soft only exists in code style AspectJ (ie- there is no annotation for this). So, you will need to compile your code using the AspectJ compiler, but you can still use load-time weaving for this if you like.
See here:
http://www.eclipse.org/aspectj/doc/released/progguide/quick-other.html
And here:
http://www.eclipse.org/aspectj/doc/released/adk15notebook/declare-soft.html
Here's a code snippet that shows how it can be done:
aspect ErrorHandler {
declare soft : Exception : within(*);
after() throwing(Exception e) : handler(e) {
// do something...
}
}
This will route all exceptions in your system through your custom error handler. And you won't need to explicitly catch or throw them.
It's simple and powerful. Perhaps too powerful, though. I'd recommend refining and being more precise about exactly which exceptions should be softened and which ones need to be advised, but this is the basic idea.
You don't have to do this in every method.
You should not catch an exception that you can't "handle". Handling means more than just rethrowing or logging or printing a stack trace. I think handling means implementing a meaningful recovery strategy.
It might mean "the buck stops here": You're Gandalf on the bridge at the edge of a layer boundary, and no exception shall pass. You don't want users to see nasty messages, so you catch and route them to a friend, easy to understand page that tells them what to do next.
Finally isn't always necessary, but it's perfect for cleaning up resources like file handles and database cursors.
If you cannot handle an exception, there's no shame in adding the throws clause to the method signature and letting callers figure out what they want to do.
In the general case, there is no mechanism to do this - Java does not have what you're looking for.
However, depending on your circumstances, it might be possible.
web.xml Exception Handler
The web.xml file allows you to define a URL to be used to handle specified exception type. (See, for example, http://wiki.metawerx.net/wiki/Web.xml.ExceptionType).
Since you're writing a webapp, you may be able to just let the exceptions throw all the way to the top, and then handle them this way.
Custom interceptor
You mention that you have backing-facades. Depending on how they're being constructed, you may be able to put a generic proxy in front of them to catch and handle the exceptions you're interested in. You've tagged your question with spring, to you might want to look at Spring AOP Proxies.
There might be other ways to get what you want, but it will depend on the specifics of your application's architecture.
The finer control you have of the exceptions, the easier it will be to debug/provide a meaningful message.
To which extent? I would link that to the complexity / expected lifetime of your application. The bigger those are, the finer should be your handling.
I see two main approachs:
User approach: You get at least one exception handling for each UI action (so you can say: "Do not push that button AGAIN").
Debugger approach: Every method has its control.
Keep in mind that most handling could be just logging of rethrowing of the exception.
More to the point, most probably, your Java EE framework will have log options in its configuration files (many of them working with java.util.loggin or log4j). You could tweak that; of course, what is send to each log category will depend of the framework implementation (so maybe not all ERROR messages will be Exceptions).
Im working on developing a webapplication with Spring 3 and Hibernate 3.6. Ive got some questions to the #Transactional Annotation and the structure of the code.
-> When I use #Transactional (transaction management with Spring), do I have to surround the #Transactional-annotated methods with try/catch when calling them?
For example, when I got a method which loads, changes and returns then an object and I call it from another class: do I have to surround the call with try/catch? maybe something goes wrong, no object is returned, database connection fails.. I dont know.
until now, I thought #Transactional cares for all possible occurring exceptions and rolls back every operation in this transaction when an error occurs.
but if it occurs, I must inform the user somehow. when I call the transactional-method in the try-block and it is rolled back, the catch block is activated?
I can tell then the user "something did go wrong". Otherwise the user maybe would not be informed?
Or is it sufficient to check if there is an object returned (if/else), then I dont need try/catch?
Im new and I would like to hear how other structure their code. Thank you :-)
Handling exceptions in Spring is really easy with HandlerExceptionResolvers and #ExceptionHandlers. I tend to use #ExceptionHandler exclusively.
You can use an #ExceptionHandler to handle a specific exception instead of handling it yourself in a try-catch block.
If the user wanted a resource that wasn't found and you want to send a 404.
#ExceptionHandler(NotFoundException.class)
#ResponseStatus(HttpStatus.NOT_FOUND)
public void handleNotFoundException(NotFoundException exc) {
// log something.
}
If there was a Server issue where you'd want to send a 500
#ExceptionHandler(SomeException.class)
public void handleException(SomeException exc, WebRequest request, HttpServletResponse response) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Sorry dude, my server broke");
}
You also should narrowly handle the exceptions. In general you shouldn't do #ExceptionHandler(Exception.class) and I also believe that it works in order, so if you do handle the general Exception it should be the last method in the class.
The Key feature used by Spring is Exception Translation.
rely on exception translation to generate exceptions your client layer understands and use try / catch there only, if possible.
thanks for answering me. I read through the link (spring documentation) and I found the following:
"However, the DAO throws plain HibernateException (which is unchecked, so does not have to be declared or caught), which means that callers can only treat exceptions as generally fatal - unless they want to depend on Hibernate's own exception hierarchy.
Catching specific causes such as an optimistic locking failure is not possible without tying the caller to the implementation strategy. This trade off might be acceptable to applications that are strongly Hibernate-based and/or do not need any special exception treatment."
My DAO is based on Plain Hibernate 3 API, so if I understand it correct, my DAO only throws plain HibernateExceptions. They are unchecked and do not have to be declared or caught.
If something goes wrong, with #Transactional the whole operation is rolled back.
To make sure that everything works as I expected it to work, I have to tie my DAO even closer to my application code. There I can check for example if an object is given back or not. (if null - else)
I could also catch the exception, log it and inform the user that something did go wrong and that his transaction did not work.
So at this point, Im still thinking, that - depending on the transaction:
if I can work with a result, everything is ok - if not, I can inform the user.
when the transaction is not specified to give back a result, I can use try/catch for catching a HibernateException. But is the Transaction still rolled back then? I thought, catching an HibernateException avoids Rolling Back of the transaction.
I still do not know what to do. :-(
Beside of this unfortunately I do not understand what MVC Exception Handling (#ExceptionHandler) has to do with this. There was a table of handled exceptions, but I did not find the HibernateException.
Or do you think it will work with this: #ExceptionHandler(HibernateException.classs)? also you said you would not recommend to handle exceptions this way.
I am developing a medium size Java Web Application with Struts as MVC framework and simple JDBC at Data Access Layer. I have been searching for exception handling best practices in such an application. I have found several articles, some of them being contradictory, only making me more confused rather than making things clear and simple. Some say it is better to reuse existing exceptions instead of defining application specific exceptions, others present a huge hierarchy of application specific exceptions for every minor trouble that may occur in the system. Some say it is better not to handle exceptions at Data Access Layer and delegate them to the Service Layer, others say Data Access Layer exceptions should be caught locally since delegating them to Service Layer would violate the abstraction between the two layers. And so on.
I would highly appreciate if you let me know of links/names to articles/books that present solid solutions which have worked for you in such a scenario. The solution should clear at least the following points with justifications:
Where the SQLExceptions be caught?
Where exceptions should be logged?
Should unchecked exceptions be logged?
Should unchecked exceptions be caught at presentation layer, and should they be shown to the user?
How checked exceptions be handled, which of them to be shown to the user and how?
How should a global exception handler page be used?
How should struts ActionErrors be used in this context?
Thanks
1: Where the SQLExceptions be caught?
In DAO classes in data access layer. You can if necessary wrap it with a custom DAO exception. This DAO exception in turn needs to be handled further as checked exception.
2: Where exceptions should be logged?
At the moment when you're about to throw them or to pass through the messaging framework.
3: Should unchecked exceptions be logged?
They should certainly be logged. They should namely not occur in real world, because those are sign of a fault in the code logic (i.e. developer fault) which needs to be bugfixed asap. They should be thrown all the way up to the container and let the container handle them with an <error-page> in web.xml. To log (and eventually mail) them, use a Filter which listens on the error page.
4: Should unchecked exceptions be caught at presentation layer, and should they be shown to the user?
They should not occur at all.
5: How checked exceptions be handled, which of them to be shown to the user and how?
If they are result of errorneous user input (e.g. not a number, bad email, constraint violation, etc), show them in the same form to the user. Otherwise (e.g. DB down, DAO exception and so on) either throw it all the way up to the error page, or display the error with a message to try again later.
6: How should a global exception handler page be used?
At least in an user-friendly manner. Thus, in the same layout, with some introductory "sorry" and if necessary with some error details and an email address so that the user can contact for the case that.
7: How should struts ActionErrors be used in this context?
Show them in same form to the user.
If you can't recover from an exception, then you should let it flow out of your code (often by making it unchecked, or wrapping it in an unchecked exception). If they remain checked, you have to cater for them at each level of your code, and consequently at every abstraction layer. SQLExceptions would normally fall into this category (you'll have to wrap them since they're checked).
For these exceptions, I normally log at the highest level, but present a page to the users simply detailing that something has gone wrong. Normally my users aren't interested in stack traces. But I usually offer them a page to let them describe what they were doing at the time, and the logged exception ties back to this submission via a unique id (recorded in the form and in the log file with the exception). That allows me to tie back users' actions to the resulting exception.
The above assumes that you can't recover from SQLExceptions, and if the database is down, then you can't do something meaningful. There are exceptions to this, of course. You may find that you're talking to multiple systems, and one being down doesn't mean you can't continue in some fashion (e.g. the Amazon home page reportedly relies on 100 services, and needs to run regardless of some of these being down).
I would expect declared exceptions to be at the same level of abstraction as the interface/methods defining them. e.g. a TradeStore would be declared to throw a TradeException, not a SQLException (since methods of storing a trade are an implementation of TradeStore - you could store in a relational db, a JavaSpace etc.).
As a warning, when displaying lower level error messages to users, make sure they're sanitized of system information. This is an area where many security exploits originate. Log them with full information, but only display a more general error message to the user.