001/*
002 * Copyright 2002-2018 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.orm;
018
019import org.springframework.dao.OptimisticLockingFailureException;
020import org.springframework.lang.Nullable;
021
022/**
023 * Exception thrown on an optimistic locking violation for a mapped object.
024 * Provides information about the persistent class and the identifier.
025 *
026 * @author Juergen Hoeller
027 * @since 13.10.2003
028 */
029@SuppressWarnings("serial")
030public class ObjectOptimisticLockingFailureException extends OptimisticLockingFailureException {
031
032        @Nullable
033        private final Object persistentClass;
034
035        @Nullable
036        private final Object identifier;
037
038
039        /**
040         * Create a general ObjectOptimisticLockingFailureException with the given message,
041         * without any information on the affected object.
042         * @param msg the detail message
043         * @param cause the source exception
044         */
045        public ObjectOptimisticLockingFailureException(String msg, Throwable cause) {
046                super(msg, cause);
047                this.persistentClass = null;
048                this.identifier = null;
049        }
050
051        /**
052         * Create a new ObjectOptimisticLockingFailureException for the given object,
053         * with the default "optimistic locking failed" message.
054         * @param persistentClass the persistent class
055         * @param identifier the ID of the object for which the locking failed
056         */
057        public ObjectOptimisticLockingFailureException(Class<?> persistentClass, Object identifier) {
058                this(persistentClass, identifier, null);
059        }
060
061        /**
062         * Create a new ObjectOptimisticLockingFailureException for the given object,
063         * with the default "optimistic locking failed" message.
064         * @param persistentClass the persistent class
065         * @param identifier the ID of the object for which the locking failed
066         * @param cause the source exception
067         */
068        public ObjectOptimisticLockingFailureException(
069                        Class<?> persistentClass, Object identifier, @Nullable Throwable cause) {
070
071                this(persistentClass, identifier,
072                                "Object of class [" + persistentClass.getName() + "] with identifier [" + identifier +
073                                "]: optimistic locking failed", cause);
074        }
075
076        /**
077         * Create a new ObjectOptimisticLockingFailureException for the given object,
078         * with the given explicit message.
079         * @param persistentClass the persistent class
080         * @param identifier the ID of the object for which the locking failed
081         * @param msg the detail message
082         * @param cause the source exception
083         */
084        public ObjectOptimisticLockingFailureException(
085                        Class<?> persistentClass, Object identifier, String msg, @Nullable Throwable cause) {
086
087                super(msg, cause);
088                this.persistentClass = persistentClass;
089                this.identifier = identifier;
090        }
091
092        /**
093         * Create a new ObjectOptimisticLockingFailureException for the given object,
094         * with the default "optimistic locking failed" message.
095         * @param persistentClassName the name of the persistent class
096         * @param identifier the ID of the object for which the locking failed
097         */
098        public ObjectOptimisticLockingFailureException(String persistentClassName, Object identifier) {
099                this(persistentClassName, identifier, null);
100        }
101
102        /**
103         * Create a new ObjectOptimisticLockingFailureException for the given object,
104         * with the default "optimistic locking failed" message.
105         * @param persistentClassName the name of the persistent class
106         * @param identifier the ID of the object for which the locking failed
107         * @param cause the source exception
108         */
109        public ObjectOptimisticLockingFailureException(
110                        String persistentClassName, Object identifier, @Nullable Throwable cause) {
111
112                this(persistentClassName, identifier,
113                                "Object of class [" + persistentClassName + "] with identifier [" + identifier +
114                                "]: optimistic locking failed", cause);
115        }
116
117        /**
118         * Create a new ObjectOptimisticLockingFailureException for the given object,
119         * with the given explicit message.
120         * @param persistentClassName the name of the persistent class
121         * @param identifier the ID of the object for which the locking failed
122         * @param msg the detail message
123         * @param cause the source exception
124         */
125        public ObjectOptimisticLockingFailureException(
126                        String persistentClassName, Object identifier, String msg, @Nullable Throwable cause) {
127
128                super(msg, cause);
129                this.persistentClass = persistentClassName;
130                this.identifier = identifier;
131        }
132
133
134        /**
135         * Return the persistent class of the object for which the locking failed.
136         * If no Class was specified, this method returns null.
137         */
138        @Nullable
139        public Class<?> getPersistentClass() {
140                return (this.persistentClass instanceof Class ? (Class<?>) this.persistentClass : null);
141        }
142
143        /**
144         * Return the name of the persistent class of the object for which the locking failed.
145         * Will work for both Class objects and String names.
146         */
147        @Nullable
148        public String getPersistentClassName() {
149                if (this.persistentClass instanceof Class) {
150                        return ((Class<?>) this.persistentClass).getName();
151                }
152                return (this.persistentClass != null ? this.persistentClass.toString() : null);
153        }
154
155        /**
156         * Return the identifier of the object for which the locking failed.
157         */
158        @Nullable
159        public Object getIdentifier() {
160                return this.identifier;
161        }
162
163}