Home » Modeling » EMF » [CDO] Exception Handling on Commit
[CDO] Exception Handling on Commit [message #900378] |
Mon, 06 August 2012 13:52  |
Eclipse User |
|
|
|
Hello
I am setting up a rcp application based on CDO/Hibernate. I am currently working on fallback exception handling strategies on a commit. I have noticed that the CommitException does not include a cause (getCause() returns null). I assume that this is quite reasonable in many cases, since one does not have to worry about having obscure exceptions on the classpath that arrise from somewhere within the jdbc implementation.
On the other hand, I would like to create some default error messages based on exceptions that arrise from constraint violations (org.hibernate.exception.ConstraintViolationException). I could parse the message from the CommitException, which holds the exception stack trace, but I was wondering if there es a more elegant solution to this.
I have tried to set up an ExceptionHandler in the CDONet4jSessionConfiguration before the CDOSession is opened, but the handleException method doesn't get called. (I verified, that it is correctly set in the CDOSession with getExceptionHandler().)
So question #1 is: Should the ExceptionHandler be notified of commit exceptions? If not, when will this ExceptionHandler be used?
Question #2: Is it possible to hook into the server for exception handling? Maybe use custom exceptions with appropriate error messages for common constraint violations.
Thanks for the support!
Greetings
Christoph
|
|
|
Re: [CDO] Exception Handling on Commit [message #900428 is a reply to message #900378] |
Tue, 07 August 2012 01:26   |
Eclipse User |
|
|
|
Am 06.08.2012 19:52, schrieb Christoph Keimel:
> Hello
>
> I am setting up a rcp application based on CDO/Hibernate. I am currently working on fallback exception handling
> strategies on a commit. I have noticed that the CommitException does not include a cause (getCause() returns null).
That seems to be an "exception", not the general rule. How exactly does this exception look like, where is it being thrown?
> I assume that this is quite reasonable in many cases, since one does not have to worry about having obscure exceptions
> on the classpath that arrise from somewhere within the jdbc implementation.
I guess you're referring to the fact that some exception classes themselves are not on the classpatch of a client
application, only on the classpatch of the server deployment. Because the server can not know what classes are available
on the client (except those in net4j, net4j.util and cdo.common) all stacktraces are also transferred in String form to
the client. See RemoteExceptionRequest and RemoteExceptionIndication for details.
> On the other hand, I would like to create some default error messages based on exceptions that arrise from constraint
> violations (org.hibernate.exception.ConstraintViolationException). I could parse the message from the CommitException,
> which holds the exception stack trace, but I was wondering if there es a more elegant solution to this.
Didn't you say that, in your case, there is no cause/stacktrace available?
> I have tried to set up an ExceptionHandler in the CDONet4jSessionConfiguration before the CDOSession is opened, but
> the handleException method doesn't get called. (I verified, that it is correctly set in the CDOSession with
> getExceptionHandler().)
>
> So question #1 is: Should the ExceptionHandler be notified of commit exceptions?
No. CommitExceptions are special in that they are created on the client side from the rollbackMessage that is received
from the server in case of "failed" commits. In other words, non-transport commit problems are handled on
application-(protocol-)level.
> If not, when will this ExceptionHandler be used?
This handler is mostly used to intercept transport-level exceptions. The RecoveringCDOSessionImpl is an example:
private class RecoveringExceptionHandler implements ExceptionHandler
{
public void handleException(CDOSession session, int attempt, Exception exception) throws Exception
{
if (exception instanceof TransportException)
{
recover();
}
}
}
>
> Question #2: Is it possible to hook into the server for exception handling?
Not yet, I think.
> Maybe use custom exceptions with appropriate error messages for common constraint violations.
What problems would you define as "common"? Perhaps you can start with some examples?
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [CDO] Exception Handling on Commit [message #900508 is a reply to message #900378] |
Tue, 07 August 2012 06:41   |
Eclipse User |
|
|
|
I am most happy to abide ... thanks for taking the time to help.
Consider this model element (xcore):
class MyElement {
unique String name
String description
}
Which gets these persistence annotations (for Hibernate):
<eclass name="MyElement">
<eattribute name="name">
<column nullable="false" unique="true"/>
</eattribute>
</eclass>
The resulting database definition now has a table "myelement" with a column "name". The column "name" has a "not null" constraint as well as a "unique" constraint.
On the client I execute the following test (where IEmTracRepoService is a simple client interface to handle the setup of the CDOSession):
public void testNotNullConstraintViolation(IEmTracRepoService repo) {
// TODO Exception Handling bei Constraint-Violations
CDOTransaction transaction = repo.openTransaction();
try {
CDOResource resource = transaction.getOrCreateResource(repo.getResourceName());
MyElement element = EmTracFactory.eINSTANCE.createMyElement();
resource.getContents().add(element);
element.setDescription("Test Element without a Name");
transaction.commit();
} catch (CommitException e) {
logger.error("CommitException", e);
} finally {
transaction.close();
}
}
This throws a CommitException as expected, because the name has not been set. This is the stack trace which is logged (shortened):
12:16:41.090 ERROR d.e.e.a.h.TestNotNullConstraintViolation - CommitException
org.eclipse.emf.cdo.util.CommitException: Rollback in HibernateStore: org.hibernate.exception.ConstraintViolationException: Column 'name' cannot be null
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:75)
...
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'name' cannot be null
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
...
I would like to be able to get the originating message of the exeption, which is "Column 'name' cannot be null" in this specific case. "e.getMessage()" returns the full stack trace as a String. Since "e.getCause()" returns null it is not possible to walk the exception hierarchie.
If the client handles everything well, this situation will not happen, because everything has been checked before the commit is sent. But sometimes constraints get added later, or the check is simply forgotten and then the rdb constraints kick in. This is why I am talking about a "fall back exception handling". It would be nice to still be able to produce good error messages for the user.
It would be nice, if I could get the MySQLIntegrityConstraintViolationException as an object, because this also holds additional information (vender code, etc.)
Greetings
Christoph
|
|
|
Re: [CDO] Exception Handling on Commit [message #900572 is a reply to message #900508] |
Tue, 07 August 2012 11:07   |
Eclipse User |
|
|
|
Am 07.08.2012 12:41, schrieb Christoph Keimel:
> I am most happy to abide ... thanks for taking the time to help.
>
> Consider this model element (xcore):
> class MyElement {
> unique String name
What does "unique" mean here? I thought it's just meaningful for many-valued features.
> String description
> }
> Which gets these persistence annotations (for Hibernate):
> <eclass name="MyElement">
> <eattribute name="name">
> <column nullable="false" unique="true"/>
> </eattribute>
> </eclass>
> The resulting database definition now has a table "myelement" with a column "name". The column "name" has a "not null"
> constraint as well as a "unique" constraint.
>
> On the client I execute the following test (where IEmTracRepoService is a simple client interface to handle the setup
> of the CDOSession):
> public void testNotNullConstraintViolation(IEmTracRepoService repo) {
> // TODO Exception Handling bei Constraint-Violations
> CDOTransaction transaction = repo.openTransaction();
> try {
> CDOResource resource = transaction.getOrCreateResource(repo.getResourceName());
> MyElement element = EmTracFactory.eINSTANCE.createMyElement();
> resource.getContents().add(element);
> element.setDescription("Test Element without a Name");
> transaction.commit();
> } catch (CommitException e) {
> logger.error("CommitException", e);
> } finally {
> transaction.close();
> }
> }
> This throws a CommitException as expected, because the name has not been set. This is the stack trace which is logged
> (shortened):
> 12:16:41.090 ERROR d.e.e.a.h.TestNotNullConstraintViolation - CommitException
> org.eclipse.emf.cdo.util.CommitException: Rollback in HibernateStore:
> org.hibernate.exception.ConstraintViolationException: Column 'name' cannot be null
> at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:75)
> ..
> Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'name' cannot be null
> at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
> ..
>
> I would like to be able to get the originating message of the exeption, which is "Column 'name' cannot be null" in
> this specific case. "e.getMessage()" returns the full stack trace as a String. Since "e.getCause()" returns null it is
> not possible to walk the exception hierarchie.
>
> If the client handles everything well, this situation will not happen, because everything has been checked before the
> commit is sent. But sometimes constraints get added later, or the check is simply forgotten and then the rdb
> constraints kick in. This is why I am talking about a "fall back exception handling". It would be nice to still be
> able to produce good error messages for the user.
>
> It would be nice, if I could get the MySQLIntegrityConstraintViolationException as an object, because this also holds
> additional information (vender code, etc.)
Ah, you are willing to put the exception class(es) on the client's classpath! Then you should have no problems because
the org.eclipse.net4j bundle declares Eclipse-"BuddyPolicy: registered" exactly for this use case. Just put
"Eclipse-RegisterBuddy: org.eclipse.net4j" into the manifest of the bundle that contributes your exception classe(s).
Some more infos about buddy classloading:
http://rajakannappan.blogspot.de/2010/03/eclipse-classloading-and-buddy-policy.html
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
| | | | | | | | | |
Goto Forum:
Current Time: Sun Jul 27 02:30:25 EDT 2025
Powered by FUDForum. Page generated in 0.04621 seconds
|