Merge remote-tracking branch 'upstream/main' into wip/6.0
This commit is contained in:
commit
105f91e910
|
@ -275,7 +275,7 @@ Please report your mapping that causes the problem to us so we can examine the d
|
||||||
+
|
+
|
||||||
The default value is `false` which means Hibernate will use an algorithm to determine if the insert can be delayed or if the insert should be performed immediately.
|
The default value is `false` which means Hibernate will use an algorithm to determine if the insert can be delayed or if the insert should be performed immediately.
|
||||||
|
|
||||||
`*hibernate.id.sequence.increment_size_mismatch_strategy*` (e.g. `LOG`, `FIX` or `EXCEPTION` (default value))::
|
`*hibernate.id.sequence.increment_size_mismatch_strategy*` (e.g. `LOG`, `FIX`, `NONE` or `EXCEPTION` (default value))::
|
||||||
This setting defines the `org.hibernate.id.SequenceMismatchStrategy` used when
|
This setting defines the `org.hibernate.id.SequenceMismatchStrategy` used when
|
||||||
Hibernate detects a mismatch between a sequence configuration in an entity mapping
|
Hibernate detects a mismatch between a sequence configuration in an entity mapping
|
||||||
and its database sequence object counterpart.
|
and its database sequence object counterpart.
|
||||||
|
|
|
@ -1389,6 +1389,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
|
||||||
this.scrollableResultSetsEnabled = enabled;
|
this.scrollableResultSetsEnabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public void enableResultSetWrappingSupport(boolean enabled) {
|
public void enableResultSetWrappingSupport(boolean enabled) {
|
||||||
this.wrapResultSetsEnabled = enabled;
|
this.wrapResultSetsEnabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
|
@ -220,6 +220,10 @@ public interface SessionFactoryOptions extends QueryEngineOptions {
|
||||||
|
|
||||||
boolean isScrollableResultSetsEnabled();
|
boolean isScrollableResultSetsEnabled();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated (since 5.5) Scheduled for removal in 6.0 as ResultSet wrapping is no longer needed
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
boolean isWrapResultSetsEnabled();
|
boolean isWrapResultSetsEnabled();
|
||||||
|
|
||||||
boolean isGetGeneratedKeysEnabled();
|
boolean isGetGeneratedKeysEnabled();
|
||||||
|
|
|
@ -1236,7 +1236,10 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings {
|
||||||
/**
|
/**
|
||||||
* Enable wrapping of JDBC result sets in order to speed up column name lookups for
|
* Enable wrapping of JDBC result sets in order to speed up column name lookups for
|
||||||
* broken JDBC drivers
|
* broken JDBC drivers
|
||||||
|
*
|
||||||
|
* @deprecated (since 5.5) Scheduled for removal in 6.0 as ResultSet wrapping is no longer needed
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
String WRAP_RESULT_SETS = "hibernate.jdbc.wrap_result_sets";
|
String WRAP_RESULT_SETS = "hibernate.jdbc.wrap_result_sets";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2552,8 +2555,9 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings {
|
||||||
* and its database sequence object counterpart.
|
* and its database sequence object counterpart.
|
||||||
* </p>
|
* </p>
|
||||||
* Possible values are {@link org.hibernate.id.SequenceMismatchStrategy#EXCEPTION},
|
* Possible values are {@link org.hibernate.id.SequenceMismatchStrategy#EXCEPTION},
|
||||||
* {@link org.hibernate.id.SequenceMismatchStrategy#LOG}, and
|
* {@link org.hibernate.id.SequenceMismatchStrategy#LOG},
|
||||||
* {@link org.hibernate.id.SequenceMismatchStrategy#FIX}.
|
* {@link org.hibernate.id.SequenceMismatchStrategy#FIX}
|
||||||
|
* and {@link org.hibernate.id.SequenceMismatchStrategy#NONE}.
|
||||||
* </p>
|
* </p>
|
||||||
* The default value is given by the {@link org.hibernate.id.SequenceMismatchStrategy#EXCEPTION},
|
* The default value is given by the {@link org.hibernate.id.SequenceMismatchStrategy#EXCEPTION},
|
||||||
* meaning that an Exception is thrown when detecting such a conflict.
|
* meaning that an Exception is thrown when detecting such a conflict.
|
||||||
|
|
|
@ -67,6 +67,7 @@ public class Oracle12LimitHandler extends AbstractLimitHandler {
|
||||||
if ( !hasMaxRows ) {
|
if ( !hasMaxRows ) {
|
||||||
return sql;
|
return sql;
|
||||||
}
|
}
|
||||||
|
sql = sql.trim();
|
||||||
|
|
||||||
return processSql(
|
return processSql(
|
||||||
sql,
|
sql,
|
||||||
|
@ -106,7 +107,6 @@ public class Oracle12LimitHandler extends AbstractLimitHandler {
|
||||||
useMaxForLimit = false;
|
useMaxForLimit = false;
|
||||||
supportOffset = true;
|
supportOffset = true;
|
||||||
|
|
||||||
sql = normalizeStatement( sql );
|
|
||||||
final int offsetFetchLength;
|
final int offsetFetchLength;
|
||||||
final String offsetFetchString;
|
final String offsetFetchString;
|
||||||
if ( hasFirstRow ) {
|
if ( hasFirstRow ) {
|
||||||
|
@ -125,8 +125,6 @@ public class Oracle12LimitHandler extends AbstractLimitHandler {
|
||||||
useMaxForLimit = true;
|
useMaxForLimit = true;
|
||||||
supportOffset = false;
|
supportOffset = false;
|
||||||
|
|
||||||
sql = normalizeStatement( sql );
|
|
||||||
|
|
||||||
String forUpdateClause = null;
|
String forUpdateClause = null;
|
||||||
boolean isForUpdate = false;
|
boolean isForUpdate = false;
|
||||||
if ( forUpdateIndex > -1 ) {
|
if ( forUpdateIndex > -1 ) {
|
||||||
|
@ -167,10 +165,6 @@ public class Oracle12LimitHandler extends AbstractLimitHandler {
|
||||||
return pagingSelect.toString();
|
return pagingSelect.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String normalizeStatement(String sql) {
|
|
||||||
return sql.trim().replaceAll( "\\s+", " " );
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getForUpdateIndex(String sql) {
|
private int getForUpdateIndex(String sql) {
|
||||||
final int forUpdateLastIndex = sql.toLowerCase( Locale.ROOT ).lastIndexOf( "for update" );
|
final int forUpdateLastIndex = sql.toLowerCase( Locale.ROOT ).lastIndexOf( "for update" );
|
||||||
// We need to recognize cases like : select a from t where b = 'for update';
|
// We need to recognize cases like : select a from t where b = 'for update';
|
||||||
|
|
|
@ -6,21 +6,25 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.engine.jdbc.env.internal;
|
package org.hibernate.engine.jdbc.env.internal;
|
||||||
|
|
||||||
|
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.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.boot.model.source.internal.hbm.CommaSeparatedStringHelper;
|
import org.hibernate.boot.model.source.internal.hbm.CommaSeparatedStringHelper;
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||||
import org.hibernate.engine.jdbc.cursor.internal.StandardRefCursorSupport;
|
import org.hibernate.engine.jdbc.cursor.internal.StandardRefCursorSupport;
|
||||||
import org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData;
|
import org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData;
|
||||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||||
import org.hibernate.engine.jdbc.env.spi.SQLStateType;
|
import org.hibernate.engine.jdbc.env.spi.SQLStateType;
|
||||||
import org.hibernate.engine.jdbc.spi.TypeInfo;
|
import org.hibernate.tool.schema.extract.spi.ExtractionContext;
|
||||||
import org.hibernate.tool.schema.extract.spi.SequenceInformation;
|
import org.hibernate.tool.schema.extract.spi.SequenceInformation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -29,7 +33,9 @@ import org.hibernate.tool.schema.extract.spi.SequenceInformation;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData {
|
public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData {
|
||||||
|
|
||||||
private final JdbcEnvironment jdbcEnvironment;
|
private final JdbcEnvironment jdbcEnvironment;
|
||||||
|
private final JdbcConnectionAccess connectionAccess;
|
||||||
|
|
||||||
private final String connectionCatalogName;
|
private final String connectionCatalogName;
|
||||||
private final String connectionSchemaName;
|
private final String connectionSchemaName;
|
||||||
|
@ -42,18 +48,19 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
|
||||||
private final boolean supportsDataDefinitionInTransaction;
|
private final boolean supportsDataDefinitionInTransaction;
|
||||||
private final boolean doesDataDefinitionCauseTransactionCommit;
|
private final boolean doesDataDefinitionCauseTransactionCommit;
|
||||||
private final SQLStateType sqlStateType;
|
private final SQLStateType sqlStateType;
|
||||||
private final boolean lobLocatorUpdateCopy;
|
private final boolean jdbcMetadataAccessible;
|
||||||
|
|
||||||
private final Set<String> extraKeywords;
|
|
||||||
private final LinkedHashSet<TypeInfo> typeInfoSet;
|
//Lazily initialized: loading all sequence information upfront has been
|
||||||
private final List<SequenceInformation> sequenceInformationList;
|
//shown to be too slow in some cases. In this way we only load it
|
||||||
|
//when there is actual need for these details.
|
||||||
|
private List<SequenceInformation> sequenceInformationList;
|
||||||
|
|
||||||
private ExtractedDatabaseMetaDataImpl(
|
private ExtractedDatabaseMetaDataImpl(
|
||||||
JdbcEnvironment jdbcEnvironment,
|
JdbcEnvironment jdbcEnvironment,
|
||||||
|
JdbcConnectionAccess connectionAccess,
|
||||||
String connectionCatalogName,
|
String connectionCatalogName,
|
||||||
String connectionSchemaName,
|
String connectionSchemaName,
|
||||||
Set<String> extraKeywords,
|
|
||||||
LinkedHashSet<TypeInfo> typeInfoSet,
|
|
||||||
boolean supportsRefCursors,
|
boolean supportsRefCursors,
|
||||||
boolean supportsNamedParameters,
|
boolean supportsNamedParameters,
|
||||||
boolean supportsScrollableResults,
|
boolean supportsScrollableResults,
|
||||||
|
@ -62,20 +69,11 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
|
||||||
boolean supportsDataDefinitionInTransaction,
|
boolean supportsDataDefinitionInTransaction,
|
||||||
boolean doesDataDefinitionCauseTransactionCommit,
|
boolean doesDataDefinitionCauseTransactionCommit,
|
||||||
SQLStateType sqlStateType,
|
SQLStateType sqlStateType,
|
||||||
boolean lobLocatorUpdateCopy,
|
boolean jdbcMetadataIsAccessible) {
|
||||||
List<SequenceInformation> sequenceInformationList) {
|
|
||||||
this.jdbcEnvironment = jdbcEnvironment;
|
this.jdbcEnvironment = jdbcEnvironment;
|
||||||
|
this.connectionAccess = connectionAccess;
|
||||||
this.connectionCatalogName = connectionCatalogName;
|
this.connectionCatalogName = connectionCatalogName;
|
||||||
this.connectionSchemaName = connectionSchemaName;
|
this.connectionSchemaName = connectionSchemaName;
|
||||||
|
|
||||||
this.extraKeywords = extraKeywords != null
|
|
||||||
? extraKeywords
|
|
||||||
: Collections.emptySet();
|
|
||||||
this.typeInfoSet = typeInfoSet != null
|
|
||||||
? typeInfoSet
|
|
||||||
: new LinkedHashSet<>();
|
|
||||||
|
|
||||||
this.supportsRefCursors = supportsRefCursors;
|
this.supportsRefCursors = supportsRefCursors;
|
||||||
this.supportsNamedParameters = supportsNamedParameters;
|
this.supportsNamedParameters = supportsNamedParameters;
|
||||||
this.supportsScrollableResults = supportsScrollableResults;
|
this.supportsScrollableResults = supportsScrollableResults;
|
||||||
|
@ -84,8 +82,7 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
|
||||||
this.supportsDataDefinitionInTransaction = supportsDataDefinitionInTransaction;
|
this.supportsDataDefinitionInTransaction = supportsDataDefinitionInTransaction;
|
||||||
this.doesDataDefinitionCauseTransactionCommit = doesDataDefinitionCauseTransactionCommit;
|
this.doesDataDefinitionCauseTransactionCommit = doesDataDefinitionCauseTransactionCommit;
|
||||||
this.sqlStateType = sqlStateType;
|
this.sqlStateType = sqlStateType;
|
||||||
this.lobLocatorUpdateCopy = lobLocatorUpdateCopy;
|
this.jdbcMetadataAccessible = jdbcMetadataIsAccessible;
|
||||||
this.sequenceInformationList = sequenceInformationList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -128,21 +125,11 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
|
||||||
return doesDataDefinitionCauseTransactionCommit;
|
return doesDataDefinitionCauseTransactionCommit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<String> getExtraKeywords() {
|
|
||||||
return extraKeywords;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SQLStateType getSqlStateType() {
|
public SQLStateType getSqlStateType() {
|
||||||
return sqlStateType;
|
return sqlStateType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean doesLobLocatorUpdateCopy() {
|
|
||||||
return lobLocatorUpdateCopy;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getConnectionCatalogName() {
|
public String getConnectionCatalogName() {
|
||||||
return connectionCatalogName;
|
return connectionCatalogName;
|
||||||
|
@ -154,24 +141,30 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LinkedHashSet<TypeInfo> getTypeInfoSet() {
|
public synchronized List<SequenceInformation> getSequenceInformationList() {
|
||||||
return typeInfoSet;
|
if ( jdbcMetadataAccessible ) {
|
||||||
}
|
//Loading the sequence information can take a while on large databases,
|
||||||
|
//even minutes in some cases.
|
||||||
@Override
|
//We trigger this lazily as only certain combinations of configurations,
|
||||||
public List<SequenceInformation> getSequenceInformationList() {
|
//mappings and used features actually trigger any use of such details.
|
||||||
return sequenceInformationList;
|
if ( sequenceInformationList == null ) {
|
||||||
|
sequenceInformationList = sequenceInformationList();
|
||||||
|
}
|
||||||
|
return sequenceInformationList;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
private final JdbcEnvironment jdbcEnvironment;
|
private final JdbcEnvironment jdbcEnvironment;
|
||||||
|
private final boolean jdbcMetadataIsAccessible;
|
||||||
|
private final JdbcConnectionAccess connectionAccess;
|
||||||
|
|
||||||
private String connectionSchemaName;
|
private String connectionSchemaName;
|
||||||
private String connectionCatalogName;
|
private String connectionCatalogName;
|
||||||
|
|
||||||
private Set<String> extraKeywords;
|
|
||||||
private LinkedHashSet<TypeInfo> typeInfoSet;
|
|
||||||
|
|
||||||
private boolean supportsRefCursors;
|
private boolean supportsRefCursors;
|
||||||
private boolean supportsNamedParameters;
|
private boolean supportsNamedParameters;
|
||||||
private boolean supportsScrollableResults;
|
private boolean supportsScrollableResults;
|
||||||
|
@ -180,11 +173,11 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
|
||||||
private boolean supportsDataDefinitionInTransaction;
|
private boolean supportsDataDefinitionInTransaction;
|
||||||
private boolean doesDataDefinitionCauseTransactionCommit;
|
private boolean doesDataDefinitionCauseTransactionCommit;
|
||||||
private SQLStateType sqlStateType;
|
private SQLStateType sqlStateType;
|
||||||
private boolean lobLocatorUpdateCopy;
|
|
||||||
private List<SequenceInformation> sequenceInformationList = Collections.emptyList();
|
|
||||||
|
|
||||||
public Builder(JdbcEnvironment jdbcEnvironment) {
|
public Builder(JdbcEnvironment jdbcEnvironment, boolean jdbcMetadataIsAccessible, JdbcConnectionAccess connectionAccess) {
|
||||||
this.jdbcEnvironment = jdbcEnvironment;
|
this.jdbcEnvironment = jdbcEnvironment;
|
||||||
|
this.jdbcMetadataIsAccessible = jdbcMetadataIsAccessible;
|
||||||
|
this.connectionAccess = connectionAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder apply(DatabaseMetaData databaseMetaData) throws SQLException {
|
public Builder apply(DatabaseMetaData databaseMetaData) throws SQLException {
|
||||||
|
@ -197,16 +190,7 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
|
||||||
supportsBatchUpdates = databaseMetaData.supportsBatchUpdates();
|
supportsBatchUpdates = databaseMetaData.supportsBatchUpdates();
|
||||||
supportsDataDefinitionInTransaction = !databaseMetaData.dataDefinitionIgnoredInTransactions();
|
supportsDataDefinitionInTransaction = !databaseMetaData.dataDefinitionIgnoredInTransactions();
|
||||||
doesDataDefinitionCauseTransactionCommit = databaseMetaData.dataDefinitionCausesTransactionCommit();
|
doesDataDefinitionCauseTransactionCommit = databaseMetaData.dataDefinitionCausesTransactionCommit();
|
||||||
extraKeywords = parseKeywords( databaseMetaData.getSQLKeywords() );
|
|
||||||
sqlStateType = SQLStateType.interpretReportedSQLStateType( databaseMetaData.getSQLStateType() );
|
sqlStateType = SQLStateType.interpretReportedSQLStateType( databaseMetaData.getSQLStateType() );
|
||||||
try {
|
|
||||||
lobLocatorUpdateCopy = databaseMetaData.locatorsUpdateCopy();
|
|
||||||
}
|
|
||||||
catch (SQLException sql) {
|
|
||||||
//ignore, the database might not support this at all
|
|
||||||
}
|
|
||||||
typeInfoSet = new LinkedHashSet<>();
|
|
||||||
typeInfoSet.addAll( TypeInfo.extractTypeInfo( databaseMetaData ) );
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,42 +208,6 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setExtraKeywords(Set<String> extraKeywords) {
|
|
||||||
if ( this.extraKeywords == null ) {
|
|
||||||
this.extraKeywords = extraKeywords;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.extraKeywords.addAll( extraKeywords );
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder addExtraKeyword(String keyword) {
|
|
||||||
if ( this.extraKeywords == null ) {
|
|
||||||
this.extraKeywords = new HashSet<>();
|
|
||||||
}
|
|
||||||
this.extraKeywords.add( keyword );
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setTypeInfoSet(LinkedHashSet<TypeInfo> typeInfoSet) {
|
|
||||||
if ( this.typeInfoSet == null ) {
|
|
||||||
this.typeInfoSet = typeInfoSet;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.typeInfoSet.addAll( typeInfoSet );
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder addTypeInfo(TypeInfo typeInfo) {
|
|
||||||
if ( this.typeInfoSet == null ) {
|
|
||||||
this.typeInfoSet = new LinkedHashSet<>();
|
|
||||||
}
|
|
||||||
typeInfoSet.add( typeInfo );
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setSupportsRefCursors(boolean supportsRefCursors) {
|
public Builder setSupportsRefCursors(boolean supportsRefCursors) {
|
||||||
this.supportsRefCursors = supportsRefCursors;
|
this.supportsRefCursors = supportsRefCursors;
|
||||||
return this;
|
return this;
|
||||||
|
@ -300,23 +248,12 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setLobLocatorUpdateCopy(boolean lobLocatorUpdateCopy) {
|
|
||||||
this.lobLocatorUpdateCopy = lobLocatorUpdateCopy;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setSequenceInformationList(List<SequenceInformation> sequenceInformationList) {
|
|
||||||
this.sequenceInformationList = sequenceInformationList;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExtractedDatabaseMetaDataImpl build() {
|
public ExtractedDatabaseMetaDataImpl build() {
|
||||||
return new ExtractedDatabaseMetaDataImpl(
|
return new ExtractedDatabaseMetaDataImpl(
|
||||||
jdbcEnvironment,
|
jdbcEnvironment,
|
||||||
|
connectionAccess,
|
||||||
connectionCatalogName,
|
connectionCatalogName,
|
||||||
connectionSchemaName,
|
connectionSchemaName,
|
||||||
extraKeywords,
|
|
||||||
typeInfoSet,
|
|
||||||
supportsRefCursors,
|
supportsRefCursors,
|
||||||
supportsNamedParameters,
|
supportsNamedParameters,
|
||||||
supportsScrollableResults,
|
supportsScrollableResults,
|
||||||
|
@ -325,9 +262,54 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
|
||||||
supportsDataDefinitionInTransaction,
|
supportsDataDefinitionInTransaction,
|
||||||
doesDataDefinitionCauseTransactionCommit,
|
doesDataDefinitionCauseTransactionCommit,
|
||||||
sqlStateType,
|
sqlStateType,
|
||||||
lobLocatorUpdateCopy,
|
jdbcMetadataIsAccessible
|
||||||
sequenceInformationList
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the sequence information List from the database.
|
||||||
|
*
|
||||||
|
* @return sequence information List
|
||||||
|
*/
|
||||||
|
private List<SequenceInformation> sequenceInformationList() {
|
||||||
|
final JdbcEnvironment jdbcEnvironment = this.jdbcEnvironment;
|
||||||
|
final Dialect dialect = this.jdbcEnvironment.getDialect();
|
||||||
|
|
||||||
|
Connection connection = null;
|
||||||
|
try {
|
||||||
|
connection = connectionAccess.obtainConnection();
|
||||||
|
final Connection c = connection;
|
||||||
|
Iterable<SequenceInformation> sequenceInformationIterable = dialect
|
||||||
|
.getSequenceInformationExtractor()
|
||||||
|
.extractMetadata( new ExtractionContext.EmptyExtractionContext() {
|
||||||
|
@Override
|
||||||
|
public Connection getJdbcConnection() {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JdbcEnvironment getJdbcEnvironment() {
|
||||||
|
return jdbcEnvironment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return StreamSupport.stream( sequenceInformationIterable.spliterator(), false )
|
||||||
|
.collect( Collectors.toList() );
|
||||||
|
}
|
||||||
|
catch (SQLException e) {
|
||||||
|
throw new HibernateException( "Could not fetch the SequenceInformation from the database", e );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if ( connection != null ) {
|
||||||
|
try {
|
||||||
|
connectionAccess.releaseConnection( connection );
|
||||||
|
}
|
||||||
|
catch (SQLException throwables) {
|
||||||
|
//ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,17 +6,8 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.engine.jdbc.env.internal;
|
package org.hibernate.engine.jdbc.env.internal;
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DatabaseMetaData;
|
import java.sql.DatabaseMetaData;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.StreamSupport;
|
|
||||||
|
|
||||||
import org.hibernate.boot.model.naming.Identifier;
|
import org.hibernate.boot.model.naming.Identifier;
|
||||||
import org.hibernate.boot.registry.selector.spi.StrategySelector;
|
import org.hibernate.boot.registry.selector.spi.StrategySelector;
|
||||||
|
@ -24,6 +15,7 @@ import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||||
import org.hibernate.engine.config.spi.StandardConverters;
|
import org.hibernate.engine.config.spi.StandardConverters;
|
||||||
|
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||||
import org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData;
|
import org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData;
|
||||||
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
|
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
|
||||||
import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
|
import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
|
||||||
|
@ -33,7 +25,6 @@ import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport;
|
||||||
import org.hibernate.engine.jdbc.env.spi.QualifiedObjectNameFormatter;
|
import org.hibernate.engine.jdbc.env.spi.QualifiedObjectNameFormatter;
|
||||||
import org.hibernate.engine.jdbc.env.spi.SchemaNameResolver;
|
import org.hibernate.engine.jdbc.env.spi.SchemaNameResolver;
|
||||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||||
import org.hibernate.engine.jdbc.spi.TypeInfo;
|
|
||||||
import org.hibernate.exception.internal.SQLExceptionTypeDelegate;
|
import org.hibernate.exception.internal.SQLExceptionTypeDelegate;
|
||||||
import org.hibernate.exception.internal.SQLStateConversionDelegate;
|
import org.hibernate.exception.internal.SQLStateConversionDelegate;
|
||||||
import org.hibernate.exception.internal.StandardSQLExceptionConverter;
|
import org.hibernate.exception.internal.StandardSQLExceptionConverter;
|
||||||
|
@ -41,8 +32,6 @@ import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
import org.hibernate.tool.schema.extract.spi.ExtractionContext;
|
|
||||||
import org.hibernate.tool.schema.extract.spi.SequenceInformation;
|
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
@ -64,7 +53,6 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
||||||
private final QualifiedObjectNameFormatter qualifiedObjectNameFormatter;
|
private final QualifiedObjectNameFormatter qualifiedObjectNameFormatter;
|
||||||
private final LobCreatorBuilderImpl lobCreatorBuilder;
|
private final LobCreatorBuilderImpl lobCreatorBuilder;
|
||||||
|
|
||||||
private final LinkedHashSet<TypeInfo> typeInfoSet = new LinkedHashSet<>();
|
|
||||||
private final NameQualifierSupport nameQualifierSupport;
|
private final NameQualifierSupport nameQualifierSupport;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,7 +61,7 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
||||||
* @param serviceRegistry The service registry
|
* @param serviceRegistry The service registry
|
||||||
* @param dialect The resolved dialect.
|
* @param dialect The resolved dialect.
|
||||||
*/
|
*/
|
||||||
public JdbcEnvironmentImpl(final ServiceRegistryImplementor serviceRegistry, Dialect dialect) {
|
public JdbcEnvironmentImpl(final ServiceRegistryImplementor serviceRegistry, final Dialect dialect) {
|
||||||
this.dialect = dialect;
|
this.dialect = dialect;
|
||||||
|
|
||||||
this.sqlAstTranslatorFactory = resolveSqlAstTranslatorFactory( dialect );
|
this.sqlAstTranslatorFactory = resolveSqlAstTranslatorFactory( dialect );
|
||||||
|
@ -97,7 +85,7 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
||||||
identifierHelperBuilder.setNameQualifierSupport( nameQualifierSupport );
|
identifierHelperBuilder.setNameQualifierSupport( nameQualifierSupport );
|
||||||
|
|
||||||
IdentifierHelper identifierHelper = null;
|
IdentifierHelper identifierHelper = null;
|
||||||
ExtractedDatabaseMetaDataImpl.Builder dbMetaDataBuilder = new ExtractedDatabaseMetaDataImpl.Builder( this );
|
ExtractedDatabaseMetaDataImpl.Builder dbMetaDataBuilder = new ExtractedDatabaseMetaDataImpl.Builder( this, false, null );
|
||||||
try {
|
try {
|
||||||
identifierHelper = dialect.buildIdentifierHelper( identifierHelperBuilder, null );
|
identifierHelper = dialect.buildIdentifierHelper( identifierHelperBuilder, null );
|
||||||
dbMetaDataBuilder.setSupportsNamedParameters( dialect.supportsNamedParameters( null ) );
|
dbMetaDataBuilder.setSupportsNamedParameters( dialect.supportsNamedParameters( null ) );
|
||||||
|
@ -169,8 +157,12 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
||||||
* Constructor form used from testing
|
* Constructor form used from testing
|
||||||
*
|
*
|
||||||
* @param dialect The dialect
|
* @param dialect The dialect
|
||||||
|
* @param jdbcConnectionAccess
|
||||||
*/
|
*/
|
||||||
public JdbcEnvironmentImpl(DatabaseMetaData databaseMetaData, Dialect dialect) throws SQLException {
|
public JdbcEnvironmentImpl(
|
||||||
|
DatabaseMetaData databaseMetaData,
|
||||||
|
Dialect dialect,
|
||||||
|
JdbcConnectionAccess jdbcConnectionAccess) throws SQLException {
|
||||||
this.dialect = dialect;
|
this.dialect = dialect;
|
||||||
|
|
||||||
this.sqlAstTranslatorFactory = resolveSqlAstTranslatorFactory( dialect );
|
this.sqlAstTranslatorFactory = resolveSqlAstTranslatorFactory( dialect );
|
||||||
|
@ -198,10 +190,9 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
||||||
}
|
}
|
||||||
this.identifierHelper = identifierHelper;
|
this.identifierHelper = identifierHelper;
|
||||||
|
|
||||||
this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl.Builder( this )
|
this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl.Builder( this, true, jdbcConnectionAccess )
|
||||||
.apply( databaseMetaData )
|
.apply( databaseMetaData )
|
||||||
.setSupportsNamedParameters( databaseMetaData.supportsNamedParameters() )
|
.setSupportsNamedParameters( databaseMetaData.supportsNamedParameters() )
|
||||||
.setSequenceInformationList( sequenceInformationList( databaseMetaData.getConnection() ) )
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
this.currentCatalog = null;
|
this.currentCatalog = null;
|
||||||
|
@ -233,6 +224,20 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated currently used by Hibernate Reactive
|
||||||
|
* This version of the constructor should handle the case in which we do actually have the option to access the DatabaseMetaData,
|
||||||
|
* but since Hibernate Reactive is currently not making use of it we take a shortcut.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public JdbcEnvironmentImpl(
|
||||||
|
ServiceRegistryImplementor serviceRegistry,
|
||||||
|
Dialect dialect,
|
||||||
|
DatabaseMetaData databaseMetaData
|
||||||
|
/*JdbcConnectionAccess jdbcConnectionAccess*/) throws SQLException {
|
||||||
|
this(serviceRegistry, dialect);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main constructor form. Builds a JdbcEnvironment using the available DatabaseMetaData
|
* The main constructor form. Builds a JdbcEnvironment using the available DatabaseMetaData
|
||||||
*
|
*
|
||||||
|
@ -245,7 +250,8 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
||||||
public JdbcEnvironmentImpl(
|
public JdbcEnvironmentImpl(
|
||||||
ServiceRegistryImplementor serviceRegistry,
|
ServiceRegistryImplementor serviceRegistry,
|
||||||
Dialect dialect,
|
Dialect dialect,
|
||||||
DatabaseMetaData databaseMetaData) throws SQLException {
|
DatabaseMetaData databaseMetaData,
|
||||||
|
JdbcConnectionAccess jdbcConnectionAccess) throws SQLException {
|
||||||
this.dialect = dialect;
|
this.dialect = dialect;
|
||||||
|
|
||||||
this.sqlAstTranslatorFactory = resolveSqlAstTranslatorFactory( dialect );
|
this.sqlAstTranslatorFactory = resolveSqlAstTranslatorFactory( dialect );
|
||||||
|
@ -279,11 +285,10 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
||||||
}
|
}
|
||||||
this.identifierHelper = identifierHelper;
|
this.identifierHelper = identifierHelper;
|
||||||
|
|
||||||
this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl.Builder( this )
|
this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl.Builder( this, true, jdbcConnectionAccess )
|
||||||
.apply( databaseMetaData )
|
.apply( databaseMetaData )
|
||||||
.setConnectionSchemaName( determineCurrentSchemaName( databaseMetaData, serviceRegistry, dialect ) )
|
.setConnectionSchemaName( determineCurrentSchemaName( databaseMetaData, serviceRegistry, dialect ) )
|
||||||
.setSupportsNamedParameters( dialect.supportsNamedParameters( databaseMetaData ) )
|
.setSupportsNamedParameters( dialect.supportsNamedParameters( databaseMetaData ) )
|
||||||
.setSequenceInformationList( sequenceInformationList( databaseMetaData.getConnection() ) )
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// and that current-catalog and current-schema happen after it
|
// and that current-catalog and current-schema happen after it
|
||||||
|
@ -295,8 +300,6 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
||||||
databaseMetaData
|
databaseMetaData
|
||||||
);
|
);
|
||||||
|
|
||||||
this.typeInfoSet.addAll( TypeInfo.extractTypeInfo( databaseMetaData ) );
|
|
||||||
|
|
||||||
this.lobCreatorBuilder = LobCreatorBuilderImpl.makeLobCreatorBuilder(
|
this.lobCreatorBuilder = LobCreatorBuilderImpl.makeLobCreatorBuilder(
|
||||||
dialect,
|
dialect,
|
||||||
cfgService.getSettings(),
|
cfgService.getSettings(),
|
||||||
|
@ -309,7 +312,7 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
||||||
private String determineCurrentSchemaName(
|
private String determineCurrentSchemaName(
|
||||||
DatabaseMetaData databaseMetaData,
|
DatabaseMetaData databaseMetaData,
|
||||||
ServiceRegistry serviceRegistry,
|
ServiceRegistry serviceRegistry,
|
||||||
Dialect dialect) throws SQLException {
|
Dialect dialect) {
|
||||||
final SchemaNameResolver schemaNameResolver;
|
final SchemaNameResolver schemaNameResolver;
|
||||||
|
|
||||||
final Object setting = serviceRegistry.getService( ConfigurationService.class ).getSettings().get(
|
final Object setting = serviceRegistry.getService( ConfigurationService.class ).getSettings().get(
|
||||||
|
@ -344,14 +347,6 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
||||||
return new SqlExceptionHelper( sqlExceptionConverter, logWarnings );
|
return new SqlExceptionHelper( sqlExceptionConverter, logWarnings );
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<String> buildMergedReservedWords(Dialect dialect, DatabaseMetaData dbmd) throws SQLException {
|
|
||||||
Set<String> reservedWords = new HashSet<>();
|
|
||||||
reservedWords.addAll( dialect.getKeywords() );
|
|
||||||
// todo : do we need to explicitly handle SQL:2003 keywords?
|
|
||||||
Collections.addAll( reservedWords, dbmd.getSQLKeywords().split( "," ) );
|
|
||||||
return reservedWords;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dialect getDialect() {
|
public Dialect getDialect() {
|
||||||
return dialect;
|
return dialect;
|
||||||
|
@ -402,47 +397,4 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
||||||
return lobCreatorBuilder;
|
return lobCreatorBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeInfo getTypeInfoForJdbcCode(int jdbcTypeCode) {
|
|
||||||
for ( TypeInfo typeInfo : typeInfoSet ) {
|
|
||||||
if ( typeInfo.getJdbcTypeCode() == jdbcTypeCode ) {
|
|
||||||
return typeInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the sequence information List from the database.
|
|
||||||
*
|
|
||||||
* @param connection database connection
|
|
||||||
* @return sequence information List
|
|
||||||
*/
|
|
||||||
private List<SequenceInformation> sequenceInformationList(final Connection connection) {
|
|
||||||
try {
|
|
||||||
|
|
||||||
Iterable<SequenceInformation> sequenceInformationIterable = dialect
|
|
||||||
.getSequenceInformationExtractor()
|
|
||||||
.extractMetadata( new ExtractionContext.EmptyExtractionContext() {
|
|
||||||
@Override
|
|
||||||
public Connection getJdbcConnection() {
|
|
||||||
return connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JdbcEnvironment getJdbcEnvironment() {
|
|
||||||
return JdbcEnvironmentImpl.this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return StreamSupport.stream( sequenceInformationIterable.spliterator(), false )
|
|
||||||
.collect( Collectors.toList() );
|
|
||||||
}
|
|
||||||
catch (SQLException e) {
|
|
||||||
log.error( "Could not fetch the SequenceInformation from the database", e );
|
|
||||||
}
|
|
||||||
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,7 +149,12 @@ public class JdbcEnvironmentInitiator implements StandardServiceInitiator<JdbcEn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return new JdbcEnvironmentImpl( registry, dialect, dbmd );
|
return new JdbcEnvironmentImpl(
|
||||||
|
registry,
|
||||||
|
dialect,
|
||||||
|
dbmd,
|
||||||
|
jdbcConnectionAccess
|
||||||
|
);
|
||||||
}
|
}
|
||||||
catch (SQLException e) {
|
catch (SQLException e) {
|
||||||
log.unableToObtainConnectionMetadata( e );
|
log.unableToObtainConnectionMetadata( e );
|
||||||
|
|
|
@ -44,24 +44,6 @@ public interface ExtractedDatabaseMetaData {
|
||||||
*/
|
*/
|
||||||
String getConnectionSchemaName();
|
String getConnectionSchemaName();
|
||||||
|
|
||||||
/**
|
|
||||||
* Set of type info reported by the driver.
|
|
||||||
*
|
|
||||||
* @return The type information obtained from the driver.
|
|
||||||
*
|
|
||||||
* @see java.sql.DatabaseMetaData#getTypeInfo()
|
|
||||||
*/
|
|
||||||
LinkedHashSet<TypeInfo> getTypeInfoSet();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the list of extra keywords (beyond standard SQL92 keywords) reported by the driver.
|
|
||||||
*
|
|
||||||
* @return The extra keywords used by this database.
|
|
||||||
*
|
|
||||||
* @see java.sql.DatabaseMetaData#getSQLKeywords()
|
|
||||||
*/
|
|
||||||
Set<String> getExtraKeywords();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does the driver report supporting named parameters?
|
* Does the driver report supporting named parameters?
|
||||||
*
|
*
|
||||||
|
@ -135,15 +117,6 @@ public interface ExtractedDatabaseMetaData {
|
||||||
*/
|
*/
|
||||||
SQLStateType getSqlStateType();
|
SQLStateType getSqlStateType();
|
||||||
|
|
||||||
/**
|
|
||||||
* Did the driver report that updates to a LOB locator affect a copy of the LOB?
|
|
||||||
*
|
|
||||||
* @return True if updates to the state of a LOB locator update only a copy.
|
|
||||||
*
|
|
||||||
* @see java.sql.DatabaseMetaData#locatorsUpdateCopy()
|
|
||||||
*/
|
|
||||||
boolean doesLobLocatorUpdateCopy();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the list of {@code SequenceInformation} objects which describe the underlying database sequences.
|
* Retrieve the list of {@code SequenceInformation} objects which describe the underlying database sequences.
|
||||||
*
|
*
|
||||||
|
|
|
@ -63,6 +63,10 @@ public class IdentifierHelperBuilder {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Important optimisation: skip loading all keywords from the DB when autoQuoteKeywords is disabled
|
||||||
|
if ( autoQuoteKeywords == false ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.reservedWords.addAll( parseKeywords( metaData.getSQLKeywords() ) );
|
this.reservedWords.addAll( parseKeywords( metaData.getSQLKeywords() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,6 +186,10 @@ public class IdentifierHelperBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void applyReservedWords(Collection<String> words) {
|
public void applyReservedWords(Collection<String> words) {
|
||||||
|
//No use when autoQuoteKeywords is disabled
|
||||||
|
if ( autoQuoteKeywords == false ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.reservedWords.addAll( words );
|
this.reservedWords.addAll( words );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,11 +93,12 @@ public interface JdbcEnvironment extends Service {
|
||||||
LobCreatorBuilder getLobCreatorBuilder();
|
LobCreatorBuilder getLobCreatorBuilder();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find type information for the type identified by the given "JDBC type code".
|
* @deprecated This is currently not implemented an will likely be removed
|
||||||
*
|
* (A default method is provided to facilitate removal from implementors)
|
||||||
* @param jdbcTypeCode The JDBC type code.
|
|
||||||
*
|
|
||||||
* @return The corresponding type info.
|
|
||||||
*/
|
*/
|
||||||
TypeInfo getTypeInfoForJdbcCode(int jdbcTypeCode);
|
@Deprecated
|
||||||
|
default TypeInfo getTypeInfoForJdbcCode(int jdbcTypeCode) {
|
||||||
|
throw new UnsupportedOperationException( "Support for getting TypeInfo from jdbcTypeCode has been disabled as it wasn't used. Use org.hibernate.engine.jdbc.spi.TypeInfo.extractTypeInfo as alternative, or report an issue and explain." );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,13 @@ public enum SequenceMismatchStrategy {
|
||||||
* When detecting a mismatch, Hibernate tries to fix it by overriding the entity sequence mapping using the one
|
* When detecting a mismatch, Hibernate tries to fix it by overriding the entity sequence mapping using the one
|
||||||
* found in the database.
|
* found in the database.
|
||||||
*/
|
*/
|
||||||
FIX;
|
FIX,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Don't perform any check. This is useful to speedup bootstrap as it won't query the sequences on the DB,
|
||||||
|
* at cost of not validating the sequences.
|
||||||
|
*/
|
||||||
|
NONE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interpret the configured SequenceMismatchStrategy value.
|
* Interpret the configured SequenceMismatchStrategy value.
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.util.Properties;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.boot.SchemaAutoTooling;
|
||||||
import org.hibernate.boot.model.naming.Identifier;
|
import org.hibernate.boot.model.naming.Identifier;
|
||||||
import org.hibernate.boot.model.relational.Database;
|
import org.hibernate.boot.model.relational.Database;
|
||||||
import org.hibernate.boot.model.relational.QualifiedName;
|
import org.hibernate.boot.model.relational.QualifiedName;
|
||||||
|
@ -200,19 +201,20 @@ public class SequenceStyleGenerator
|
||||||
|
|
||||||
final boolean isPooledOptimizer = OptimizerFactory.isPooledOptimizer( optimizationStrategy );
|
final boolean isPooledOptimizer = OptimizerFactory.isPooledOptimizer( optimizationStrategy );
|
||||||
|
|
||||||
if ( isPooledOptimizer && isPhysicalSequence( jdbcEnvironment, forceTableUse ) ) {
|
|
||||||
|
SequenceMismatchStrategy sequenceMismatchStrategy = configurationService.getSetting(
|
||||||
|
AvailableSettings.SEQUENCE_INCREMENT_SIZE_MISMATCH_STRATEGY,
|
||||||
|
SequenceMismatchStrategy::interpret,
|
||||||
|
SequenceMismatchStrategy.EXCEPTION
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( sequenceMismatchStrategy != SequenceMismatchStrategy.NONE && isPooledOptimizer && isPhysicalSequence( jdbcEnvironment, forceTableUse ) ) {
|
||||||
String databaseSequenceName = sequenceName.getObjectName().getText();
|
String databaseSequenceName = sequenceName.getObjectName().getText();
|
||||||
Long databaseIncrementValue = getSequenceIncrementValue( jdbcEnvironment, databaseSequenceName );
|
Long databaseIncrementValue = getSequenceIncrementValue( jdbcEnvironment, databaseSequenceName );
|
||||||
|
|
||||||
if ( databaseIncrementValue != null && !databaseIncrementValue.equals( (long) incrementSize ) ) {
|
if ( databaseIncrementValue != null && !databaseIncrementValue.equals( (long) incrementSize ) ) {
|
||||||
int dbIncrementValue = databaseIncrementValue.intValue();
|
int dbIncrementValue = databaseIncrementValue.intValue();
|
||||||
|
|
||||||
SequenceMismatchStrategy sequenceMismatchStrategy = configurationService.getSetting(
|
|
||||||
AvailableSettings.SEQUENCE_INCREMENT_SIZE_MISMATCH_STRATEGY,
|
|
||||||
SequenceMismatchStrategy::interpret,
|
|
||||||
SequenceMismatchStrategy.EXCEPTION
|
|
||||||
);
|
|
||||||
|
|
||||||
switch ( sequenceMismatchStrategy ) {
|
switch ( sequenceMismatchStrategy ) {
|
||||||
case EXCEPTION:
|
case EXCEPTION:
|
||||||
throw new MappingException(
|
throw new MappingException(
|
||||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.metamodel.internal;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -25,6 +26,7 @@ import org.hibernate.Internal;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.internal.EntityManagerMessageLogger;
|
import org.hibernate.internal.EntityManagerMessageLogger;
|
||||||
import org.hibernate.internal.HEMLogging;
|
import org.hibernate.internal.HEMLogging;
|
||||||
|
import org.hibernate.internal.log.DeprecationLogger;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
import org.hibernate.internal.util.ReflectHelper;
|
||||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.mapping.Component;
|
import org.hibernate.mapping.Component;
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.dialect.pagination.Oracle12LimitHandler;
|
||||||
|
import org.hibernate.engine.spi.QueryParameters;
|
||||||
|
import org.hibernate.engine.spi.RowSelection;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
@TestForIssue( jiraKey = "HHH-14649")
|
||||||
|
public class Oracle12LimitHandlerTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSqlWithSpace() {
|
||||||
|
final String sql = "select p.name from Person p where p.id = 1 for update";
|
||||||
|
final String expected = "select * from ( select p.name from Person p where p.id = 1 ) where rownum <= ? for update";
|
||||||
|
|
||||||
|
final QueryParameters queryParameters = getQueryParameters( 0, 5 );
|
||||||
|
final String processedSql = Oracle12LimitHandler.INSTANCE.processSql( sql, queryParameters );
|
||||||
|
|
||||||
|
assertEquals( expected, processedSql );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSqlWithSpaceInsideQuotedString() {
|
||||||
|
final String sql = "select p.name from Person p where p.name = ' this is a string with spaces ' for update";
|
||||||
|
final String expected = "select * from ( select p.name from Person p where p.name = ' this is a string with spaces ' ) where rownum <= ? for update";
|
||||||
|
|
||||||
|
final QueryParameters queryParameters = getQueryParameters( 0, 5 );
|
||||||
|
final String processedSql = Oracle12LimitHandler.INSTANCE.processSql( sql, queryParameters );
|
||||||
|
|
||||||
|
assertEquals( expected, processedSql );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSqlWithForUpdateInsideQuotedString() {
|
||||||
|
final String sql = "select a.prop from A a where a.name = 'this is for update '";
|
||||||
|
final String expected = "select a.prop from A a where a.name = 'this is for update ' fetch first ? rows only";
|
||||||
|
|
||||||
|
final QueryParameters queryParameters = getQueryParameters( 0, 5 );
|
||||||
|
final String processedSql = Oracle12LimitHandler.INSTANCE.processSql( sql, queryParameters );
|
||||||
|
|
||||||
|
assertEquals( expected, processedSql );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSqlWithForUpdateInsideAndOutsideQuotedStringA() {
|
||||||
|
final String sql = "select a.prop from A a where a.name = 'this is for update ' for update";
|
||||||
|
final String expected = "select * from ( select a.prop from A a where a.name = 'this is for update ' ) where rownum <= ? for update";
|
||||||
|
|
||||||
|
final QueryParameters queryParameters = getQueryParameters( 0, 5 );
|
||||||
|
final String processedSql = Oracle12LimitHandler.INSTANCE.processSql( sql, queryParameters );
|
||||||
|
|
||||||
|
assertEquals( expected, processedSql );
|
||||||
|
}
|
||||||
|
|
||||||
|
private QueryParameters getQueryParameters(int firstRow, int maxRow) {
|
||||||
|
final QueryParameters queryParameters = new QueryParameters();
|
||||||
|
RowSelection rowSelection = new RowSelection();
|
||||||
|
rowSelection.setFirstRow( firstRow );
|
||||||
|
rowSelection.setMaxRows( maxRow );
|
||||||
|
queryParameters.setRowSelection( rowSelection );
|
||||||
|
return queryParameters;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.engine.jdbc.env.internal;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
|
import org.hibernate.cfg.Environment;
|
||||||
|
import org.hibernate.dialect.H2Dialect;
|
||||||
|
import org.hibernate.id.SequenceMismatchStrategy;
|
||||||
|
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies that setting {@code AvailableSettings.SEQUENCE_INCREMENT_SIZE_MISMATCH_STRATEGY} to {@code none}
|
||||||
|
* is going to skip loading the sequence information from the database.
|
||||||
|
*/
|
||||||
|
@TestForIssue( jiraKey = "HHH-14667")
|
||||||
|
public class SkipLoadingSequenceInformationTest extends BaseCoreFunctionalTestCase {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(Configuration configuration) {
|
||||||
|
configuration.setProperty( AvailableSettings.SEQUENCE_INCREMENT_SIZE_MISMATCH_STRATEGY, SequenceMismatchStrategy.NONE.name() );
|
||||||
|
configuration.setProperty( Environment.DIALECT, VetoingDialect.class.getName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name="seqentity")
|
||||||
|
static class SequencingEntity {
|
||||||
|
@Id
|
||||||
|
@GenericGenerator(name = "pooledoptimizer", strategy = "enhanced-sequence",
|
||||||
|
parameters = {
|
||||||
|
@org.hibernate.annotations.Parameter(name = "optimizer", value = "pooled"),
|
||||||
|
@org.hibernate.annotations.Parameter(name = "initial_value", value = "1"),
|
||||||
|
@org.hibernate.annotations.Parameter(name = "increment_size", value = "2")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "pooledoptimizer")
|
||||||
|
Integer id;
|
||||||
|
String name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class[]{SequencingEntity.class};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
// If it's able to boot, we're good.
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class VetoingDialect extends H2Dialect {
|
||||||
|
@Override
|
||||||
|
public SequenceInformationExtractor getSequenceInformationExtractor() {
|
||||||
|
throw new IllegalStateException("Should really not invoke this method in this setup");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -38,8 +38,6 @@ public class NoDatabaseMetaDataTest extends BaseUnitTestCase {
|
||||||
|
|
||||||
assertNull( extractedDatabaseMetaData.getConnectionCatalogName() );
|
assertNull( extractedDatabaseMetaData.getConnectionCatalogName() );
|
||||||
assertNull( extractedDatabaseMetaData.getConnectionSchemaName() );
|
assertNull( extractedDatabaseMetaData.getConnectionSchemaName() );
|
||||||
assertTrue( extractedDatabaseMetaData.getTypeInfoSet().isEmpty() );
|
|
||||||
assertTrue( extractedDatabaseMetaData.getExtraKeywords().isEmpty() );
|
|
||||||
assertFalse( extractedDatabaseMetaData.supportsNamedParameters() );
|
assertFalse( extractedDatabaseMetaData.supportsNamedParameters() );
|
||||||
assertFalse( extractedDatabaseMetaData.supportsRefCursors() );
|
assertFalse( extractedDatabaseMetaData.supportsRefCursors() );
|
||||||
assertFalse( extractedDatabaseMetaData.supportsScrollableResults() );
|
assertFalse( extractedDatabaseMetaData.supportsScrollableResults() );
|
||||||
|
@ -48,7 +46,6 @@ public class NoDatabaseMetaDataTest extends BaseUnitTestCase {
|
||||||
assertFalse( extractedDatabaseMetaData.supportsDataDefinitionInTransaction() );
|
assertFalse( extractedDatabaseMetaData.supportsDataDefinitionInTransaction() );
|
||||||
assertFalse( extractedDatabaseMetaData.doesDataDefinitionCauseTransactionCommit() );
|
assertFalse( extractedDatabaseMetaData.doesDataDefinitionCauseTransactionCommit() );
|
||||||
assertNull( extractedDatabaseMetaData.getSqlStateType() );
|
assertNull( extractedDatabaseMetaData.getSqlStateType() );
|
||||||
assertFalse( extractedDatabaseMetaData.doesLobLocatorUpdateCopy() );
|
|
||||||
|
|
||||||
StandardServiceRegistryBuilder.destroy( serviceRegistry );
|
StandardServiceRegistryBuilder.destroy( serviceRegistry );
|
||||||
}
|
}
|
||||||
|
@ -65,8 +62,6 @@ public class NoDatabaseMetaDataTest extends BaseUnitTestCase {
|
||||||
|
|
||||||
assertNull( extractedDatabaseMetaData.getConnectionCatalogName() );
|
assertNull( extractedDatabaseMetaData.getConnectionCatalogName() );
|
||||||
assertNull( extractedDatabaseMetaData.getConnectionSchemaName() );
|
assertNull( extractedDatabaseMetaData.getConnectionSchemaName() );
|
||||||
assertTrue( extractedDatabaseMetaData.getTypeInfoSet().isEmpty() );
|
|
||||||
assertTrue( extractedDatabaseMetaData.getExtraKeywords().isEmpty() );
|
|
||||||
assertTrue( extractedDatabaseMetaData.supportsNamedParameters() );
|
assertTrue( extractedDatabaseMetaData.supportsNamedParameters() );
|
||||||
assertFalse( extractedDatabaseMetaData.supportsRefCursors() );
|
assertFalse( extractedDatabaseMetaData.supportsRefCursors() );
|
||||||
assertFalse( extractedDatabaseMetaData.supportsScrollableResults() );
|
assertFalse( extractedDatabaseMetaData.supportsScrollableResults() );
|
||||||
|
@ -75,7 +70,6 @@ public class NoDatabaseMetaDataTest extends BaseUnitTestCase {
|
||||||
assertFalse( extractedDatabaseMetaData.supportsDataDefinitionInTransaction() );
|
assertFalse( extractedDatabaseMetaData.supportsDataDefinitionInTransaction() );
|
||||||
assertFalse( extractedDatabaseMetaData.doesDataDefinitionCauseTransactionCommit() );
|
assertFalse( extractedDatabaseMetaData.doesDataDefinitionCauseTransactionCommit() );
|
||||||
assertNull( extractedDatabaseMetaData.getSqlStateType() );
|
assertNull( extractedDatabaseMetaData.getSqlStateType() );
|
||||||
assertFalse( extractedDatabaseMetaData.doesLobLocatorUpdateCopy() );
|
|
||||||
|
|
||||||
StandardServiceRegistryBuilder.destroy( serviceRegistry );
|
StandardServiceRegistryBuilder.destroy( serviceRegistry );
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,19 +6,16 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.orm.test.schemafilter;
|
package org.hibernate.orm.test.schemafilter;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.GenerationType;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.SequenceGenerator;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import javax.persistence.Entity;
|
||||||
import org.hamcrest.BaseMatcher;
|
import javax.persistence.GeneratedValue;
|
||||||
import org.hamcrest.Description;
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.SequenceGenerator;
|
||||||
|
|
||||||
import org.hibernate.boot.Metadata;
|
import org.hibernate.boot.Metadata;
|
||||||
import org.hibernate.boot.MetadataSources;
|
import org.hibernate.boot.MetadataSources;
|
||||||
|
@ -34,22 +31,23 @@ import org.hibernate.tool.schema.internal.SchemaCreatorImpl;
|
||||||
import org.hibernate.tool.schema.internal.SchemaDropperImpl;
|
import org.hibernate.tool.schema.internal.SchemaDropperImpl;
|
||||||
import org.hibernate.tool.schema.spi.SchemaFilter;
|
import org.hibernate.tool.schema.spi.SchemaFilter;
|
||||||
|
|
||||||
|
import org.hibernate.testing.RequiresDialect;
|
||||||
|
import org.hibernate.testing.ServiceRegistryBuilder;
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.hibernate.testing.DialectChecks;
|
import org.hamcrest.BaseMatcher;
|
||||||
import org.hibernate.testing.RequiresDialectFeature;
|
import org.hamcrest.Description;
|
||||||
import org.hibernate.testing.ServiceRegistryBuilder;
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
|
||||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Andrea Boriero
|
* @author Andrea Boriero
|
||||||
*/
|
*/
|
||||||
@TestForIssue(jiraKey = "HHH-10937")
|
@TestForIssue(jiraKey = "HHH-10937")
|
||||||
@RequiresDialectFeature(value = {DialectChecks.SupportSchemaCreation.class})
|
@RequiresDialect(H2Dialect.class)
|
||||||
public class SequenceFilterTest extends BaseUnitTestCase {
|
public class SequenceFilterTest extends BaseUnitTestCase {
|
||||||
private StandardServiceRegistryImpl serviceRegistry;
|
private StandardServiceRegistryImpl serviceRegistry;
|
||||||
private Metadata metadata;
|
private Metadata metadata;
|
||||||
|
@ -59,6 +57,7 @@ public class SequenceFilterTest extends BaseUnitTestCase {
|
||||||
Map settings = new HashMap();
|
Map settings = new HashMap();
|
||||||
settings.putAll( Environment.getProperties() );
|
settings.putAll( Environment.getProperties() );
|
||||||
settings.put( AvailableSettings.DIALECT, H2Dialect.class.getName() );
|
settings.put( AvailableSettings.DIALECT, H2Dialect.class.getName() );
|
||||||
|
settings.put( "hibernate.temp.use_jdbc_metadata_defaults", "false" );
|
||||||
settings.put( AvailableSettings.FORMAT_SQL, false );
|
settings.put( AvailableSettings.FORMAT_SQL, false );
|
||||||
|
|
||||||
this.serviceRegistry = ServiceRegistryBuilder.buildServiceRegistry( settings );
|
this.serviceRegistry = ServiceRegistryBuilder.buildServiceRegistry( settings );
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.dialect.SQLServer2012Dialect;
|
import org.hibernate.dialect.SQLServer2012Dialect;
|
||||||
|
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||||
import org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl;
|
import org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl;
|
||||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||||
|
@ -82,15 +83,16 @@ public class SQLServerDialectSequenceInformationTest extends BaseUnitTestCase {
|
||||||
ssrb.applySettings( Collections.singletonMap( AvailableSettings.URL, newUrl ) );
|
ssrb.applySettings( Collections.singletonMap( AvailableSettings.URL, newUrl ) );
|
||||||
StandardServiceRegistry ssr = ssrb.build();
|
StandardServiceRegistry ssr = ssrb.build();
|
||||||
|
|
||||||
try ( Connection connection = ssr.getService( JdbcServices.class )
|
final JdbcConnectionAccess bootstrapJdbcConnectionAccess = ssr.getService( JdbcServices.class )
|
||||||
.getBootstrapJdbcConnectionAccess()
|
.getBootstrapJdbcConnectionAccess();
|
||||||
.obtainConnection() ) {
|
|
||||||
|
try ( Connection connection = bootstrapJdbcConnectionAccess.obtainConnection() ) {
|
||||||
|
|
||||||
try (Statement statement = connection.createStatement()) {
|
try (Statement statement = connection.createStatement()) {
|
||||||
statement.execute( "CREATE SEQUENCE ITEM_SEQ START WITH 100 INCREMENT BY 10" );
|
statement.execute( "CREATE SEQUENCE ITEM_SEQ START WITH 100 INCREMENT BY 10" );
|
||||||
}
|
}
|
||||||
|
|
||||||
JdbcEnvironment jdbcEnvironment = new JdbcEnvironmentImpl( connection.getMetaData(), dialect );
|
JdbcEnvironment jdbcEnvironment = new JdbcEnvironmentImpl( connection.getMetaData(), dialect, bootstrapJdbcConnectionAccess );
|
||||||
Iterable<SequenceInformation> sequenceInformations = SequenceInformationExtractorLegacyImpl.INSTANCE.extractMetadata(
|
Iterable<SequenceInformation> sequenceInformations = SequenceInformationExtractorLegacyImpl.INSTANCE.extractMetadata(
|
||||||
new ExtractionContext.EmptyExtractionContext() {
|
new ExtractionContext.EmptyExtractionContext() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -93,6 +93,30 @@ public class OraclePaginationWithLocksTest {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNativeQueryWithSpaces(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction( session -> {
|
||||||
|
final List<Person> people = session.createNativeQuery(
|
||||||
|
"select p.name from Person p where p.id = 1 for update" )
|
||||||
|
.setMaxResults( 10 )
|
||||||
|
.list();
|
||||||
|
} );
|
||||||
|
|
||||||
|
scope.inTransaction( session -> {
|
||||||
|
Person p = new Person();
|
||||||
|
p.setName( " this is a string with spaces " );
|
||||||
|
session.persist( p );
|
||||||
|
} );
|
||||||
|
|
||||||
|
scope.inTransaction( session -> {
|
||||||
|
final List<Person> people = session.createNativeQuery(
|
||||||
|
"select p.name from Person p where p.name = ' this is a string with spaces ' for update" )
|
||||||
|
.setMaxResults( 10 )
|
||||||
|
.list();
|
||||||
|
assertEquals( 1, people.size() );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCriteriaQuery(SessionFactoryScope scope) {
|
public void testCriteriaQuery(SessionFactoryScope scope) {
|
||||||
scope.inTransaction(
|
scope.inTransaction(
|
||||||
|
|
|
@ -56,10 +56,11 @@ public class BasicTestingJdbcServiceImpl implements JdbcServices, ServiceRegistr
|
||||||
dialect = ConnectionProviderBuilder.getCorrespondingDialect();
|
dialect = ConnectionProviderBuilder.getCorrespondingDialect();
|
||||||
connectionProvider = ConnectionProviderBuilder.buildConnectionProvider( allowAggressiveRelease );
|
connectionProvider = ConnectionProviderBuilder.buildConnectionProvider( allowAggressiveRelease );
|
||||||
sqlStatementLogger = new SqlStatementLogger( true, false, false );
|
sqlStatementLogger = new SqlStatementLogger( true, false, false );
|
||||||
|
this.jdbcConnectionAccess = new JdbcConnectionAccessImpl( connectionProvider );
|
||||||
|
|
||||||
Connection jdbcConnection = connectionProvider.getConnection();
|
Connection jdbcConnection = connectionProvider.getConnection();
|
||||||
try {
|
try {
|
||||||
jdbcEnvironment = new JdbcEnvironmentImpl( jdbcConnection.getMetaData(), dialect );
|
jdbcEnvironment = new JdbcEnvironmentImpl( jdbcConnection.getMetaData(), dialect, jdbcConnectionAccess );
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
try {
|
try {
|
||||||
|
@ -69,7 +70,6 @@ public class BasicTestingJdbcServiceImpl implements JdbcServices, ServiceRegistr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.jdbcConnectionAccess = new JdbcConnectionAccessImpl( connectionProvider );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void release() {
|
public void release() {
|
||||||
|
|
Loading…
Reference in New Issue