-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 posts ] 
Author Message
 Post subject: to catch the Unique contraint violation Exception
PostPosted: Wed Jun 21, 2006 2:49 pm 
Newbie

Joined: Thu Jun 15, 2006 5:58 pm
Posts: 18
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version:

Mapping documents:

Code between sessionFactory.openSession() and session.close():

Full stack trace of any exception that occurs:

Name and version of the database you are using:

The generated SQL (show_sql=true):

Debug level Hibernate log excerpt:

Using Hibernate 3.1.3 backend - postgres 8.0

I have a column in my mapping set as
<property name="name" unique= "true"/>
When I run my java application and try to enter the same name again in my screen , I get a contraint violation exception

WARN - SQL Error: 0, SQLState: 23505
ERROR - ERROR: duplicate key violates unique constraint "tdat_product_unique"

ERROR - Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:202)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:333)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)


I get the exception in my console.I would like to catch the exception and rethrow the exception with nice comments to the user. But when I tried to get the SQLState in my code , it returns me a null value. Is there a way to rethrow my error.

Could some body help me on this.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 21, 2006 8:18 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
You're catching hibernate's ConstraintViolationException, but getSQLState() is returning null? Odd. What is getSQLException() returning? If that's not null, you can use getSQLException().getSQLState().

If that doesn't work, you could put a breakpoint in SQLStateConverter and see what's happening. You may have to extend your Dialect, if the SQLException is being thrown away due to being unparsable in some way.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 22, 2006 6:19 pm 
Newbie

Joined: Thu Jun 15, 2006 5:58 pm
Posts: 18
I tried e.getSQLException().getSQLState() but I am getting a null value. I am not clear on your second statement.could you please elaborate.

Could you tell me if there is a way to rethrow my error.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 22, 2006 6:26 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
If e.getSQLException() is not null, but e.getSQLException().getSQLState() is null, then there is no SQLState info being returned by your JDBC driver, so there's nothing that hibernate can do for you. The best you can hope for is to use getErrorCode(), or maybe even parse getMessage() (ick). I think you should just handle the possibility that getSQLState is null, and tell the user that "no additional information is available", or something like that.

You can ignore the other statement, as it would only help to enhance the ConstraintViolationException using the information in the SQLException. If there is no more information in the SQLException, then that idea won't help.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 22, 2006 6:54 pm 
Newbie

Joined: Thu Jun 15, 2006 5:58 pm
Posts: 18
Hibernate: select nextval ('tdat_product_product_id_seq')
Hibernate: insert into tdat_product (name, multi_ad, max_ad_units, deactivedate, last_modified_on , multiplier, product_id) values (?, ?, ?, ?, ?, ?, ?)
WARN - SQL Error: 0, SQLState: null
ERROR - Batch entry 0 insert into tdat_product (name, multi_ad, max_ad_units, deactivedate, last_modified_on , multiplier, product_id) values ( was aborted. Call getNextException() to see the cause.
WARN - SQL Error: 0, SQLState: 23505
ERROR - ERROR: duplicate key violates unique constraint "tdat_product_unique"

ERROR - Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update



I am able to see the SQLState : 23505 in the console.I am wondering why it returns me a null value when I read the SQLState.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 22, 2006 7:04 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
I'm guessing that one is because the driver has logged two SQLExceptions. The one with code 0, state null is the failed batch insert. The next one is the constraint violation. So in your exception-enhancing code, you'll need to iterate through all the exceptions. Note that some drivers chain the last exception to itself, so this is the code you need:
Code:
...
catch (ConstraintViolationException e)
{
  StringBuilder b = buildMessagePreamble();
  SQLException se = e.getSQLException();
  SQLException prevSe = null;
  while ((se != null) && (prevSe != se))
  {
    b.append(buildExceptionMessage(se));
    prevSe = se;
    se = se.getNextException();
  }
  throw new CustomizedException(b.toString(), e);
}

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 22, 2006 7:56 pm 
Newbie

Joined: Thu Jun 15, 2006 5:58 pm
Posts: 18
---


Last edited by user_hibernate on Thu Jun 22, 2006 8:00 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 22, 2006 7:57 pm 
Newbie

Joined: Thu Jun 15, 2006 5:58 pm
Posts: 18
Thanks for the information.
Here is my concern , in my xml mapping file I have
<property name="name" unique= "true"/> ,
which is to set unique constraint property.Do I still need to set the constraint in my database side too. As when I removed the unique constraint from my db and tried inserting the same name .the exception isnt caught and the value get inserted into my database. I was hoping that the unique constraint on my xml mapping should take care of this.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 22, 2006 7:58 pm 
Newbie

Joined: Thu Jun 15, 2006 5:58 pm
Posts: 18
--


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 22, 2006 8:12 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
The unique="true" thing on a property affects only schema creation tools (hbm2ddl). It adds the uniqueness constraint to the DB at schema creation time. It does not do any in-memory checking: if it did that, every row in the table would have to be loaded before any row could be updated or inserted. That's highly undesirable.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.