One solution is to use a custom translation defined in sql-error-codes.xml. First create your own exception class that is a sub class of DataAccessException.
Code:
import org.springframework.dao.DataIntegrityViolationException;
public class UniqueConstraintException extends DataIntegrityViolationException {
public UniqueConstraintException(String msg) {
super(msg);
}
public UniqueConstraintException(String msg, Throwable ex) {
super(msg, ex);
}
}
Then make a copy of sql-error-codes.xml and modify it to fit your needs. Add a "customTranslations" entry for your custom exceptions class. This modified version of sql-error-codes.xml must be placed on the classpath to get picked up.
Code:
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="Oracle" class="org.springframework.jdbc.support.SQLErrorCodes">
<property name="badSqlGrammarCodes"><value>900,903,904,917,936,942,17006</value></property>
<property name="dataIntegrityViolationCodes"><value>1400,1722,2291</value></property>
<property name="cannotAcquireLockCodes"><value>54</value></property>
<property name="customTranslations">
<list>
<bean class="org.springframework.jdbc.support.CustomSQLErrorCodesTranslation">
<property name="errorCodes"><value>1</value></property>
<property name="exceptionClass"><value>UniqueConstraintException</value></property>
</bean>
</list>
</property>
</bean>
</beans>
Now you can catch this custom exception and handle it or throw an application exception.
For PostgreSQL - they do provide error codes starting with version 7.4.