EJB3 Getting Original JDBC Errors

I am using EJB3 on Glassfish using the default TopLink stability manager. In a Bean session, when a persistence manager executes a database exception, it marks a transaction rollback and throws an EJBException, which in turn wraps a RollbackException. Now I was expecting to get the original jdbc exception from the exception thrown from one of these exceptions, but that is not the case.

It is important that I throw the original exception, as I need to inform the users about the problems, and for this I need to analyze the SQL error codes.

Does anyone know if this information can be obtained from Toplink? Or is Hibernate possible?

Thanks,

+4
source share
4 answers

The only way I found what I want is to get the manager to write to db using manager.flush () and then catch a PersistenceException that throws. Then I can log the database error as I want and throw an EJBException to force a rollback. Leaving the container to make a flash seems to irrevocably lose any useful messages with TopLink.

+1
source

I had the same problem. I ended up using the AroundInvoke hook method, so you can catch any exception on the server side and extract any information you want and wrap it to throw your own exception and set EjbContext to roll back the transaction.

I can provide you with an example if you do not come.

+3
source

Good question, Ant

I know that you want to throw a database exception, but when this happens, the application in most cases cannot restore its initial state or does not know how to restore it. Thus, this should be handled as a runtime exception . Some problems in database exceptions include

  • Error connecting to database
  • invalid request
  • table or column does not exist

You see that the application cannot restore its initial state. If you consider it possible to restore the original state , to use the application exception . The client will receive the same exception for the application created by your business method. If you want to get the exact exception thrown by your business method, you have two options:

  • Use the business delegate template to access EJB

As you know, a runtime exception is wrapped with an EJBException, so you can use something like

Suppose you have this bean-free session

@Stateless public class BeanImpl implements Bean { public void doSomething() { try { // some code } catch(SomeException e) { throw new EJBException(e); } } } 

So you end the bean session through the business delegate

 public class BeamBusinessDelegate implements Bean { // your stateless session bean goes here private Bean bean; public BeamImpl() { InitialContext i = new InitialContext(); bean = (Bean) i.lookup(<GLOBAL_JNDI_ADDRESS_OR_RELATIVE_ENVIRONMENT_NAMING_CONTEXT_ADDRESS>); } public void doSomething() { try { bean.doSomething() } catch(EJBException e) { throw e.getCause(); } } } 

Or you can extend an EJBException to suit your needs

 public class DatabaseException extends EJBException { } 

So, in your business method

 @Stateless public class BeanImpl implements Bean { public void doSomething() { try { // some code } catch(SomeException e) { throw new DatabaseException(); } } } 

Yours faithfully,

+1
source

I have the same question: how to get SQL error message generated from JPA?

I did not find a solution either, but added this line to my persistence.xml

  <properties> <property name="toplink.logging.level" value="FINE" /> </properties> 

and now I can see how sql commands came out.

Link: http://www.jairrillo.com/blog/2008/09/04/introduction-to-jpa-part-1-getting-started/

+1
source

All Articles