/** * Copyright (c) 2009 - 2012 Red Hat, Inc. * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package org.candlepin.util; import org.hibernate.StaleStateException; import org.hibernate.exception.ConstraintViolationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.persistence.OptimisticLockException; import javax.persistence.PersistenceException; import javax.persistence.RollbackException; /** * This utility class allows to determine what an exception thrown by Hibernate or * SQL driver means. * * One situation where this is useful is detection of constraint violations. * It's much easier to catch constraint violation (possibly caused by * concurrent requests) than to utilize pessimistic locking. * * @author fnguyen */ public class RdbmsExceptionTranslator { private static Logger log = LoggerFactory.getLogger(RdbmsExceptionTranslator.class); /** * Decides if the sqlException was thrown because of the update/delete statement * had no effect in the database * * @param sqlException the exception thrown by Hibernate (RDMBs Driver) * @return true if the SQL exception meets the criteria */ public boolean isUpdateHadNoEffectException(RollbackException sqlException) { log.debug("Translating {}", sqlException); if (sqlException.getCause() != null && sqlException.getCause() instanceof OptimisticLockException) { Exception e = (OptimisticLockException) sqlException.getCause(); if (e.getCause() != null && e.getCause() instanceof StaleStateException) { return true; } } return false; } public boolean isConstraintViolationDuplicateEntry(PersistenceException pe) { log.debug("Translating {}", pe); if (pe.getCause() != null && pe.getCause() instanceof ConstraintViolationException) { ConstraintViolationException cve = (ConstraintViolationException) pe.getCause(); log.info("ConstraintViolationException error code:" + cve.getErrorCode()); //MySQL error code ER_DUP_ENTRY //http://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html if (cve.getSQLState() != null && cve.getSQLState().equals("23000") && cve.getErrorCode() == 1062) { return true; } //Postgres error code DUPLICATE OBJECT //https://www.postgresql.org/docs/8.3/static/errcodes-appendix.html if (cve.getSQLState() != null && cve.getSQLState().equals("23505")) { return true; } //TODO add Oracle } return false; } }