Skip to content

Commit 427fd9b

Browse files
committed
OracleTableMetaDataProvider tries Connection.unwrap as well
Issue: SPR-14670
1 parent 6417ed4 commit 427fd9b

File tree

1 file changed

+57
-34
lines changed

1 file changed

+57
-34
lines changed

spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleTableMetaDataProvider.java

Lines changed: 57 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@
3030
/**
3131
* Oracle-specific implementation of the {@link org.springframework.jdbc.core.metadata.TableMetaDataProvider}.
3232
* 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}.
3434
*
3535
* <p>Thanks to Mike Youngstrom and Bruce Campbell for submitting the original suggestion for the Oracle
3636
* current schema lookup implementation.
@@ -46,17 +46,53 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider {
4646
private String defaultSchema;
4747

4848

49+
/**
50+
* Constructor used to initialize with provided database metadata.
51+
* @param databaseMetaData metadata to be used
52+
*/
4953
public OracleTableMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException {
5054
this(databaseMetaData, false);
5155
}
5256

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+
5465
super(databaseMetaData);
5566
this.includeSynonyms = includeSynonyms;
67+
5668
lookupDefaultSchema(databaseMetaData);
5769
}
5870

5971

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+
6096
@Override
6197
protected String getDefaultSchema() {
6298
if (this.defaultSchema != null) {
@@ -65,6 +101,7 @@ protected String getDefaultSchema() {
65101
return super.getDefaultSchema();
66102
}
67103

104+
68105
@Override
69106
public void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData,
70107
String catalogName, String schemaName, String tableName) throws SQLException {
@@ -80,21 +117,29 @@ public void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData,
80117
if (nativeJdbcExtractor != null) {
81118
con = nativeJdbcExtractor.getNativeConnection(con);
82119
}
83-
boolean isOracleCon;
120+
121+
boolean isOracleCon = false;
84122
try {
85123
Class<?> oracleConClass = con.getClass().getClassLoader().loadClass("oracle.jdbc.OracleConnection");
86124
isOracleCon = oracleConClass.isInstance(con);
125+
if (!isOracleCon) {
126+
con = (Connection) con.unwrap(oracleConClass);
127+
isOracleCon = oracleConClass.isInstance(con);
128+
}
87129
}
88130
catch (ClassNotFoundException ex) {
89131
if (logger.isInfoEnabled()) {
90-
logger.info("Couldn't find Oracle JDBC API: " + ex);
132+
logger.info("Could not find Oracle JDBC API: " + ex);
91133
}
92-
isOracleCon = false;
134+
}
135+
catch (SQLException ex) {
136+
// No OracleConnection found by unwrap
93137
}
94138

95139
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+
}
98143
super.initializeWithTableColumnMetaData(databaseMetaData, catalogName, schemaName, tableName);
99144
return;
100145
}
@@ -112,39 +157,17 @@ public void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData,
112157
ReflectionUtils.makeAccessible(setIncludeSynonyms);
113158
setIncludeSynonyms.invoke(con, Boolean.TRUE);
114159
}
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);
117162
}
118163

119164
super.initializeWithTableColumnMetaData(databaseMetaData, catalogName, schemaName, tableName);
120165

121166
try {
122167
setIncludeSynonyms.invoke(con, originalValueForIncludeSynonyms);
123168
}
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);
148171
}
149172
}
150173

0 commit comments

Comments
 (0)