HHH-18220 Detect if Application Continuity is enabled for Oracle dialect
This commit is contained in:
parent
58e814965e
commit
7c711751dd
|
@ -12,6 +12,7 @@ package org.hibernate.cfg;
|
||||||
* its underlying JDBC {@link java.sql.Connection}.
|
* its underlying JDBC {@link java.sql.Connection}.
|
||||||
*
|
*
|
||||||
* @author Marco Belladelli
|
* @author Marco Belladelli
|
||||||
|
* @author Loïc Lefèvre
|
||||||
*/
|
*/
|
||||||
public interface DialectSpecificSettings {
|
public interface DialectSpecificSettings {
|
||||||
/**
|
/**
|
||||||
|
@ -28,6 +29,15 @@ public interface DialectSpecificSettings {
|
||||||
*/
|
*/
|
||||||
public static final String ORACLE_EXTENDED_STRING_SIZE = "hibernate.dialect.oracle.extended_string_size";
|
public static final String ORACLE_EXTENDED_STRING_SIZE = "hibernate.dialect.oracle.extended_string_size";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether this database is accessed using a database service protected by Application Continuity.
|
||||||
|
*
|
||||||
|
* @settingDefault {@code false}
|
||||||
|
*
|
||||||
|
* @see <a href="https://docs.oracle.com/en/database/oracle/oracle-database/23/jjdbc/application-continuity.html">Application Continuity for Java</a>
|
||||||
|
*/
|
||||||
|
public static final String ORACLE_APPLICATION_CONTINUITY = "hibernate.dialect.oracle.application_continuity";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies whether this database's {@code ansinull} setting is enabled.
|
* Specifies whether this database's {@code ansinull} setting is enabled.
|
||||||
*
|
*
|
||||||
|
|
|
@ -187,6 +187,9 @@ public class OracleDialect extends Dialect {
|
||||||
// Is MAX_STRING_SIZE set to EXTENDED?
|
// Is MAX_STRING_SIZE set to EXTENDED?
|
||||||
protected final boolean extended;
|
protected final boolean extended;
|
||||||
|
|
||||||
|
// Is the database accessed using a database service protected by Application Continuity.
|
||||||
|
protected final boolean applicationContinuity;
|
||||||
|
|
||||||
protected final int driverMajorVersion;
|
protected final int driverMajorVersion;
|
||||||
|
|
||||||
protected final int driverMinorVersion;
|
protected final int driverMinorVersion;
|
||||||
|
@ -200,6 +203,7 @@ public class OracleDialect extends Dialect {
|
||||||
super(version);
|
super(version);
|
||||||
autonomous = false;
|
autonomous = false;
|
||||||
extended = false;
|
extended = false;
|
||||||
|
applicationContinuity = false;
|
||||||
driverMajorVersion = 19;
|
driverMajorVersion = 19;
|
||||||
driverMinorVersion = 0;
|
driverMinorVersion = 0;
|
||||||
}
|
}
|
||||||
|
@ -212,6 +216,7 @@ public class OracleDialect extends Dialect {
|
||||||
super( info );
|
super( info );
|
||||||
autonomous = serverConfiguration.isAutonomous();
|
autonomous = serverConfiguration.isAutonomous();
|
||||||
extended = serverConfiguration.isExtended();
|
extended = serverConfiguration.isExtended();
|
||||||
|
applicationContinuity = serverConfiguration.isApplicationContinuity();
|
||||||
this.driverMinorVersion = serverConfiguration.getDriverMinorVersion();
|
this.driverMinorVersion = serverConfiguration.getDriverMinorVersion();
|
||||||
this.driverMajorVersion = serverConfiguration.getDriverMajorVersion();
|
this.driverMajorVersion = serverConfiguration.getDriverMajorVersion();
|
||||||
}
|
}
|
||||||
|
@ -258,6 +263,10 @@ public class OracleDialect extends Dialect {
|
||||||
return extended;
|
return extended;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isApplicationContinuity() {
|
||||||
|
return applicationContinuity;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DatabaseVersion getMinimumSupportedVersion() {
|
protected DatabaseVersion getMinimumSupportedVersion() {
|
||||||
return MINIMUM_VERSION;
|
return MINIMUM_VERSION;
|
||||||
|
|
|
@ -6,15 +6,20 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.dialect;
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
import java.sql.DatabaseMetaData;
|
import java.sql.DatabaseMetaData;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import oracle.jdbc.replay.ReplayStatistics;
|
||||||
|
import oracle.jdbc.replay.ReplayableConnection;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
|
|
||||||
|
import static oracle.jdbc.replay.ReplayableConnection.StatisticsReportType.FOR_CURRENT_CONNECTION;
|
||||||
|
import static org.hibernate.cfg.DialectSpecificSettings.ORACLE_APPLICATION_CONTINUITY;
|
||||||
import static org.hibernate.cfg.DialectSpecificSettings.ORACLE_AUTONOMOUS_DATABASE;
|
import static org.hibernate.cfg.DialectSpecificSettings.ORACLE_AUTONOMOUS_DATABASE;
|
||||||
import static org.hibernate.cfg.DialectSpecificSettings.ORACLE_EXTENDED_STRING_SIZE;
|
import static org.hibernate.cfg.DialectSpecificSettings.ORACLE_EXTENDED_STRING_SIZE;
|
||||||
|
|
||||||
|
@ -22,10 +27,12 @@ import static org.hibernate.cfg.DialectSpecificSettings.ORACLE_EXTENDED_STRING_S
|
||||||
* Utility class that extract some initial configuration from the database for {@link OracleDialect}.
|
* Utility class that extract some initial configuration from the database for {@link OracleDialect}.
|
||||||
*
|
*
|
||||||
* @author Marco Belladelli
|
* @author Marco Belladelli
|
||||||
|
* @author Loïc Lefèvre
|
||||||
*/
|
*/
|
||||||
public class OracleServerConfiguration {
|
public class OracleServerConfiguration {
|
||||||
private final boolean autonomous;
|
private final boolean autonomous;
|
||||||
private final boolean extended;
|
private final boolean extended;
|
||||||
|
private final boolean applicationContinuity;
|
||||||
private final int driverMajorVersion;
|
private final int driverMajorVersion;
|
||||||
private final int driverMinorVersion;
|
private final int driverMinorVersion;
|
||||||
|
|
||||||
|
@ -37,6 +44,10 @@ public class OracleServerConfiguration {
|
||||||
return extended;
|
return extended;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isApplicationContinuity() {
|
||||||
|
return applicationContinuity;
|
||||||
|
}
|
||||||
|
|
||||||
public int getDriverMajorVersion() {
|
public int getDriverMajorVersion() {
|
||||||
return driverMajorVersion;
|
return driverMajorVersion;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +57,7 @@ public class OracleServerConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
public OracleServerConfiguration(boolean autonomous, boolean extended) {
|
public OracleServerConfiguration(boolean autonomous, boolean extended) {
|
||||||
this( autonomous, extended, 19, 0 );
|
this( autonomous, extended, false, 19, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
public OracleServerConfiguration(
|
public OracleServerConfiguration(
|
||||||
|
@ -54,8 +65,18 @@ public class OracleServerConfiguration {
|
||||||
boolean extended,
|
boolean extended,
|
||||||
int driverMajorVersion,
|
int driverMajorVersion,
|
||||||
int driverMinorVersion) {
|
int driverMinorVersion) {
|
||||||
|
this(autonomous, extended, false, driverMajorVersion, driverMinorVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OracleServerConfiguration(
|
||||||
|
boolean autonomous,
|
||||||
|
boolean extended,
|
||||||
|
boolean applicationContinuity,
|
||||||
|
int driverMajorVersion,
|
||||||
|
int driverMinorVersion) {
|
||||||
this.autonomous = autonomous;
|
this.autonomous = autonomous;
|
||||||
this.extended = extended;
|
this.extended = extended;
|
||||||
|
this.applicationContinuity = applicationContinuity;
|
||||||
this.driverMajorVersion = driverMajorVersion;
|
this.driverMajorVersion = driverMajorVersion;
|
||||||
this.driverMinorVersion = driverMinorVersion;
|
this.driverMinorVersion = driverMinorVersion;
|
||||||
}
|
}
|
||||||
|
@ -63,6 +84,7 @@ public class OracleServerConfiguration {
|
||||||
public static OracleServerConfiguration fromDialectResolutionInfo(DialectResolutionInfo info) {
|
public static OracleServerConfiguration fromDialectResolutionInfo(DialectResolutionInfo info) {
|
||||||
Boolean extended = null;
|
Boolean extended = null;
|
||||||
Boolean autonomous = null;
|
Boolean autonomous = null;
|
||||||
|
Boolean applicationContinuity = null;
|
||||||
Integer majorVersion = null;
|
Integer majorVersion = null;
|
||||||
Integer minorVersion = null;
|
Integer minorVersion = null;
|
||||||
final DatabaseMetaData databaseMetaData = info.getDatabaseMetadata();
|
final DatabaseMetaData databaseMetaData = info.getDatabaseMetadata();
|
||||||
|
@ -70,7 +92,42 @@ public class OracleServerConfiguration {
|
||||||
majorVersion = databaseMetaData.getDriverMajorVersion();
|
majorVersion = databaseMetaData.getDriverMajorVersion();
|
||||||
minorVersion = databaseMetaData.getDriverMinorVersion();
|
minorVersion = databaseMetaData.getDriverMinorVersion();
|
||||||
|
|
||||||
try (final Statement statement = databaseMetaData.getConnection().createStatement()) {
|
|
||||||
|
try {
|
||||||
|
final Connection c = databaseMetaData.getConnection();
|
||||||
|
|
||||||
|
// Use Oracle JDBC replay statistics information to determine if this
|
||||||
|
// connection is protected by Application Continuity
|
||||||
|
try {
|
||||||
|
final ReplayableConnection re = (ReplayableConnection) c;
|
||||||
|
ReplayStatistics stats = re.getReplayStatistics(FOR_CURRENT_CONNECTION);
|
||||||
|
|
||||||
|
final long totalRequests = stats.getTotalRequests();
|
||||||
|
final long protectedCalls = stats.getTotalProtectedCalls();
|
||||||
|
|
||||||
|
try (final Statement s = c.createStatement()) {
|
||||||
|
try (final ResultSet r = s.executeQuery("select 1 from dual")) {
|
||||||
|
r.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stats = re.getReplayStatistics(FOR_CURRENT_CONNECTION);
|
||||||
|
|
||||||
|
// Application continuity is enabled on this database service if the number of
|
||||||
|
// total requests and the number of protected calls for this connection have
|
||||||
|
// both increased.
|
||||||
|
applicationContinuity = stats.getTotalRequests() > totalRequests && stats.getTotalProtectedCalls() > protectedCalls;
|
||||||
|
}
|
||||||
|
catch(Exception e) {
|
||||||
|
// A ClassCastException or a NullPointerException are expected here in the case
|
||||||
|
// the Connection Factory is not the right one (not Replayable: ClassCastException)
|
||||||
|
// or if the database service has not been configured (server side) to enable
|
||||||
|
// application continuity (NullPointerException).
|
||||||
|
applicationContinuity = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// continue the checks...
|
||||||
|
try (final Statement statement = c.createStatement()) {
|
||||||
final ResultSet rs = statement.executeQuery(
|
final ResultSet rs = statement.executeQuery(
|
||||||
"select cast('string' as varchar2(32000)), " +
|
"select cast('string' as varchar2(32000)), " +
|
||||||
"sys_context('USERENV','CLOUD_SERVICE') from dual"
|
"sys_context('USERENV','CLOUD_SERVICE') from dual"
|
||||||
|
@ -81,6 +138,7 @@ public class OracleServerConfiguration {
|
||||||
autonomous = isAutonomous(rs.getString(2));
|
autonomous = isAutonomous(rs.getString(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (SQLException ex) {
|
catch (SQLException ex) {
|
||||||
// failed, so MAX_STRING_SIZE == STANDARD, still need to check autonomous
|
// failed, so MAX_STRING_SIZE == STANDARD, still need to check autonomous
|
||||||
extended = false;
|
extended = false;
|
||||||
|
@ -102,6 +160,13 @@ public class OracleServerConfiguration {
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if ( applicationContinuity == null ) {
|
||||||
|
applicationContinuity = ConfigurationHelper.getBoolean(
|
||||||
|
ORACLE_APPLICATION_CONTINUITY,
|
||||||
|
info.getConfigurationValues(),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
if ( majorVersion == null ) {
|
if ( majorVersion == null ) {
|
||||||
try {
|
try {
|
||||||
java.sql.Driver driver = java.sql.DriverManager.getDriver( "jdbc:oracle:thin:" );
|
java.sql.Driver driver = java.sql.DriverManager.getDriver( "jdbc:oracle:thin:" );
|
||||||
|
@ -114,7 +179,7 @@ public class OracleServerConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return new OracleServerConfiguration( autonomous, extended, majorVersion, minorVersion );
|
return new OracleServerConfiguration( autonomous, extended, applicationContinuity, majorVersion, minorVersion );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isAutonomous(String cloudServiceParam) {
|
private static boolean isAutonomous(String cloudServiceParam) {
|
||||||
|
|
Loading…
Reference in New Issue