1
1
/*
2
- * Copyright 2002-2014 the original author or authors.
2
+ * Copyright 2002-2017 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
30
30
/**
31
31
* Oracle-specific implementation of the {@link org.springframework.jdbc.core.metadata.TableMetaDataProvider}.
32
32
* Supports a feature for including synonyms in the metadata lookup. Also supports lookup of current schema
33
- * using the sys_context.
33
+ * using the {@code sys_context} .
34
34
*
35
35
* <p>Thanks to Mike Youngstrom and Bruce Campbell for submitting the original suggestion for the Oracle
36
36
* current schema lookup implementation.
@@ -46,17 +46,53 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider {
46
46
private String defaultSchema ;
47
47
48
48
49
+ /**
50
+ * Constructor used to initialize with provided database metadata.
51
+ * @param databaseMetaData metadata to be used
52
+ */
49
53
public OracleTableMetaDataProvider (DatabaseMetaData databaseMetaData ) throws SQLException {
50
54
this (databaseMetaData , false );
51
55
}
52
56
53
- public OracleTableMetaDataProvider (DatabaseMetaData databaseMetaData , boolean includeSynonyms ) throws SQLException {
57
+ /**
58
+ * Constructor used to initialize with provided database metadata.
59
+ * @param databaseMetaData metadata to be used
60
+ * @param includeSynonyms whether to include synonyms
61
+ */
62
+ public OracleTableMetaDataProvider (DatabaseMetaData databaseMetaData , boolean includeSynonyms )
63
+ throws SQLException {
64
+
54
65
super (databaseMetaData );
55
66
this .includeSynonyms = includeSynonyms ;
67
+
56
68
lookupDefaultSchema (databaseMetaData );
57
69
}
58
70
59
71
72
+ /*
73
+ * Oracle-based implementation for detecting the current schema.
74
+ */
75
+ private void lookupDefaultSchema (DatabaseMetaData databaseMetaData ) {
76
+ try {
77
+ CallableStatement cstmt = null ;
78
+ try {
79
+ cstmt = databaseMetaData .getConnection ().prepareCall (
80
+ "{? = call sys_context('USERENV', 'CURRENT_SCHEMA')}" );
81
+ cstmt .registerOutParameter (1 , Types .VARCHAR );
82
+ cstmt .execute ();
83
+ this .defaultSchema = cstmt .getString (1 );
84
+ }
85
+ finally {
86
+ if (cstmt != null ) {
87
+ cstmt .close ();
88
+ }
89
+ }
90
+ }
91
+ catch (SQLException ex ) {
92
+ logger .debug ("Encountered exception during default schema lookup" , ex );
93
+ }
94
+ }
95
+
60
96
@ Override
61
97
protected String getDefaultSchema () {
62
98
if (this .defaultSchema != null ) {
@@ -65,6 +101,7 @@ protected String getDefaultSchema() {
65
101
return super .getDefaultSchema ();
66
102
}
67
103
104
+
68
105
@ Override
69
106
public void initializeWithTableColumnMetaData (DatabaseMetaData databaseMetaData ,
70
107
String catalogName , String schemaName , String tableName ) throws SQLException {
@@ -80,21 +117,29 @@ public void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData,
80
117
if (nativeJdbcExtractor != null ) {
81
118
con = nativeJdbcExtractor .getNativeConnection (con );
82
119
}
83
- boolean isOracleCon ;
120
+
121
+ boolean isOracleCon = false ;
84
122
try {
85
123
Class <?> oracleConClass = con .getClass ().getClassLoader ().loadClass ("oracle.jdbc.OracleConnection" );
86
124
isOracleCon = oracleConClass .isInstance (con );
125
+ if (!isOracleCon ) {
126
+ con = (Connection ) con .unwrap (oracleConClass );
127
+ isOracleCon = oracleConClass .isInstance (con );
128
+ }
87
129
}
88
130
catch (ClassNotFoundException ex ) {
89
131
if (logger .isInfoEnabled ()) {
90
- logger .info ("Couldn't find Oracle JDBC API: " + ex );
132
+ logger .info ("Could not find Oracle JDBC API: " + ex );
91
133
}
92
- isOracleCon = false ;
134
+ }
135
+ catch (SQLException ex ) {
136
+ // No OracleConnection found by unwrap
93
137
}
94
138
95
139
if (!isOracleCon ) {
96
- logger .warn ("Unable to include synonyms in table metadata lookup. Connection used for " +
97
- "DatabaseMetaData is not recognized as an Oracle connection: " + con );
140
+ if (logger .isWarnEnabled ()) {
141
+ logger .warn ("Unable to include synonyms in table metadata lookup - no Oracle Connection: " + con );
142
+ }
98
143
super .initializeWithTableColumnMetaData (databaseMetaData , catalogName , schemaName , tableName );
99
144
return ;
100
145
}
@@ -112,39 +157,17 @@ public void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData,
112
157
ReflectionUtils .makeAccessible (setIncludeSynonyms );
113
158
setIncludeSynonyms .invoke (con , Boolean .TRUE );
114
159
}
115
- catch (Exception ex ) {
116
- throw new InvalidDataAccessApiUsageException ("Couldn't prepare Oracle Connection" , ex );
160
+ catch (Throwable ex ) {
161
+ throw new InvalidDataAccessApiUsageException ("Could not prepare Oracle Connection" , ex );
117
162
}
118
163
119
164
super .initializeWithTableColumnMetaData (databaseMetaData , catalogName , schemaName , tableName );
120
165
121
166
try {
122
167
setIncludeSynonyms .invoke (con , originalValueForIncludeSynonyms );
123
168
}
124
- catch (Exception ex ) {
125
- throw new InvalidDataAccessApiUsageException ("Couldn't reset Oracle Connection" , ex );
126
- }
127
- }
128
-
129
- /*
130
- * Oracle-based implementation for detecting the current schema.
131
- */
132
- private void lookupDefaultSchema (DatabaseMetaData databaseMetaData ) {
133
- try {
134
- CallableStatement cstmt = null ;
135
- try {
136
- cstmt = databaseMetaData .getConnection ().prepareCall ("{? = call sys_context('USERENV', 'CURRENT_SCHEMA')}" );
137
- cstmt .registerOutParameter (1 , Types .VARCHAR );
138
- cstmt .execute ();
139
- this .defaultSchema = cstmt .getString (1 );
140
- }
141
- finally {
142
- if (cstmt != null ) {
143
- cstmt .close ();
144
- }
145
- }
146
- }
147
- catch (Exception ignore ) {
169
+ catch (Throwable ex ) {
170
+ throw new InvalidDataAccessApiUsageException ("Could not reset Oracle Connection" , ex );
148
171
}
149
172
}
150
173
0 commit comments