package hirondelle.web4j.database;

/**
 Thrown when a uniqueness problem occurs in the datastore
 during an <tt>ADD</tt> or <tt>CHANGE</tt> operation.

 <P>This type of exception is singled out since it is so common. It allows 
 {@link hirondelle.web4j.action.Action}s to catch this specific kind of exception.

 <P>For relational databases, this exception should be thrown for <tt>INSERT</tt>
 and <tt>UPDATE</tt> operations which may violate a <tt>UNIQUE</tt> or 
 <tt>PRIMARY KEY</tt> constraint, or similar item.
 {@link Db}, {@link DbTx}, and {@link TxTemplate} will throw a <tt>DuplicateException</tt> 
 exception for {@link java.sql.SQLException}s having an error code matching the 
 <tt>ErrorCodeForDuplicateKey</tt> configured in <tt>web.xml</tt>. 
 See <tt>web.xml</tt> for more information.

 <h3>Typical Use Case</h3>
 Here, an {@link hirondelle.web4j.action.Action} is calling a DAO method which may throw 
 a <tt>DuplicateException</tt>: 
<PRE>
private void addSomething throws DAOException {
  //this try..catch is needed only if the operation 
  //can have a duplicate problem
  try {
    dao.addSomething();
  }
  catch (DuplicateException ex){
    addError("Cannot add. That item already exists.");
  }
}
</PRE>
 <P>Note that if the operation cannot have a duplicate problem, then the <tt>Action</tt>
 should not attempt to catch <tt>DuplicateException</tt>. 
<P>
 Here is the DAO operation which may have a duplicate problem. 
<PRE>
//It is highly recommended, but optional, to declare 
//DuplicateException in this method header, to bring 
//it to the attention of the caller
public addSomething() throws DAOException, DuplicateException {
  //...elided
}
</PRE>
 Again, if the operation cannot have a duplicate problem, then the DAO should not 
 declare a <tt>DuplicateException</tt> in its throws clause.
 
 <P>The {@link Db#add(SqlId, Object[])} and {@link Db#edit(SqlId, Object[])} methods can throw a 
 <tt>DuplicateException</tt>.
*/
public final class DuplicateException extends DAOException {

  /**
   Constructor.
   
   <P>Arguments are passed to {@link DAOException#DAOException(String, Throwable)}.
  */
  public DuplicateException(String aMessage, Throwable aRootCause) {
    super(aMessage, aRootCause);
  }
  
}
