• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Exception handling in EJB with Container Managed Transaction using Hibernate

 
Selvakumar Kumarasamy
Greenhorn
Posts: 18
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I am using EJB with transaction-type specified as "Container" in ejb-jar.xml. I am also using Hibernate for DB operations. Code in my DAO lokks something like the following.

EntityManger entityManager = getEntityManager(); // this line will get the appropriate entity manager from EntityManagerFactory.
try {
enttyManager.merge(obj);
} catch (exception e) {
e.printStacktrace(); // never comes here when the exception occurs
} finally {
entityManger.close();
}

Whenever the update operation fails due to valid reasons, all the stacktraces are printed and even the transaction is rollbacked as required. But never comes in to catch block in my code. Hibernate itself is handling all the exception I hope. I would like to handle those exception in my code and I wolud like to provide appropriate customized error message to the user. How shall I handle.

Please help me.
 
Vesa Tanhua-Tyrkk´┐Ż
Greenhorn
Posts: 25
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

What kind of exceptions you get?
According to javadoc merge seems to throw following exceptions:
IllegalStateException, IllegalArgumentException and TransactionRequiredException
 
Selvakumar Kumarasamy
Greenhorn
Posts: 18
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am getting org.hibernate.exception.GenericJDBCException with appropriate SQL Exeption. If I use Bean Managed Transaction I am able to handle the exception when I try to commit the transaction. In Container Managed Transaction since commit is done by Container, until commit we will not get this exception and not able to handle the same.

If you have any idea on how to catch the exception which arises when Container is commiting the transaction, please share.
[ February 06, 2008: Message edited by: Selvakumar Kumarasamy ]
 
Paul Sturrock
Bartender
Posts: 10336
Eclipse IDE Hibernate Java
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

try {
enttyManager.merge(obj);
} catch (exception e) {
e.printStacktrace(); // never comes here when the exception occurs

What you are suggesting is impossible, assuming you are actually catching Exception, and the line enttyManager.merge(obj) is where the exception is being thrown. Nothing to do with CMT or Hibernate, thats just how Java works.

What exception is causing the transaction to be rolled back? I'm assuming its probably some sort of RuntimeException, since you say you don't handle the execption from the CMT call and the transaction is actually being rolled back.
 
Selvakumar Kumarasamy
Greenhorn
Posts: 18
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think I need to explain the problem little more.

In BMT code will look like this.

Entitytransaction entityTransaction = gettransaction();
try {
entityTransaction.begin();
entiryManager.merge(obj);
entityTransaction.commit();
} catch(Exception e) {
entityTransaction.rolback();
}

Since we are calling commit() method, the exception is thrown while executing the entityTransaction.commit(); statement.

But in case of CMT we will not commit the transaction programmatically, rather Container will commit the transaction at the end. That means, entiryManager.merge() will not commit the changes until commit() is called.
Even in the EJB the method will be succesful and won't get inside catch block. After the EJBs business method is over, Container is trying to commit the transaction which is not in our scope. I would like to handle the exception when the container is trying to commit.
[ February 06, 2008: Message edited by: Selvakumar Kumarasamy ]
 
Paul Sturrock
Bartender
Posts: 10336
Eclipse IDE Hibernate Java
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

But in case of CMT we will not commit the transaction programmatically, rather Container will commit the transaction at the end. That means, entiryManager.merge() will not commit the changes until commit() is called.

Yes. But since you have wrapped your method call in a CMT this is presumably what you want? Why use CMT and try to commit early, as it were? It will have no effect, since the transaction will only really commit when the CMT commits.


Even in the EJB the method will be succesful and won't get inside catch block. After the EJBs business method is over, Container is trying to commit the transaction which is not in our scope.

By default you will be using JDBC transactions, which (since they are run in a CMT) will commit when the transaction commits. That is, unless you have specified a different transaction manager lookup class for Hibernate to use? In CMT your try catch block needs to be round your business method call, and you need to explicitly call setRollbackOnly() when the method fails with an application exception.


I would like to handle the exception when the container is trying to commit

Well, that means you would need to use BMT, not CMT.
 
Stijn de Witt
Greenhorn
Posts: 3
  • 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I realize this post is quite old, but it scores high in Google for searches on CJB commit exceptions (in fact that's how I got here) and I think I have a more satisfactory answer than the current ones, so here goes.

CMT is convenient but some exceptions you definitely will want to handle at the application level, such as Unique Constraint violations. Fortunately, there is a way. The trick seems to be using two beans. Call one bean from the other so that CMT commits the transaction after the bean call returns and then wrap this bean call in a try catch block.

So your old code looked like this:



Now just add a second bean:



In this example I use container injection of the SomeBean, but you should be able to use the same with a manual lookup.
 
Helmut Neubauer
Greenhorn
Posts: 6
Java
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Sturrock wrote:

try {
enttyManager.merge(obj);
} catch (exception e) {
e.printStacktrace(); // never comes here when the exception occurs

What you are suggesting is impossible, assuming you are actually catching Exception, and the line enttyManager.merge(obj) is where the exception is being thrown. Nothing to do with CMT or Hibernate, thats just how Java works.


I know this post is quite old, but while looking around I come across it and wonder about the quoted answer. Normally the catch clause should work if the exception is thrown in merge(obj). It has something to do with CMT respectively whith transactions or not? The mentioned SQL Exception isn't caught because it is thrown during commit and not while calling merge. But if merge throws an IllegalArgumentException because obj isn't an entity, the catch will work or am I wrong? Perhaps someone can clarify things for me?


 
Helmut Neubauer
Greenhorn
Posts: 6
Java
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
By the way it should be also possible to handle this scenario with one bean:



I didn't try it, but it should work. But I'm not sure if a BMT Bean will work better and look nicer.
 
I agree. Here's the link: http://aspose.com/file-tools
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic