HHH-15489 - Remove support for Oracle versions older than 11.2
Signed-off-by: Jan Schatteman <jschatte@redhat.com>
This commit is contained in:
parent
6321016051
commit
89a98f2dc7
|
@ -147,7 +147,7 @@ public class ExplicitLockingTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@RequiresDialect(value = OracleDialect.class, majorVersion = 8)
|
@RequiresDialect(value = OracleDialect.class)
|
||||||
public void testFollowOnLocking(EntityManagerFactoryScope scope) {
|
public void testFollowOnLocking(EntityManagerFactoryScope scope) {
|
||||||
scope.inTransaction( entityManager -> {
|
scope.inTransaction( entityManager -> {
|
||||||
log.info("testBuildLockRequest");
|
log.info("testBuildLockRequest");
|
||||||
|
|
|
@ -21,7 +21,7 @@ import org.junit.jupiter.api.Test;
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
*/
|
*/
|
||||||
@RequiresDialect(value = OracleDialect.class, majorVersion = 8)
|
@RequiresDialect(value = OracleDialect.class)
|
||||||
@Jpa(
|
@Jpa(
|
||||||
annotatedClasses = RowIdTest.Product.class
|
annotatedClasses = RowIdTest.Product.class
|
||||||
)
|
)
|
||||||
|
|
|
@ -34,7 +34,7 @@ import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
*/
|
*/
|
||||||
@RequiresDialect(value = OracleDialect.class, majorVersion = 8)
|
@RequiresDialect(value = OracleDialect.class)
|
||||||
@Jpa(
|
@Jpa(
|
||||||
annotatedClasses = OracleCustomSQLWithStoredProcedureTest.Person.class
|
annotatedClasses = OracleCustomSQLWithStoredProcedureTest.Person.class
|
||||||
)
|
)
|
||||||
|
|
|
@ -38,7 +38,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
*/
|
*/
|
||||||
@RequiresDialect(value = OracleDialect.class, majorVersion = 8)
|
@RequiresDialect(value = OracleDialect.class)
|
||||||
@Jpa(
|
@Jpa(
|
||||||
annotatedClasses = {
|
annotatedClasses = {
|
||||||
Person.class,
|
Person.class,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,501 @@
|
||||||
|
/*
|
||||||
|
* 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.community.dialect;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.internal.util.collections.Stack;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||||
|
import org.hibernate.query.IllegalQueryOperationException;
|
||||||
|
import org.hibernate.query.sqm.BinaryArithmeticOperator;
|
||||||
|
import org.hibernate.query.sqm.ComparisonOperator;
|
||||||
|
import org.hibernate.query.sqm.FetchClauseType;
|
||||||
|
import org.hibernate.query.sqm.FrameExclusion;
|
||||||
|
import org.hibernate.query.sqm.FrameKind;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.FunctionExpression;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Literal;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Over;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.SqlTuple;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Summarization;
|
||||||
|
import org.hibernate.sql.ast.tree.from.FunctionTableReference;
|
||||||
|
import org.hibernate.sql.ast.tree.from.QueryPartTableReference;
|
||||||
|
import org.hibernate.sql.ast.tree.from.UnionTableGroup;
|
||||||
|
import org.hibernate.sql.ast.tree.from.ValuesTableReference;
|
||||||
|
import org.hibernate.sql.ast.tree.insert.InsertStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.insert.Values;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryGroup;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
|
import org.hibernate.sql.ast.tree.select.SelectClause;
|
||||||
|
import org.hibernate.sql.ast.tree.select.SortSpecification;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
import org.hibernate.type.SqlTypes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for Oracle.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class OracleLegacySqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public OracleLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected LockStrategy determineLockingStrategy(
|
||||||
|
QuerySpec querySpec,
|
||||||
|
ForUpdateClause forUpdateClause,
|
||||||
|
Boolean followOnLocking) {
|
||||||
|
LockStrategy strategy = super.determineLockingStrategy( querySpec, forUpdateClause, followOnLocking );
|
||||||
|
final boolean followOnLockingDisabled = Boolean.FALSE.equals( followOnLocking );
|
||||||
|
if ( strategy != LockStrategy.FOLLOW_ON && querySpec.hasSortSpecifications() ) {
|
||||||
|
if ( followOnLockingDisabled ) {
|
||||||
|
throw new IllegalQueryOperationException( "Locking with ORDER BY is not supported" );
|
||||||
|
}
|
||||||
|
strategy = LockStrategy.FOLLOW_ON;
|
||||||
|
}
|
||||||
|
// Oracle also doesn't support locks with set operators
|
||||||
|
// See https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_10002.htm#i2066346
|
||||||
|
if ( strategy != LockStrategy.FOLLOW_ON && isPartOfQueryGroup() ) {
|
||||||
|
if ( followOnLockingDisabled ) {
|
||||||
|
throw new IllegalQueryOperationException( "Locking with set operators is not supported" );
|
||||||
|
}
|
||||||
|
strategy = LockStrategy.FOLLOW_ON;
|
||||||
|
}
|
||||||
|
if ( strategy != LockStrategy.FOLLOW_ON && hasSetOperations( querySpec ) ) {
|
||||||
|
if ( followOnLockingDisabled ) {
|
||||||
|
throw new IllegalQueryOperationException( "Locking with set operators is not supported" );
|
||||||
|
}
|
||||||
|
strategy = LockStrategy.FOLLOW_ON;
|
||||||
|
}
|
||||||
|
if ( strategy != LockStrategy.FOLLOW_ON && useOffsetFetchClause( querySpec ) && !isRowsOnlyFetchClauseType( querySpec ) ) {
|
||||||
|
if ( followOnLockingDisabled ) {
|
||||||
|
throw new IllegalQueryOperationException( "Locking with FETCH is not supported" );
|
||||||
|
}
|
||||||
|
strategy = LockStrategy.FOLLOW_ON;
|
||||||
|
}
|
||||||
|
if ( strategy != LockStrategy.FOLLOW_ON ) {
|
||||||
|
final boolean hasOffset;
|
||||||
|
if ( querySpec.isRoot() && hasLimit() && getLimit().getFirstRow() != null ) {
|
||||||
|
hasOffset = true;
|
||||||
|
// We must record that the generated SQL depends on the fact that there is an offset
|
||||||
|
addAppliedParameterBinding( getOffsetParameter(), null );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hasOffset = querySpec.getOffsetClauseExpression() != null;
|
||||||
|
}
|
||||||
|
if ( hasOffset ) {
|
||||||
|
if ( followOnLockingDisabled ) {
|
||||||
|
throw new IllegalQueryOperationException( "Locking with OFFSET is not supported" );
|
||||||
|
}
|
||||||
|
strategy = LockStrategy.FOLLOW_ON;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasSetOperations(QuerySpec querySpec) {
|
||||||
|
return querySpec.getFromClause().queryTableGroups( group -> group instanceof UnionTableGroup ? group : null ) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isPartOfQueryGroup() {
|
||||||
|
return getQueryPartStack().findCurrentFirst( part -> part instanceof QueryGroup ? part : null ) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean shouldEmulateFetchClause(QueryPart queryPart) {
|
||||||
|
// Check if current query part is already row numbering to avoid infinite recursion
|
||||||
|
if (getQueryPartForRowNumbering() == queryPart) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final boolean hasLimit = queryPart.isRoot() && hasLimit() || queryPart.getFetchClauseExpression() != null
|
||||||
|
|| queryPart.getOffsetClauseExpression() != null;
|
||||||
|
if ( !hasLimit ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Even if Oracle supports the OFFSET/FETCH clause, there are conditions where we still want to use the ROWNUM pagination
|
||||||
|
if ( supportsOffsetFetchClause() ) {
|
||||||
|
// When the query has no sort specifications and offset, we want to use the ROWNUM pagination as that is a special locking case
|
||||||
|
return !queryPart.hasSortSpecifications() && !hasOffset( queryPart )
|
||||||
|
// Workaround an Oracle bug, segmentation fault for insert queries with a plain query group and fetch clause
|
||||||
|
|| queryPart instanceof QueryGroup && getClauseStack().isEmpty() && getStatement() instanceof InsertStatement;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FetchClauseType getFetchClauseTypeForRowNumbering(QueryPart queryPart) {
|
||||||
|
final FetchClauseType fetchClauseType = super.getFetchClauseTypeForRowNumbering( queryPart );
|
||||||
|
final boolean hasOffset;
|
||||||
|
if ( queryPart.isRoot() && hasLimit() ) {
|
||||||
|
hasOffset = getLimit().getFirstRow() != null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hasOffset = queryPart.getOffsetClauseExpression() != null;
|
||||||
|
}
|
||||||
|
if ( queryPart instanceof QuerySpec && !hasOffset && fetchClauseType == FetchClauseType.ROWS_ONLY ) {
|
||||||
|
// We return null here, because in this particular case, we render a special rownum query
|
||||||
|
// which can be seen in #emulateFetchOffsetWithWindowFunctions
|
||||||
|
// Note that we also build upon this in #visitOrderBy
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return fetchClauseType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void emulateFetchOffsetWithWindowFunctions(
|
||||||
|
QueryPart queryPart,
|
||||||
|
Expression offsetExpression,
|
||||||
|
Expression fetchExpression,
|
||||||
|
FetchClauseType fetchClauseType,
|
||||||
|
boolean emulateFetchClause) {
|
||||||
|
if ( queryPart instanceof QuerySpec && offsetExpression == null && fetchClauseType == FetchClauseType.ROWS_ONLY ) {
|
||||||
|
// Special case for Oracle to support locking along with simple max results paging
|
||||||
|
final QuerySpec querySpec = (QuerySpec) queryPart;
|
||||||
|
withRowNumbering(
|
||||||
|
querySpec,
|
||||||
|
true, // we need select aliases to avoid ORA-00918: column ambiguously defined
|
||||||
|
() -> {
|
||||||
|
final QueryPart currentQueryPart = getQueryPartStack().getCurrent();
|
||||||
|
final boolean needsParenthesis;
|
||||||
|
final boolean needsWrapper;
|
||||||
|
if ( currentQueryPart instanceof QueryGroup ) {
|
||||||
|
needsParenthesis = false;
|
||||||
|
// visitQuerySpec will add the select wrapper
|
||||||
|
needsWrapper = !currentQueryPart.hasOffsetOrFetchClause();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
needsParenthesis = !querySpec.isRoot();
|
||||||
|
needsWrapper = true;
|
||||||
|
}
|
||||||
|
if ( needsWrapper ) {
|
||||||
|
if ( needsParenthesis ) {
|
||||||
|
appendSql( '(' );
|
||||||
|
}
|
||||||
|
appendSql( "select * from " );
|
||||||
|
if ( !needsParenthesis ) {
|
||||||
|
appendSql( '(' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.visitQuerySpec( querySpec );
|
||||||
|
if ( needsWrapper ) {
|
||||||
|
if ( !needsParenthesis ) {
|
||||||
|
appendSql( ')' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
appendSql( " where rownum<=" );
|
||||||
|
final Stack<Clause> clauseStack = getClauseStack();
|
||||||
|
clauseStack.push( Clause.WHERE );
|
||||||
|
try {
|
||||||
|
fetchExpression.accept( this );
|
||||||
|
|
||||||
|
// We render the FOR UPDATE clause in the outer query
|
||||||
|
clauseStack.pop();
|
||||||
|
clauseStack.push( Clause.FOR_UPDATE );
|
||||||
|
visitForUpdateClause( querySpec );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
clauseStack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( needsWrapper ) {
|
||||||
|
if ( needsParenthesis ) {
|
||||||
|
appendSql( ')' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.emulateFetchOffsetWithWindowFunctions(
|
||||||
|
queryPart,
|
||||||
|
offsetExpression,
|
||||||
|
fetchExpression,
|
||||||
|
fetchClauseType,
|
||||||
|
emulateFetchClause
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void visitOrderBy(List<SortSpecification> sortSpecifications) {
|
||||||
|
// If we have a query part for row numbering, there is no need to render the order by clause
|
||||||
|
// as that is part of the row numbering window function already, by which we then order by in the outer query
|
||||||
|
final QueryPart queryPartForRowNumbering = getQueryPartForRowNumbering();
|
||||||
|
if ( queryPartForRowNumbering == null ) {
|
||||||
|
renderOrderBy( true, sortSpecifications );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// This logic is tightly coupled to #emulateFetchOffsetWithWindowFunctions and #getFetchClauseTypeForRowNumbering
|
||||||
|
// so that this is rendered when we end up in the special case for Oracle that renders a rownum filter
|
||||||
|
if ( getFetchClauseTypeForRowNumbering( queryPartForRowNumbering ) == null ) {
|
||||||
|
final QuerySpec querySpec = (QuerySpec) queryPartForRowNumbering;
|
||||||
|
if ( querySpec.getOffsetClauseExpression() == null
|
||||||
|
&& ( !querySpec.isRoot() || getOffsetParameter() == null ) ) {
|
||||||
|
// When rendering `rownum` for Oracle, we need to render the order by clause still
|
||||||
|
renderOrderBy( true, sortSpecifications );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void visitValuesList(List<Values> valuesList) {
|
||||||
|
if ( valuesList.size() < 2 ) {
|
||||||
|
super.visitValuesList( valuesList );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Oracle doesn't support a multi-values insert
|
||||||
|
// So we render a select union emulation instead
|
||||||
|
String separator = "";
|
||||||
|
final Stack<Clause> clauseStack = getClauseStack();
|
||||||
|
try {
|
||||||
|
clauseStack.push( Clause.VALUES );
|
||||||
|
for ( Values values : valuesList ) {
|
||||||
|
appendSql( separator );
|
||||||
|
renderExpressionsAsSubquery( values.getExpressions() );
|
||||||
|
separator = " union all ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
clauseStack.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitValuesTableReference(ValuesTableReference tableReference) {
|
||||||
|
emulateValuesTableReferenceColumnAliasing( tableReference );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQueryPartTableReference(QueryPartTableReference tableReference) {
|
||||||
|
emulateQueryPartTableReferenceColumnAliasing( tableReference );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitFunctionTableReference(FunctionTableReference tableReference) {
|
||||||
|
append( "table(" );
|
||||||
|
tableReference.getFunctionExpression().accept( this );
|
||||||
|
append( CLOSE_PARENTHESIS );
|
||||||
|
renderTableReferenceIdentificationVariable( tableReference );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQueryGroup(QueryGroup queryGroup) {
|
||||||
|
if ( shouldEmulateFetchClause( queryGroup ) ) {
|
||||||
|
emulateFetchOffsetWithWindowFunctions( queryGroup, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitQueryGroup( queryGroup );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQuerySpec(QuerySpec querySpec) {
|
||||||
|
if ( shouldEmulateFetchClause( querySpec ) ) {
|
||||||
|
emulateFetchOffsetWithWindowFunctions( querySpec, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitQuerySpec( querySpec );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
if ( !isRowNumberingCurrentQueryPart() ) {
|
||||||
|
if ( supportsOffsetFetchClause() ) {
|
||||||
|
renderOffsetFetchClause( queryPart, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assertRowsOnlyFetchClauseType( queryPart );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderRowNumber(SelectClause selectClause, QueryPart queryPart) {
|
||||||
|
if ( !queryPart.hasSortSpecifications() ) {
|
||||||
|
// Oracle doesn't allow an empty over clause for the row_number() function
|
||||||
|
appendSql( "rownum" );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.renderRowNumber( selectClause, queryPart );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOver(Over<?> over) {
|
||||||
|
final Expression expression = over.getExpression();
|
||||||
|
if ( expression instanceof FunctionExpression && "row_number".equals( ( (FunctionExpression) expression ).getFunctionName() ) ) {
|
||||||
|
if ( over.getPartitions().isEmpty() && over.getOrderList().isEmpty()
|
||||||
|
&& over.getStartKind() == FrameKind.UNBOUNDED_PRECEDING
|
||||||
|
&& over.getEndKind() == FrameKind.CURRENT_ROW
|
||||||
|
&& over.getExclusion() == FrameExclusion.NO_OTHERS ) {
|
||||||
|
// Oracle doesn't allow an empty over clause for the row_number() function
|
||||||
|
append( "rownum" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.visitOver( over );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderComparison(Expression lhs, ComparisonOperator operator, Expression rhs) {
|
||||||
|
final JdbcMappingContainer lhsExpressionType = lhs.getExpressionType();
|
||||||
|
if ( lhsExpressionType == null ) {
|
||||||
|
renderComparisonEmulateDecode( lhs, operator, rhs );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch ( lhsExpressionType.getJdbcMappings().get( 0 ).getJdbcType().getJdbcTypeCode() ) {
|
||||||
|
case SqlTypes.SQLXML:
|
||||||
|
// In Oracle, XMLTYPE is not "comparable", so we have to use the xmldiff function for this purpose
|
||||||
|
switch ( operator ) {
|
||||||
|
case EQUAL:
|
||||||
|
case NOT_DISTINCT_FROM:
|
||||||
|
appendSql( "0=" );
|
||||||
|
break;
|
||||||
|
case NOT_EQUAL:
|
||||||
|
case DISTINCT_FROM:
|
||||||
|
appendSql( "1=" );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
renderComparisonEmulateDecode( lhs, operator, rhs );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
appendSql( "existsnode(xmldiff(" );
|
||||||
|
lhs.accept( this );
|
||||||
|
appendSql( ',' );
|
||||||
|
rhs.accept( this );
|
||||||
|
appendSql( "),'/*[local-name()=''xdiff'']/*')" );
|
||||||
|
break;
|
||||||
|
case SqlTypes.BLOB:
|
||||||
|
// In Oracle, BLOB types are not "comparable", so we have to use the dbms_lob.compare function for this purpose
|
||||||
|
switch ( operator ) {
|
||||||
|
case EQUAL:
|
||||||
|
appendSql( "0=" );
|
||||||
|
break;
|
||||||
|
case NOT_EQUAL:
|
||||||
|
appendSql( "-1=" );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
renderComparisonEmulateDecode( lhs, operator, rhs );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
appendSql( "dbms_lob.compare(" );
|
||||||
|
lhs.accept( this );
|
||||||
|
appendSql( ',' );
|
||||||
|
rhs.accept( this );
|
||||||
|
appendSql( ')' );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
renderComparisonEmulateDecode( lhs, operator, rhs );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSelectTupleComparison(
|
||||||
|
List<SqlSelection> lhsExpressions,
|
||||||
|
SqlTuple tuple,
|
||||||
|
ComparisonOperator operator) {
|
||||||
|
emulateSelectTupleComparison( lhsExpressions, tuple.getExpressions(), operator, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void visitCaseSearchedExpression(CaseSearchedExpression caseSearchedExpression, boolean inSelect) {
|
||||||
|
// Oracle did not add support for CASE until 9i
|
||||||
|
if ( getDialect().getVersion().isBefore( 9 ) ) {
|
||||||
|
visitDecodeCaseSearchedExpression( caseSearchedExpression );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitCaseSearchedExpression( caseSearchedExpression, inSelect );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderPartitionItem(Expression expression) {
|
||||||
|
if ( expression instanceof Literal ) {
|
||||||
|
appendSql( "()" );
|
||||||
|
}
|
||||||
|
else if ( expression instanceof Summarization ) {
|
||||||
|
Summarization summarization = (Summarization) expression;
|
||||||
|
appendSql( summarization.getKind().sqlText() );
|
||||||
|
appendSql( OPEN_PARENTHESIS );
|
||||||
|
renderCommaSeparated( summarization.getGroupings() );
|
||||||
|
appendSql( CLOSE_PARENTHESIS );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
expression.accept( this );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean supportsDuplicateSelectItemsInQueryGroup() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean supportsRowValueConstructorSyntax() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean supportsRowValueConstructorSyntaxInInList() {
|
||||||
|
return getDialect().getVersion().isSameOrAfter( 8, 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean supportsRowValueConstructorSyntaxInQuantifiedPredicates() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean supportsRowValueConstructorSyntaxInInSubQuery() {
|
||||||
|
return getDialect().getVersion().isSameOrAfter( 9 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getFromDual() {
|
||||||
|
return " from dual";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getFromDualForSelectOnly() {
|
||||||
|
return getFromDual();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsOffsetFetchClause() {
|
||||||
|
return getDialect().supportsFetchClause( FetchClauseType.ROWS_ONLY );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitBinaryArithmeticExpression(BinaryArithmeticExpression arithmeticExpression) {
|
||||||
|
final BinaryArithmeticOperator operator = arithmeticExpression.getOperator();
|
||||||
|
if ( operator == BinaryArithmeticOperator.MODULO ) {
|
||||||
|
append( "mod" );
|
||||||
|
appendSql( OPEN_PARENTHESIS );
|
||||||
|
arithmeticExpression.getLeftHandOperand().accept( this );
|
||||||
|
appendSql( ',' );
|
||||||
|
arithmeticExpression.getRightHandOperand().accept( this );
|
||||||
|
appendSql( CLOSE_PARENTHESIS );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitBinaryArithmeticExpression( arithmeticExpression );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -113,12 +113,14 @@ public class OracleDialect extends Dialect {
|
||||||
|
|
||||||
public static final String PREFER_LONG_RAW = "hibernate.dialect.oracle.prefer_long_raw";
|
public static final String PREFER_LONG_RAW = "hibernate.dialect.oracle.prefer_long_raw";
|
||||||
|
|
||||||
|
private static final DatabaseVersion MINIMUM_VERSION = DatabaseVersion.make( 11, 2 );
|
||||||
|
|
||||||
private final LimitHandler limitHandler = supportsFetchClause( FetchClauseType.ROWS_ONLY )
|
private final LimitHandler limitHandler = supportsFetchClause( FetchClauseType.ROWS_ONLY )
|
||||||
? Oracle12LimitHandler.INSTANCE
|
? Oracle12LimitHandler.INSTANCE
|
||||||
: new LegacyOracleLimitHandler( getVersion() );
|
: new LegacyOracleLimitHandler( getVersion() );
|
||||||
|
|
||||||
public OracleDialect() {
|
public OracleDialect() {
|
||||||
this( DatabaseVersion.make( 8, 0 ) );
|
this( MINIMUM_VERSION );
|
||||||
}
|
}
|
||||||
|
|
||||||
public OracleDialect(DatabaseVersion version) {
|
public OracleDialect(DatabaseVersion version) {
|
||||||
|
@ -129,6 +131,11 @@ public class OracleDialect extends Dialect {
|
||||||
super(info);
|
super(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DatabaseVersion getMinimumSupportedVersion() {
|
||||||
|
return MINIMUM_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPreferredSqlTypeCodeForBoolean() {
|
public int getPreferredSqlTypeCodeForBoolean() {
|
||||||
return Types.BIT;
|
return Types.BIT;
|
||||||
|
@ -181,13 +188,8 @@ public class OracleDialect extends Dialect {
|
||||||
functionFactory.octetLength_pattern( "lengthb(?1)", "dbms_lob.getlength(?1)*2" );
|
functionFactory.octetLength_pattern( "lengthb(?1)", "dbms_lob.getlength(?1)*2" );
|
||||||
functionFactory.bitLength_pattern( "lengthb(?1)*8", "dbms_lob.getlength(?1)*16" );
|
functionFactory.bitLength_pattern( "lengthb(?1)*8", "dbms_lob.getlength(?1)*16" );
|
||||||
|
|
||||||
if ( getVersion().isBefore( 9 ) ) {
|
//Oracle has had coalesce() since 9.0.1
|
||||||
queryEngine.getSqmFunctionRegistry().register( "coalesce", new NvlCoalesceEmulation() );
|
functionFactory.coalesce();
|
||||||
}
|
|
||||||
else {
|
|
||||||
//Oracle has had coalesce() since 9.0.1
|
|
||||||
functionFactory.coalesce();
|
|
||||||
}
|
|
||||||
|
|
||||||
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
||||||
"locate",
|
"locate",
|
||||||
|
@ -240,7 +242,7 @@ public class OracleDialect extends Dialect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String currentDate() {
|
public String currentDate() {
|
||||||
return getVersion().isBefore( 9 ) ? currentTimestamp() : "current_date";
|
return "current_date";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -250,7 +252,7 @@ public class OracleDialect extends Dialect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String currentTimestamp() {
|
public String currentTimestamp() {
|
||||||
return getVersion().isBefore( 9 ) ? "sysdate" : currentTimestampWithTimeZone();
|
return currentTimestampWithTimeZone();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -260,12 +262,12 @@ public class OracleDialect extends Dialect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String currentLocalTimestamp() {
|
public String currentLocalTimestamp() {
|
||||||
return getVersion().isBefore( 9 ) ? currentTimestamp() : "localtimestamp";
|
return "localtimestamp";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String currentTimestampWithTimeZone() {
|
public String currentTimestampWithTimeZone() {
|
||||||
return getVersion().isBefore( 9 ) ? currentTimestamp() : "current_timestamp";
|
return "current_timestamp";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -578,15 +580,12 @@ public class OracleDialect extends Dialect {
|
||||||
case DATE:
|
case DATE:
|
||||||
case TIME:
|
case TIME:
|
||||||
return "date";
|
return "date";
|
||||||
case TIMESTAMP:
|
|
||||||
// the only difference between date and timestamp
|
// the only difference between date and timestamp
|
||||||
// on Oracle is that date has no fractional seconds
|
// on Oracle is that date has no fractional seconds
|
||||||
case TIMESTAMP_WITH_TIMEZONE:
|
|
||||||
return getVersion().isBefore( 9 ) ? "date" : super.columnType( sqlTypeCode );
|
|
||||||
case TIME_WITH_TIMEZONE:
|
case TIME_WITH_TIMEZONE:
|
||||||
return getVersion().isBefore( 9 ) ? "date" : "timestamp($p) with time zone";
|
return "timestamp($p) with time zone";
|
||||||
case VARCHAR:
|
case VARCHAR:
|
||||||
return getVersion().isBefore( 9 ) ? "varchar2($l)" : "varchar2($l char)";
|
return "varchar2($l char)";
|
||||||
case NVARCHAR:
|
case NVARCHAR:
|
||||||
return "nvarchar2($l)";
|
return "nvarchar2($l)";
|
||||||
case BINARY:
|
case BINARY:
|
||||||
|
@ -602,21 +601,18 @@ public class OracleDialect extends Dialect {
|
||||||
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
|
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
|
||||||
|
|
||||||
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( SQLXML, "SYS.XMLTYPE", this ) );
|
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( SQLXML, "SYS.XMLTYPE", this ) );
|
||||||
if ( getVersion().isSameOrAfter( 10 ) ) {
|
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( GEOMETRY, "MDSYS.SDO_GEOMETRY", this ) );
|
||||||
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( GEOMETRY, "MDSYS.SDO_GEOMETRY", this ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TimeZoneSupport getTimeZoneSupport() {
|
public TimeZoneSupport getTimeZoneSupport() {
|
||||||
return getVersion().isSameOrAfter( 9 ) ? TimeZoneSupport.NATIVE : TimeZoneSupport.NONE;
|
return TimeZoneSupport.NATIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initDefaultProperties() {
|
protected void initDefaultProperties() {
|
||||||
super.initDefaultProperties();
|
super.initDefaultProperties();
|
||||||
String newerVersion = Boolean.toString( getVersion().isSameOrAfter( 12 ) );
|
getDefaultProperties().setProperty( Environment.BATCH_VERSIONED_DATA, Boolean.toString( getVersion().isSameOrAfter( 12 ) ) );
|
||||||
getDefaultProperties().setProperty( Environment.BATCH_VERSIONED_DATA, newerVersion );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -764,32 +760,9 @@ public class OracleDialect extends Dialect {
|
||||||
return limitHandler;
|
return limitHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getSelectClauseNullString(int sqlType, TypeConfiguration typeConfiguration) {
|
|
||||||
if ( getVersion().isSameOrAfter( 9 ) ) {
|
|
||||||
return super.getSelectClauseNullString( sqlType, typeConfiguration );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
switch(sqlType) {
|
|
||||||
case Types.VARCHAR:
|
|
||||||
case Types.CHAR:
|
|
||||||
return "to_char(null)";
|
|
||||||
case Types.DATE:
|
|
||||||
case Types.TIME:
|
|
||||||
case Types.TIMESTAMP:
|
|
||||||
case Types.TIMESTAMP_WITH_TIMEZONE:
|
|
||||||
return "to_date(null)";
|
|
||||||
default:
|
|
||||||
return "to_number(null)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCurrentTimestampSelectString() {
|
public String getCurrentTimestampSelectString() {
|
||||||
return getVersion().isBefore( 9 )
|
return "select systimestamp from dual";
|
||||||
? "select sysdate from dual"
|
|
||||||
: "select systimestamp from dual";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1104,12 +1077,12 @@ public class OracleDialect extends Dialect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsNoWait() {
|
public boolean supportsNoWait() {
|
||||||
return getVersion().isSameOrAfter( 9 );
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsSkipLocked() {
|
public boolean supportsSkipLocked() {
|
||||||
return getVersion().isSameOrAfter( 10 );
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -414,17 +414,6 @@ public class OracleSqlAstTranslator<T extends JdbcOperation> extends AbstractSql
|
||||||
emulateSelectTupleComparison( lhsExpressions, tuple.getExpressions(), operator, true );
|
emulateSelectTupleComparison( lhsExpressions, tuple.getExpressions(), operator, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void visitCaseSearchedExpression(CaseSearchedExpression caseSearchedExpression, boolean inSelect) {
|
|
||||||
// Oracle did not add support for CASE until 9i
|
|
||||||
if ( getDialect().getVersion().isBefore( 9 ) ) {
|
|
||||||
visitDecodeCaseSearchedExpression( caseSearchedExpression );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
super.visitCaseSearchedExpression( caseSearchedExpression, inSelect );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void renderPartitionItem(Expression expression) {
|
protected void renderPartitionItem(Expression expression) {
|
||||||
if ( expression instanceof Literal ) {
|
if ( expression instanceof Literal ) {
|
||||||
|
@ -454,7 +443,7 @@ public class OracleSqlAstTranslator<T extends JdbcOperation> extends AbstractSql
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean supportsRowValueConstructorSyntaxInInList() {
|
protected boolean supportsRowValueConstructorSyntaxInInList() {
|
||||||
return getDialect().getVersion().isSameOrAfter( 8, 2 );
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -464,7 +453,7 @@ public class OracleSqlAstTranslator<T extends JdbcOperation> extends AbstractSql
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean supportsRowValueConstructorSyntaxInInSubQuery() {
|
protected boolean supportsRowValueConstructorSyntaxInInSubQuery() {
|
||||||
return getDialect().getVersion().isSameOrAfter( 9 );
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -24,7 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
xmlMappings = "org/hibernate/orm/test/generatedkeys/select/MyEntity.hbm.xml"
|
xmlMappings = "org/hibernate/orm/test/generatedkeys/select/MyEntity.hbm.xml"
|
||||||
)
|
)
|
||||||
@SessionFactory
|
@SessionFactory
|
||||||
@RequiresDialect(value = OracleDialect.class, majorVersion = 9)
|
@RequiresDialect(value = OracleDialect.class)
|
||||||
public class SelectGeneratorTest {
|
public class SelectGeneratorTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -34,7 +34,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
* @author Gail Badner
|
* @author Gail Badner
|
||||||
*/
|
*/
|
||||||
@SkipForDialect(dialectClass = MySQLDialect.class, majorVersion = 5, matchSubTypes = true, reason = "BLOB/TEXT column 'id' used in key specification without a key length")
|
@SkipForDialect(dialectClass = MySQLDialect.class, majorVersion = 5, matchSubTypes = true, reason = "BLOB/TEXT column 'id' used in key specification without a key length")
|
||||||
@SkipForDialect(dialectClass = OracleDialect.class, majorVersion = 9, matchSubTypes = true, reason = "ORA-02329: column of datatype LOB cannot be unique or a primary key")
|
@SkipForDialect(dialectClass = OracleDialect.class, matchSubTypes = true, reason = "ORA-02329: column of datatype LOB cannot be unique or a primary key")
|
||||||
@DomainModel(
|
@DomainModel(
|
||||||
annotatedClasses = ByteArrayIdTest.DemoEntity.class
|
annotatedClasses = ByteArrayIdTest.DemoEntity.class
|
||||||
)
|
)
|
||||||
|
|
|
@ -34,7 +34,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
* @author Gail Badner
|
* @author Gail Badner
|
||||||
*/
|
*/
|
||||||
@SkipForDialect(dialectClass = MySQLDialect.class, majorVersion = 5, reason = "BLOB/TEXT column 'id' used in key specification without a key length")
|
@SkipForDialect(dialectClass = MySQLDialect.class, majorVersion = 5, reason = "BLOB/TEXT column 'id' used in key specification without a key length")
|
||||||
@SkipForDialect(dialectClass = OracleDialect.class, majorVersion = 9, matchSubTypes = true, reason = "ORA-02329: column of datatype LOB cannot be unique or a primary key")
|
@SkipForDialect(dialectClass = OracleDialect.class, matchSubTypes = true, reason = "ORA-02329: column of datatype LOB cannot be unique or a primary key")
|
||||||
@DomainModel(
|
@DomainModel(
|
||||||
annotatedClasses = PrimitiveByteArrayIdTest.DemoEntity.class
|
annotatedClasses = PrimitiveByteArrayIdTest.DemoEntity.class
|
||||||
)
|
)
|
||||||
|
|
|
@ -21,7 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
@SkipForDialect(dialectClass = OracleDialect.class, majorVersion = 8, matchSubTypes = true,
|
@SkipForDialect(dialectClass = OracleDialect.class, matchSubTypes = true,
|
||||||
reason = "Oracle do not support identity key generation")
|
reason = "Oracle do not support identity key generation")
|
||||||
@SkipForDialect(dialectClass = AbstractHANADialect.class, matchSubTypes = true,
|
@SkipForDialect(dialectClass = AbstractHANADialect.class, matchSubTypes = true,
|
||||||
reason = "Hana do not support identity key generation")
|
reason = "Hana do not support identity key generation")
|
||||||
|
|
|
@ -28,7 +28,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
xmlMappings = "org/hibernate/orm/test/mapping/generated/ComponentOwner.hbm.xml"
|
xmlMappings = "org/hibernate/orm/test/mapping/generated/ComponentOwner.hbm.xml"
|
||||||
)
|
)
|
||||||
@SessionFactory
|
@SessionFactory
|
||||||
@RequiresDialect( value = OracleDialect.class, majorVersion = 9 )
|
@RequiresDialect( value = OracleDialect.class )
|
||||||
public class PartiallyGeneratedComponentTest {
|
public class PartiallyGeneratedComponentTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -35,7 +35,7 @@ import static org.hamcrest.core.Is.is;
|
||||||
@TestForIssue(jiraKey = "10495")
|
@TestForIssue(jiraKey = "10495")
|
||||||
@RequiresDialects(
|
@RequiresDialects(
|
||||||
value = {
|
value = {
|
||||||
@RequiresDialect(value = OracleDialect.class, majorVersion = 10),
|
@RequiresDialect(value = OracleDialect.class),
|
||||||
@RequiresDialect(value = PostgreSQLDialect.class, majorVersion = 8, minorVersion = 1)
|
@RequiresDialect(value = PostgreSQLDialect.class, majorVersion = 8, minorVersion = 1)
|
||||||
})
|
})
|
||||||
@DomainModel(
|
@DomainModel(
|
||||||
|
|
|
@ -18,7 +18,7 @@ import org.junit.jupiter.api.Test;
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
*/
|
*/
|
||||||
@RequiresDialect(value = OracleDialect.class, majorVersion = 9)
|
@RequiresDialect(value = OracleDialect.class)
|
||||||
@TestForIssue(jiraKey = "HHH-13104")
|
@TestForIssue(jiraKey = "HHH-13104")
|
||||||
@DomainModel(
|
@DomainModel(
|
||||||
xmlMappings = "org/hibernate/orm/test/ops/Competition.hbm.xml"
|
xmlMappings = "org/hibernate/orm/test/ops/Competition.hbm.xml"
|
||||||
|
|
|
@ -39,7 +39,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
/**
|
/**
|
||||||
* @author Brett Meyer
|
* @author Brett Meyer
|
||||||
*/
|
*/
|
||||||
@RequiresDialect(value = OracleDialect.class, majorVersion = 8)
|
@RequiresDialect(value = OracleDialect.class)
|
||||||
@DomainModel(
|
@DomainModel(
|
||||||
annotatedClasses = { OracleQueryHintTest.Employee.class, OracleQueryHintTest.Department.class }
|
annotatedClasses = { OracleQueryHintTest.Employee.class, OracleQueryHintTest.Department.class }
|
||||||
)
|
)
|
||||||
|
|
|
@ -33,7 +33,7 @@ import static org.junit.Assert.assertThat;
|
||||||
*/
|
*/
|
||||||
@DomainModel( annotatedClasses = RowIdTest.Product.class )
|
@DomainModel( annotatedClasses = RowIdTest.Product.class )
|
||||||
@SessionFactory(statementInspectorClass = SQLStatementInspector.class)
|
@SessionFactory(statementInspectorClass = SQLStatementInspector.class)
|
||||||
@RequiresDialect( value = OracleDialect.class, majorVersion = 9)
|
@RequiresDialect( value = OracleDialect.class)
|
||||||
public class RowIdTest {
|
public class RowIdTest {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
|
|
|
@ -26,7 +26,7 @@ import jakarta.persistence.criteria.CriteriaQuery;
|
||||||
/**
|
/**
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
@RequiresDialect(value = OracleDialect.class, majorVersion = 9)
|
@RequiresDialect(value = OracleDialect.class)
|
||||||
@DomainModel(
|
@DomainModel(
|
||||||
xmlMappings = "org/hibernate/orm/test/rowid/Point.hbm.xml"
|
xmlMappings = "org/hibernate/orm/test/rowid/Point.hbm.xml"
|
||||||
)
|
)
|
||||||
|
|
|
@ -37,7 +37,7 @@ import org.junit.jupiter.api.Test;
|
||||||
*
|
*
|
||||||
* @author Brett Meyer
|
* @author Brett Meyer
|
||||||
*/
|
*/
|
||||||
@RequiresDialect(value = OracleDialect.class, majorVersion = 9)
|
@RequiresDialect(value = OracleDialect.class)
|
||||||
public class SynonymValidationTest extends BaseSessionFactoryFunctionalTest {
|
public class SynonymValidationTest extends BaseSessionFactoryFunctionalTest {
|
||||||
|
|
||||||
private StandardServiceRegistry ssr;
|
private StandardServiceRegistry ssr;
|
||||||
|
|
|
@ -70,7 +70,7 @@ public class OrderedSequenceStructure extends SequenceStructure {
|
||||||
);
|
);
|
||||||
|
|
||||||
//noinspection deprecation
|
//noinspection deprecation
|
||||||
if ( dialect instanceof OracleDialect && dialect.getVersion().isSameOrAfter( 8 ) ) {
|
if ( dialect instanceof OracleDialect ) {
|
||||||
for ( int i = 0; i < createStrings.length; ++i ) {
|
for ( int i = 0; i < createStrings.length; ++i ) {
|
||||||
createStrings[i] = createStrings[i] + ORDER;
|
createStrings[i] = createStrings[i] + ORDER;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ public class SinglePropertyMapper extends AbstractPropertyMapper implements Simp
|
||||||
boolean dbLogicallyDifferent = true;
|
boolean dbLogicallyDifferent = true;
|
||||||
final Dialect dialect = session.getFactory().getJdbcServices()
|
final Dialect dialect = session.getFactory().getJdbcServices()
|
||||||
.getDialect();
|
.getDialect();
|
||||||
if ( ( dialect instanceof OracleDialect && dialect.getVersion().isSameOrAfter( 8 ) ) && (newObj instanceof String || oldObj instanceof String) ) {
|
if ( ( dialect instanceof OracleDialect ) && (newObj instanceof String || oldObj instanceof String) ) {
|
||||||
// Don't generate new revision when database replaces empty string with NULL during INSERT or UPDATE statements.
|
// Don't generate new revision when database replaces empty string with NULL during INSERT or UPDATE statements.
|
||||||
dbLogicallyDifferent = !(StringTools.isEmpty( newObj ) && StringTools.isEmpty( oldObj ));
|
dbLogicallyDifferent = !(StringTools.isEmpty( newObj ) && StringTools.isEmpty( oldObj ));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue