001/*
002 * Copyright 2002-2012 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.transaction;
018
019import org.springframework.util.Assert;
020
021/**
022 * Exception thrown when a general transaction system error is encountered,
023 * like on commit or rollback.
024 *
025 * @author Juergen Hoeller
026 * @since 24.03.2003
027 */
028@SuppressWarnings("serial")
029public class TransactionSystemException extends TransactionException {
030
031        private Throwable applicationException;
032
033
034        /**
035         * Constructor for TransactionSystemException.
036         * @param msg the detail message
037         */
038        public TransactionSystemException(String msg) {
039                super(msg);
040        }
041
042        /**
043         * Constructor for TransactionSystemException.
044         * @param msg the detail message
045         * @param cause the root cause from the transaction API in use
046         */
047        public TransactionSystemException(String msg, Throwable cause) {
048                super(msg, cause);
049        }
050
051
052        /**
053         * Set an application exception that was thrown before this transaction exception,
054         * preserving the original exception despite the overriding TransactionSystemException.
055         * @param ex the application exception
056         * @throws IllegalStateException if this TransactionSystemException already holds an
057         * application exception
058         */
059        public void initApplicationException(Throwable ex) {
060                Assert.notNull(ex, "Application exception must not be null");
061                if (this.applicationException != null) {
062                        throw new IllegalStateException("Already holding an application exception: " + this.applicationException);
063                }
064                this.applicationException = ex;
065        }
066
067        /**
068         * Return the application exception that was thrown before this transaction exception,
069         * if any.
070         * @return the application exception, or {@code null} if none set
071         */
072        public final Throwable getApplicationException() {
073                return this.applicationException;
074        }
075
076        /**
077         * Return the exception that was the first to be thrown within the failed transaction:
078         * i.e. the application exception, if any, or the TransactionSystemException's own cause.
079         * @return the original exception, or {@code null} if there was none
080         */
081        public Throwable getOriginalException() {
082                return (this.applicationException != null ? this.applicationException : getCause());
083        }
084
085        @Override
086        public boolean contains(Class<?> exType) {
087                return super.contains(exType) || (exType != null && exType.isInstance(this.applicationException));
088        }
089
090}