View Javadoc
1   /*
2    * Copyright 2002-2012 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.jdbc.support;
18  
19  import javax.sql.DataSource;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  
24  import org.springframework.beans.factory.InitializingBean;
25  
26  /**
27   * Base class for {@link org.springframework.jdbc.core.JdbcTemplate} and
28   * other JDBC-accessing DAO helpers, defining common properties such as
29   * DataSource and exception translator.
30   *
31   * <p>Not intended to be used directly.
32   * See {@link org.springframework.jdbc.core.JdbcTemplate}.
33   *
34   * @author Juergen Hoeller
35   * @since 28.11.2003
36   * @see org.springframework.jdbc.core.JdbcTemplate
37   */
38  public abstract class JdbcAccessor implements InitializingBean {
39  
40  	/** Logger available to subclasses */
41  	protected final Log logger = LogFactory.getLog(getClass());
42  
43  	private DataSource dataSource;
44  
45  	private SQLExceptionTranslator exceptionTranslator;
46  
47  	private boolean lazyInit = true;
48  
49  
50  	/**
51  	 * Set the JDBC DataSource to obtain connections from.
52  	 */
53  	public void setDataSource(DataSource dataSource) {
54  		this.dataSource = dataSource;
55  	}
56  
57  	/**
58  	 * Return the DataSource used by this template.
59  	 */
60  	public DataSource getDataSource() {
61  		return this.dataSource;
62  	}
63  
64  	/**
65  	 * Specify the database product name for the DataSource that this accessor uses.
66  	 * This allows to initialize a SQLErrorCodeSQLExceptionTranslator without
67  	 * obtaining a Connection from the DataSource to get the metadata.
68  	 * @param dbName the database product name that identifies the error codes entry
69  	 * @see SQLErrorCodeSQLExceptionTranslator#setDatabaseProductName
70  	 * @see java.sql.DatabaseMetaData#getDatabaseProductName()
71  	 */
72  	public void setDatabaseProductName(String dbName) {
73  		this.exceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(dbName);
74  	}
75  
76  	/**
77  	 * Set the exception translator for this instance.
78  	 * <p>If no custom translator is provided, a default
79  	 * {@link SQLErrorCodeSQLExceptionTranslator} is used
80  	 * which examines the SQLException's vendor-specific error code.
81  	 * @see org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator
82  	 * @see org.springframework.jdbc.support.SQLStateSQLExceptionTranslator
83  	 */
84  	public void setExceptionTranslator(SQLExceptionTranslator exceptionTranslator) {
85  		this.exceptionTranslator = exceptionTranslator;
86  	}
87  
88  	/**
89  	 * Return the exception translator for this instance.
90  	 * <p>Creates a default {@link SQLErrorCodeSQLExceptionTranslator}
91  	 * for the specified DataSource if none set, or a
92  	 * {@link SQLStateSQLExceptionTranslator} in case of no DataSource.
93  	 * @see #getDataSource()
94  	 */
95  	public synchronized SQLExceptionTranslator getExceptionTranslator() {
96  		if (this.exceptionTranslator == null) {
97  			DataSource dataSource = getDataSource();
98  			if (dataSource != null) {
99  				this.exceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(dataSource);
100 			}
101 			else {
102 				this.exceptionTranslator = new SQLStateSQLExceptionTranslator();
103 			}
104 		}
105 		return this.exceptionTranslator;
106 	}
107 
108 	/**
109 	 * Set whether to lazily initialize the SQLExceptionTranslator for this accessor,
110 	 * on first encounter of a SQLException. Default is "true"; can be switched to
111 	 * "false" for initialization on startup.
112 	 * <p>Early initialization just applies if {@code afterPropertiesSet()} is called.
113 	 * @see #getExceptionTranslator()
114 	 * @see #afterPropertiesSet()
115 	 */
116 	public void setLazyInit(boolean lazyInit) {
117 		this.lazyInit = lazyInit;
118 	}
119 
120 	/**
121 	 * Return whether to lazily initialize the SQLExceptionTranslator for this accessor.
122 	 * @see #getExceptionTranslator()
123 	 */
124 	public boolean isLazyInit() {
125 		return this.lazyInit;
126 	}
127 
128 	/**
129 	 * Eagerly initialize the exception translator, if demanded,
130 	 * creating a default one for the specified DataSource if none set.
131 	 */
132 	@Override
133 	public void afterPropertiesSet() {
134 		if (getDataSource() == null) {
135 			throw new IllegalArgumentException("Property 'dataSource' is required");
136 		}
137 		if (!isLazyInit()) {
138 			getExceptionTranslator();
139 		}
140 	}
141 
142 }