-->
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.  [ 3 posts ] 
Author Message
 Post subject: How to obtain cause of ConstraintViolationException?
PostPosted: Mon Jul 13, 2009 6:31 pm 
Newbie

Joined: Tue Jun 02, 2009 12:35 am
Posts: 4
I have a web form which allows users to edit some data. Some of the fields have unique constraints. I'd like to be able to detect which constraint has been violated so I can advise the user. The web form is part of a struts app running in JBOSS. I can catch the RunTimeException and check that the cause is the ConstraintViolationException. The getMessage() method is unhelpful (Could not execute JDBC batch update). The getConstraintName() method returns null.
However I can see in the Eclipse console:
10:13:13,968 ERROR [JDBCExceptionReporter] ERROR: duplicate key violates unique constraint "sitenumber_idx".
So the useful information is there, somewhere. How do I get to it?


Top
 Profile  
 
 Post subject: Re: How to obtain cause of ConstraintViolationException?
PostPosted: Thu Sep 17, 2009 3:27 am 
Newbie

Joined: Wed Feb 18, 2009 11:44 am
Posts: 3
Quote:
I'd like to be able to detect which constraint has been violated so I can advise the user....The getMessage() method is unhelpful...The getConstraintName() method returns null

i have the same problem...how to find out the violated constraint?
did you find any solution?


Top
 Profile  
 
 Post subject: Re: How to obtain cause of ConstraintViolationException?
PostPosted: Thu Sep 17, 2009 5:07 pm 
Newbie

Joined: Tue Jun 02, 2009 12:35 am
Posts: 4
Yes, I found a solution, but the annoying thing is that is doesn't work the same all the time. I have both seam and struts apps that needed this and you have to tweak the while loop in the getViolatedConstraintName(). Also I am doing this for postgres. Your milage will vary for other db's I am sure

Code:
import org.hibernate.exception.ConstraintViolationException;
import org.postgresql.util.PSQLException;

/**
*
* @author turekg
*/
public class ExceptionUtils {
 
  /**
   * Gets the name of the violated constraint. Note call hierarchy is different than Struts' !
   *
   * @param ex RuntimeException
   * @return constraint name
   *
   */
  public static String getViolatedConstraintName(Throwable t) {
    Throwable cause = t;
    while (cause != null) {
      if (cause instanceof PSQLException) {
       break;
      }
      cause = cause.getCause();
    }

    //We are now dealing with a ConstraintViolationException
    PSQLException psqlException =  (PSQLException) cause;
   
    int sqlState = Integer.valueOf(psqlException.getSQLState()).intValue();
    switch (sqlState) {
      // CHECK VIOLATION
      case 23514: return extractUsingTemplate("violates check constraint \"","\"", psqlException.getMessage());
      // UNIQUE VIOLATION
      case 23505: return extractUsingTemplate("violates unique constraint \"","\"", psqlException.getMessage());
      // FOREIGN KEY VIOLATION
      case 23503: return extractUsingTemplate("violates foreign key constraint \"","\"", psqlException.getMessage());
      // NOT NULL VIOLATION
      case 23502: return extractUsingTemplate("null value in column \"","\" violates not-null constraint", psqlException.getMessage());
      // TODO: RESTRICT VIOLATION
      case 23001: return null;
      // ALL OTHER
      default: return null;
    }
  }
 
  public static boolean isViolatedConstraint(Throwable t) {
    Throwable cause = t;
    while (cause != null) {
      if (cause instanceof ConstraintViolationException) {
        return true;
      }
      cause = cause.getCause();
    }
   
    return false;
  }
 
      /**
   * Extracts the constraint name based on a template (i.e.,
   * <i>templateStart</i><b>constraintName</b><i>templateEnd</i>).
   *
   * @param templateStart
   *          The pattern denoting the start of the constraint name within the
   *          message.
   * @param templateEnd
   *          The pattern denoting the end of the constraint name within the
   *          message.
   * @param message
   *          The templated error message containing the constraint name.
   * @return The found constraint name, or null.
   */
  private static String extractUsingTemplate(String templateStart, String templateEnd, String message) {
    int templateStartPosition = message.indexOf(templateStart);
    if (templateStartPosition < 0) {
      return null;
    }

    int start = templateStartPosition + templateStart.length();
    int end = message.indexOf(templateEnd, start);
    if (end < 0) {
      end = message.length();
    }

    return message.substring(start, end);
  }
}



Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 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.