From my DAO method I need to return a result (even if exception occured). I try to do it in such a manner by it doesn't work in case of exception(I have an exception: don't flush the Session after an exception occurs).
#Repository
#Transactional(rollbackFor=HibernateException.class)
public class UserDAO {
#Override
public boolean save(Proxy proxy) {
try{
sessionFactory.getCurrentSession().save(proxy);
}
catch(HibernateException e){
//TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
return true;
}
}
However when I uncomment //TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
all works like I expect. I know that documentation don't recommend to use this approach, but annotation rollback doesn't work for me. Can you explain, please, why? Can I modify the code to get it work, if it is possible?
Spring will rollback only if the exception is thrown by the method. If it's thrown and caught inside the method, Spring doesn't know anything about the exception, and thus considers that everything went fine, and thus doesn't rollback the transaction.
So, either keep the call to setRollbackOnly, or, much preferred, don't use boolean results to indicate that an operation succeeded or failed. An exception should be thrown if the save wasn't successful.
rollbackFor attribute works if annotated method throws specified exception. In your case exception is catched inside the method and is not propagated up so rollbackFor has no effect.
If you do need to return a value instead of throwing an exception to your caller, you do need to rely on setRollbackOnly(), which I don't think is bad, but pretty standard way.
Besides, I think throwing an exception is a better idea because your caller has no notion of what goes wrong when there is a 'false'. Otherwise, you might need to return an error code or error message or something more meaningful than a 'false'.
Related
In my service, have handled DataIntegrityViolationException when calling myCrudRepository.saveAndFlush to handle concurrent persist (insertion) requests. It works and I can catch the exception. After this, I prefer to make sure if the exception is exactly because entity already exists, not due to any other possible unknown issues. So, I call myCrudRepository.exists(entity.getId()) , but DataIntegrityViolationException is thrown again.
Here is my simple code:
private void save(final Employee entity) throws MyAppException {
try{
this.myCrudRepository.saveAndFlush(entity);
}catch (org.springframework.dao.DataIntegrityViolationException e){
// check if the error is really because the entity already exists
// entity.getId() is already generated before any save. it's like National ID
boolean exists = this.myCrudRepository.exists(entity.getId()); // DataIntegrityViolationException is thrown here again!
if (exists)
throw new MyAppException(HttpStatus.CONFLICT, "Entity already exists.");
else
throw e;
}
}
But if I use findOne instead of exists, it works fine. It's somehow strange, but of course it has a technical reason that I'm not good enough to make a guess.
Any idea? Thanks in advance.
The problem is when you are using Transactional method and after the method returns the transaction will auto commit and hibernate will wrap up the exceptions into another one. Actually the exception is occurring when transaction commits and at that time you are out of that method already. To catch the exception from inside the method you can simply use em.flush() after this.myCrudRepository.saveAndFlush(entity);.
I've just started my very first toy-project in java and faced with misunderstanding of how it should be done. I'm using java.util.logging and JUnit4 library.
For example we have something like this:
public class SomeClass {
private static Logger log = Logger.getLogger(SomeClass.class.getName());
public static void SomeMethod() {
try{
...some code...
} catch(Exception e){
log.warning("Something bad happened");
}
}
And the unit-test will be:
#Test
public void SomeClassTest(){
SomeClass.SomeMethod();
}
But there will never be an exception, cause I've already handled it in method.
Should I generate new exception in catch-block? Or may be using junit combined with logging is not a good idea?
A method that does not throw an exception (and returns the expected value if any) is meant to work correctly from the perspective of a user.
So you should use try - catch and logging inside a method, when you can catch an exception and the method will still work correctly (do something else when this error happens for example but still return the expected result or perform the supposed operation).
In this case the unit test should check if the operation was performed correctly (if the object is in the expected state and the result value (in your case void) is correct
You should rethrow the exception (and usually not log it, but that depends) if the method cannot do what it is supposed to do when the exception occurs.
In this case the unit test should check if the operation was performed correctly (if the object is in the expected state and the result value (in your case void) is correct if there is no exception, and if there is an exception it should check if this exception was expected
If you want to test that the exception is thrown then you would have to re-throw, or not catch, the Exception.
Otherwise you can unit test that the class is in the correct state after the exception, i.e. that the exception was correctly handled.
I would say one other thing. Don't catch(Exception e), catch the specific exception you are expecting. Otherwise you will handle other, unexpected, exceptions in the same way and that is really quite dangerous.
You can simply rethrow the caught exception:
public class SomeClass {
private static Logger log = Logger.getLogger(SomeClass.class.getName());
public static void SomeMethod() {
try {
// your stuff
} catch (Exception e) {
log.warning("Something happened");
throw e;
}
}
}
Should I generate new exception in catch-block?
No. don't do that! you can test your existing code! when you only want to log the message but you don't want to handle it in the method that call someMethod() don't throw it!
using junit combined with logging is not a good idea?
both are good ideas and can be used together without problems.
Think about how you can test your method. i would not modify the code just that you can easily test it. because you WANTED to catch the exception and log for a reason.
try verifing what variables or objects are modified in your test-method
I have a method with following signature
I want to log exception after catching by my point cut, rite now when i execute the code it throws the exception print on the console then comes to my point cut defined method, may be because it is #AfterThoring annotation but there is no #BeforeThrowing annotation available ? please suggest what can i do
public void jingleBell(){
System.out.println("Jingle Bell Job...");
throw new RuntimeException("test error");
}
and following advice with pointcut
#AfterThrowing(pointcut = "execution(* com.dc.lnwsk.adapter.Search.jingleBell())", throwing = "ex")
public void handleException(Throwable ex){
//Log exception
}
Exceptions are not like methods where bye code can be altered(weaved) to call a new method before calling the point cut method.
Exceptions are run time phenomenon and JVM doesn't know in advance that some exception is going to be thrown and hence no #BeforeThrowing.
if you know your exception scenario up-front then better use #Before on the point cut method and handle the exception scenario.
In the past I'd read tons of code with methods like:
public Object doSomething() throws Throwable {
...
}
Is it common practice to do that?
What are pros & cons?
throws Trowable seemed to me like the "Agent Orange" way of getting the Exception- matter done
EDIT
Handle expected Exceptions in the Method
Throw unexpected Exceptions (one by one)
Don't care of Errors
Is that the way to go?
You should not throw Throwable. Here's why.
Throwable is the top of the hierarchy of things that can be thrown and is made up of Exceptions and Errors. Since Errors by definition arise from unsalvagable conditions, it is pointless to include them in your method declaration. That leaves just Exception.
You should declare your method with throws Exception instead.
Note that the narrower the range of throws the better.
Declaring your method to be throws Exception is ok if your method doesn't generate the exceptions, but instead calls other code that is declared as throws Exception and you want exceptions to percolate up the call stack.
If your method is the generating the exception, then declare a narrower range, eg throws IOException, MyProcessingException, etc
That's a loaded question. This isn't so much about exception handling as it is about code readability.
It depends where you get your code samples from. Professionals prefer to be more specific when throwing out of a method. The main reason is that it keeps your APIs more readable. For example, if your method throws Throwable, that basically means anything could happen and your method doesn't want to deal with it, no matter what. But really, only a limited number of things could happen:
Whatever checked exceptions resulting from other calls you are making in your method
Whatever checked exceptions you are throwing on purpose based on your own assertions
Whatever unchecked exception you didn't plan for
Errors (java.lang.Error) that are more global to the JVM and the environment
By specifically stating the exceptions you want to throw, you are telling the users of your API about what they should beware of. For example, when you use InputStream, you'll notice most methods throw at least java.io.IOException, which gives you some useful information about what you should watch for.
When coding, as a general rule, you want to try to keep your APIs as expressive as possible. You've got essentially one line of code to show the public API of a method (i.e. its signature, annotations too I guess), so you want it completely expressive (return type, name, parameters, but also the thrown exceptions).
As far as catching the throwables and printing the stack trace, I'd say that you should not catch the exception unless you can do something about it. Instead, let it roll up the call stack until some class catches it to do something about it. Sometimes, it may roll all the way up to your main class, which I guess would have to catch it and print the stack trace as last resort. Basically, if you can't act upon the exception, then let it go up the call stack. Also it is extremely rare that you find yourself in a situation where you should silence an exception (i.e. catch it but do nothing about it). That's usually inviting problems when comes time to troubleshoot issues.
Here is a fun but interesting article around misuse of exception handling in general.
In some rare cases it is acceptable to throw Throwables. For example, #Around advices in Spring AOP are usually declared to throw a Throwable.
The following example is copied verbatim from Spring AOP docs:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;
#Aspect
public class AroundExample {
#Around("com.xyz.myapp.SystemArchitecture.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
// start stopwatch
Object retVal = pjp.proceed();
// stop stopwatch
return retVal;
}
}
Why is doBasicProfiling declared to throw a Throwable? Because the original method (i.e. the execution join point), might throw an Error, RuntimeException, or a checked exception. So it only makes sense to declare doBasicProfiling to throw a Throwable.
Functionally, it is equivalent with throws Exception, since errors are unchecked.
I see no reason to declare a method to throw Throwable. However, this doesn't mean that catch and printStackTrace is a good alternative.
Usually, you want to catch throwables where you can do something sensible with them.
Code that throws a throwable you don't expect should explode gloriously, so you can see the error and fix the bug.
Is it common practice to do that?
In the JDK it is rare. This is mostly used when it is not clear how to handle checked exceptions.
What are pros & cons?
The pros is that you get your code to compile without worrying about checked exception.s
The cons is that exception you should be handling are being ignored.
Isn't it better to catch and printStackTrace()?
Unhandled exception are usually printed anyway so catching them doesn't help much.
You should catch an exception when you can add some value by doing so and add the exception to the throws clause when you can't.
It is really debatable matter.
Having method throwing too many exceptions will result in lot of error handling code. Some times it is not intended.
But because I don't like too many exception in signature does not mean that Lets use Parent of all exceptions and we are done!! It will not work.
What one can do is categorise exceptions such as BusinessException,ServiceException so that if you have a business rule which says that minimum balance in account can not be less than say 100$ then InsufficientBalance exception will be generated which will be child of BusinessException
so you method will be like
public Object doSomething() throws BusinessException {
if(!hasMinimumbalance())
{
throw new InsufficientBalance(ErrorCode);
}
}
What this will do is club related exceptions together and whenever API user wants to detect exception specific error then he can do it, else generic error handling is possible.
The core point here is on the UI you should display to the user that You have run out of balance and you can not withdraw money
You can say on the larger aspect to display human readable form of error it is really necessary to have separation of exceptions.
Are you asking about Throwable specifically? If so, then it's not good practice. It doesn't provide any useful information to class (method) user.
Throwing (and catching) Throwable (or Exception) is generally bad practice because it 'blankets' any specific exceptions you might want to catch. Then you would have to resort to ugliness like below:
public void myMethod() throws Throwable {
if (x) {
throw new MyException1();
}
if (y) {
throw new MyException2();
}
}
public void callingMethod() {
try {
myMethod();
}
catch(Throwable t) {
if (t instanceof MyException1) {
// handle exception 1
}
else if (t instanceof MyException2) {
// handle exception 2
}
else {
// handle other exceptions
}
}
}
Which is error prone (and flagged by CheckStyle as a code violation). It is much preferrable to have code like this:
public void myMethod() throws MyException1, MyException2 {
if (x) {
throw new MyException1();
}
if (y) {
throw new MyException2();
}
}
public void callingMethod() {
try {
myMethod();
}
catch(MyException1 e) {
// handle exception 1
}
catch(MyException2 e) {
// handle exception 2
}
}
Handling an exception just by calling printStackTrace() is usually not a good idea. printStackTrace() sends the stacktrace to standard error, which may not be read at all. A better option is to use the application's logging facility (like log4j) to report the exception. Even then, just logging it might no be enough.
My rule of thumb is:
If you can handle an exception locally, do so. For example when parsing a String as an Integer you could catch the NumberFormatException and return a default value:
prvate int parseAmount(String amountValue) {
int amount;
try {
amount = Integer.parseInt(amountValue);
}
catch(NumberFormatException e) {
// default amount
amount = 0;
}
return amount;
}
If you cannot handle an exception locally, consider if you should expose the exception type that is being thrown. If this type is some obscure (implementation-dependent) type, then wrapping it in your own generic exception type is probably a good idea:
private Customer getCustomer(int customerId) throws ServiceException {
try {
return customerService.getCustomer(customerId);
}
catch(CustomerServiceSpaghettiTangledException e) {
throw new ServiceException("Error calling the customer service", e);
}
}
Here 'ServiceException' is a subclass of Exception created by you. Spring also offers an exception hierarchy specifically for this purpose.
By wrapping the exception you hide the implementation details, making your service layer much simpler to use.
If you decide to throw an exception from your method, you will need to handle it 'higher up' in the callstack. This can be a generic error page in your web application stating that something went wrong and possibly providing an error message or code. In some cases the higher level code can attempt a retry or possibly an alternative way to obtain the required result.
The only use case I can think of would be for test code like unit tests. But Adam's counterpoint still stands "If so, then it's not good practice. It doesn't provide any useful information to class (method) user."
I'm not sure of why this is happening, but I have a simple setup where a caller's return value is null.
I call a function which might throw registered exceptions. When it does, myXDSConsumerRequestHandler stays null. The problem is that I'm able to recover from the registered events (checked the object on the callee). So how do I call the retrieveDocuments and get my object back?
I understand the flow is broken when the exception is thrown, so should I be catching the exceptions at a higher level?
This is the caller:
try {
myXDSConsumerRequestHandler =
RetrieveDocSetUtil.retrieveDocuments(NIST, multipleRetrieveMap);
} catch (VerboseIllegalArgumentException e) {
} catch (XDSException e) {
}
This is the callee:
public static RetrieveDocumentSetImpl retrieveDocuments(
String repoURL, Map<String, String> docRepoMap)
throws VerboseIllegalArgumentException, XDSException {
RetrieveDocumentSetImpl myXDSConsumerRequestHandler =
new RetrieveDocumentSetImpl(repoURL);
myXDSConsumerRequestHandler.retrieveDocumentSet(docRepoMap);
return myXDSConsumerRequestHandler;
}
Thank you!
If retrieveDocuments() throws an exception then it never gets a chance to return something. The statement myXDSConsumerRequestHandler = RetrieveDocSetUtil.retrieveDocuments() does not finish normally.
It is not possible to both catch an exception from a method and receive the return value.
If retrieveDocuments() has something meaningful it can return to callers even when these exceptions are encountered, then this method should be catching exceptions internally and returning an appropriate return value rather than allowing the exception to propagate up to the calling method.
Your code is executed in the following order:
Call retrieveDocuments
Assign the result to myXDSConsumerRequestHandler
If an exception is thrown during step 1, step 2 will never happen.
In general, you cannot both throw an exception and return a value.
You problem comes from having a methid doing too much. It both obtains a RetrieveDocumentSetImpl and attempts to use it.
RetrieveDocumentSetImpl myXDSConsumerRequestHandler =
new RetrieveDocumentSetImpl(repoURL);
myXDSConsumerRequestHandler.retrieveDocumentSet(docRepoMap);
return myXDSConsumerRequestHandler;
Separate this into two methods:
RetrieveDocumentSetImpl myXDSConsumerRequestHandler =
new RetrieveDocumentSetImpl(repoURL);
return myXDSConsumerRequestHandler;
which either return a handler or fails, throwing an Exception, and
myXDSConsumerRequestHandler.retrieveDocumentSet(docRepoMap);
Then your caller can call the first method, grabbing the return code, and then if they so choose try various things such as cal the second, catching the indidual exceptions they throw.
Here are my suggestions
Add proper handling on public retrieveDocuments(NIST, multipleRetrieveMap) method to ensure that proper parameters are passed to your method. This will address exceptions specially related to VerboseIllegalArgumentException the parameter validation/handling should be done before you pass the paramters to the retrieveDocuments method. Im afraid that if you encounter an exception you can no longer retreive your object for the reason stated by the previous posters It is not possible to both catch an exception from a method and receive the return value. thats why proper validation and handling is very important.
After determining the cause of your exception, define/create your own exceptions. This will save you a lot of time and headache in the future.