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.
Related
I am having a hard time organizing how I should deal with errors that occur in the service layer. The reason for throwing that exception in this method is when the password provided is to weak or the confirmation id is wrong. The name of the exception is not settled yet though.
However, are checked exceptions to be avoided in a new application anyway? If so, how do I communicate errors like this to the caller? The caller in this scenario is the web layer which exposes a web service. I want to handle the error in the web layer and create a error message.
I have a method:
boolean confirmPasswordReset(int accountId, String confirmationId, String newPassword) throws ConstraintViolation;
And this is the exception class:
public class ConstraintViolation extends Exception {
public ConstraintViolation(String message) {
super(message);
}
}
From reading this article it looks like it should be right:
http://www.oracle.com/technetwork/articles/entarch/effective-exceptions-092345.html
Contingency
Is considered to be: A part of the design
Is expected to happen: Regularly but rarely
Who cares about it: The upstream code that invokes the method Examples: Alternative return modes
Best Mapping: A checked exception
I try to use checked exceptions as little as possible. I think using a runtime exception and documenting it clearly is enough.
From your case, you seem to be the one designing and controlling the web layer. In that case, you already know what runtime exceptions your service layer throws and how to handle them. You don't need to be told by the compiler.
I would only use a checked exception if the exception is recoverable, and the client of the code is external where I have to force it to handle the exception. Even then, the result will most likely be one more empty catch block.
Here you can find a good discussion of the pro's and con's of both approaches.
http://tutorials.jenkov.com/java-exception-handling/checked-or-unchecked-exceptions.html
What I think is important (similiar to the author of article above) is that you choose which way to go (checked or unchecked) and then stay consistent. Otherwise you'll end up with a messy codebase and will likely suffer from the downsides of both approaches.
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).
I'm using Hibernate and Spring and I'm currently stuck with something which I thought would be very simple to fix. I have a service method similar to this:
#Transactional
public void deleteObject(ObjectClass object)
{
this.objectClassDAO.delete(object);
}
I need to display a friendly message when the user tries to delete an object which is related to another entity. The problem I have is that the ConstraintViolationException is thrown until commit() is called, which runs outside of the scope of my service method. Is there a way to let spring call some intermediate code in the event of a particular exception, so that I can set the proper error message?
I've been searching on google for over an hour with no luck. The approaches I've found that seem at least mildly related seem like overkill and like they run at application level. Is there a simple way to intercept an exception after a commit at method-level?
You're probably using FlushMode.AUTO and the exception is being thrown when the transaction ends (in the proxy around your service created by Spring). You can explicitly call Session.flush() inside of the objectClassDAO.delete() method. You typically don't want to do this, but in this case it will force a synchronization with the underlying persistence and if there is a constraint violation the exception will be thrown before objectClassDAO.delete returns. This may be a last resort though.
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.
I know we can declare the exception for our method if we want it to be handled by the calling method. This will even allow us to do stuff like write to the OutputStream without wrapping the code in try/catch block if the enclosing method throws IOException.
My question is: Can anyone provide an instance where this is usually done where you'd like the calling method to handle the exception instead of the current method?
Edit: I meant calling method instead of super class in the last line.
In general, I would say design your exception flow so that the exception is caught by the code that can actually take appropriate action.
This usually means that in a "library" method (or, some kind of general utility method in a large project), you will be throwing exceptions not catching them.
On the other hand, if you have a situation where you find yourself declaring your method to throw an exception that you believe in practice will hardly ever occur (e.g. serialisation generally involves all sorts of spurious checked exceptions which in practice won't occur, e.g. if you're deserialising an Integer, it's really unlikely that the Integer class is not present, but you still have to catch the appropriate exception), then you have a third option of re-casting to a RuntimeException.
I guess by "super class" you mean the code that called your method.
If you expect the caller to know more about the problem compared to your method, than you can pass this responsibility up the calling stack.
In general, if you do not know how to handle the problem, don't. Ether pass it or wrap it in another exception.
If you can't handle the error at the point in a sensible way (e.g. displaying error message, taking an alternative path, etcetera), then just let it bubble up.
If you want the error to be handled at a different level of the application.
Here's a semi-concrete example. Let's say I've got a web application which is implemented as a series of states and actions. Suppose that, while a state is being processed, a database access causes an SQLException to be thrown. This would not happen during the normal operation of my application; it would only happen if there were something wrong with the database.
The method that access the database doesn't need to know what my procedure for handling semi-fatal errors like this is. That logic implemented at a higher level — in the method that processes the state — and it's essentially the same for any runtime error, whether it's literally a RuntimeException or not: spit out a nice-looking error message to the user telling them to contact tech support.
Imagine if I had to add a try/catch block performing this logic to every method that accessed the database and could possibly throw an SQLException. That's what's called a nightmare.
I have used expections to as part of transferring information between architectural layers of application.
For Example:
if the DAO (Database Access Layer) gets a SQLException it throws a customized DAOLayerException which is caught by the businesslayer which in turn throws an exception which is caught by the presentation layer.
This was for unchecked exceptions.
I usually follow the practice of throwing checked unchecked exceptions (not handling them) if the function is to be used by numerous caller or are unknown at the time of development of the function.
In web frameworks (like spring) you often let errors propagate and container will deal with them (by showing error page or message to the user, rolling back transaction, etc).
Also, there are lots of java errors you never catch, like OutOfMemoryError. You can catch them, but you can't deal with them properly.
You asked for an example, and here is a common one.
If you are writing code to read a particular file format, these normally declare IOException. The reason for this is that it might be used by a desktop app (which wants to put up a dialog box) or a text utility (which wants to write an error message) or a web app (which wants to return an error code). Exception handling allows you to do that.
Yes, I would declare it so it propagates up until a parent calling method which would actually handle it (display on UI, break there, ..)
For Instance, I may have some helper methods in a sendEmail method. If a helper method say checkEmailAddress() produced an exception, I would want sendEmail to know about it, which can further propagate it up or do an alert on UI "email is wrong"