HHH-16541 Fix Sybase test issues and HSQLDB hanging
This commit is contained in:
parent
2d833133b6
commit
7823b48a3a
|
@ -124,7 +124,7 @@ public class SybaseASELegacySqlAstTranslator<T extends JdbcOperation> extends Ab
|
||||||
appendSql( UNION_ALL );
|
appendSql( UNION_ALL );
|
||||||
searchIndex = unionIndex + UNION_ALL.length();
|
searchIndex = unionIndex + UNION_ALL.length();
|
||||||
}
|
}
|
||||||
append( tableExpression, searchIndex, tableExpression.length() - 2 );
|
append( tableExpression, searchIndex, tableExpression.length() - 1 );
|
||||||
renderLockHint( lockMode );
|
renderLockHint( lockMode );
|
||||||
appendSql( " )" );
|
appendSql( " )" );
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.function.Consumer;
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.query.sqm.ComparisonOperator;
|
import org.hibernate.query.sqm.ComparisonOperator;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||||
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||||
|
@ -25,6 +26,7 @@ import org.hibernate.sql.ast.tree.expression.Literal;
|
||||||
import org.hibernate.sql.ast.tree.expression.SqlTuple;
|
import org.hibernate.sql.ast.tree.expression.SqlTuple;
|
||||||
import org.hibernate.sql.ast.tree.expression.Summarization;
|
import org.hibernate.sql.ast.tree.expression.Summarization;
|
||||||
import org.hibernate.sql.ast.tree.from.NamedTableReference;
|
import org.hibernate.sql.ast.tree.from.NamedTableReference;
|
||||||
|
import org.hibernate.sql.ast.tree.from.UnionTableReference;
|
||||||
import org.hibernate.sql.ast.tree.select.QueryPart;
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
import org.hibernate.sql.ast.tree.select.SelectClause;
|
import org.hibernate.sql.ast.tree.select.SelectClause;
|
||||||
|
@ -37,6 +39,8 @@ import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
*/
|
*/
|
||||||
public class SybaseAnywhereSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
public class SybaseAnywhereSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
private static final String UNION_ALL = " union all ";
|
||||||
|
|
||||||
public SybaseAnywhereSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
public SybaseAnywhereSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
super( sessionFactory, statement );
|
super( sessionFactory, statement );
|
||||||
}
|
}
|
||||||
|
@ -95,16 +99,48 @@ public class SybaseAnywhereSqlAstTranslator<T extends JdbcOperation> extends Abs
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean renderNamedTableReference(NamedTableReference tableReference, LockMode lockMode) {
|
protected boolean renderNamedTableReference(NamedTableReference tableReference, LockMode lockMode) {
|
||||||
super.renderNamedTableReference( tableReference, lockMode );
|
|
||||||
if ( getDialect().getVersion().isBefore( 10 ) ) {
|
if ( getDialect().getVersion().isBefore( 10 ) ) {
|
||||||
if ( LockMode.READ.lessThan( lockMode ) ) {
|
final String tableExpression = tableReference.getTableExpression();
|
||||||
appendSql( " holdlock" );
|
if ( tableReference instanceof UnionTableReference && lockMode != LockMode.NONE && tableExpression.charAt( 0 ) == '(' ) {
|
||||||
|
// SQL Server requires to push down the lock hint to the actual table names
|
||||||
|
int searchIndex = 0;
|
||||||
|
int unionIndex;
|
||||||
|
while ( ( unionIndex = tableExpression.indexOf( UNION_ALL, searchIndex ) ) != -1 ) {
|
||||||
|
append( tableExpression, searchIndex, unionIndex );
|
||||||
|
renderLockHint( lockMode );
|
||||||
|
appendSql( UNION_ALL );
|
||||||
|
searchIndex = unionIndex + UNION_ALL.length();
|
||||||
|
}
|
||||||
|
append( tableExpression, searchIndex, tableExpression.length() - 1 );
|
||||||
|
renderLockHint( lockMode );
|
||||||
|
appendSql( " )" );
|
||||||
|
|
||||||
|
registerAffectedTable( tableReference );
|
||||||
|
final Clause currentClause = getClauseStack().getCurrent();
|
||||||
|
if ( rendersTableReferenceAlias( currentClause ) ) {
|
||||||
|
final String identificationVariable = tableReference.getIdentificationVariable();
|
||||||
|
if ( identificationVariable != null ) {
|
||||||
|
appendSql( ' ' );
|
||||||
|
appendSql( identificationVariable );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
super.renderNamedTableReference( tableReference, lockMode );
|
||||||
|
renderLockHint( lockMode );
|
||||||
|
}
|
||||||
|
// Just always return true because SQL Server doesn't support the FOR UPDATE clause
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void renderLockHint(LockMode lockMode) {
|
||||||
|
if ( LockMode.READ.lessThan( lockMode ) ) {
|
||||||
|
appendSql( " holdlock" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void renderForUpdateClause(QuerySpec querySpec, ForUpdateClause forUpdateClause) {
|
protected void renderForUpdateClause(QuerySpec querySpec, ForUpdateClause forUpdateClause) {
|
||||||
if ( getDialect().getVersion().isBefore( 10 ) ) {
|
if ( getDialect().getVersion().isBefore( 10 ) ) {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.function.Consumer;
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.query.sqm.ComparisonOperator;
|
import org.hibernate.query.sqm.ComparisonOperator;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||||
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||||
|
@ -25,6 +26,7 @@ import org.hibernate.sql.ast.tree.expression.Literal;
|
||||||
import org.hibernate.sql.ast.tree.expression.SqlTuple;
|
import org.hibernate.sql.ast.tree.expression.SqlTuple;
|
||||||
import org.hibernate.sql.ast.tree.expression.Summarization;
|
import org.hibernate.sql.ast.tree.expression.Summarization;
|
||||||
import org.hibernate.sql.ast.tree.from.NamedTableReference;
|
import org.hibernate.sql.ast.tree.from.NamedTableReference;
|
||||||
|
import org.hibernate.sql.ast.tree.from.UnionTableReference;
|
||||||
import org.hibernate.sql.ast.tree.select.QueryPart;
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
import org.hibernate.sql.exec.spi.JdbcOperation;
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
@ -36,6 +38,8 @@ import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
*/
|
*/
|
||||||
public class SybaseLegacySqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
public class SybaseLegacySqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
private static final String UNION_ALL = " union all ";
|
||||||
|
|
||||||
public SybaseLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
public SybaseLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
super( sessionFactory, statement );
|
super( sessionFactory, statement );
|
||||||
}
|
}
|
||||||
|
@ -99,11 +103,43 @@ public class SybaseLegacySqlAstTranslator<T extends JdbcOperation> extends Abstr
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean renderNamedTableReference(NamedTableReference tableReference, LockMode lockMode) {
|
protected boolean renderNamedTableReference(NamedTableReference tableReference, LockMode lockMode) {
|
||||||
super.renderNamedTableReference( tableReference, lockMode );
|
final String tableExpression = tableReference.getTableExpression();
|
||||||
|
if ( tableReference instanceof UnionTableReference && lockMode != LockMode.NONE && tableExpression.charAt( 0 ) == '(' ) {
|
||||||
|
// SQL Server requires to push down the lock hint to the actual table names
|
||||||
|
int searchIndex = 0;
|
||||||
|
int unionIndex;
|
||||||
|
while ( ( unionIndex = tableExpression.indexOf( UNION_ALL, searchIndex ) ) != -1 ) {
|
||||||
|
append( tableExpression, searchIndex, unionIndex );
|
||||||
|
renderLockHint( lockMode );
|
||||||
|
appendSql( UNION_ALL );
|
||||||
|
searchIndex = unionIndex + UNION_ALL.length();
|
||||||
|
}
|
||||||
|
append( tableExpression, searchIndex, tableExpression.length() - 1 );
|
||||||
|
renderLockHint( lockMode );
|
||||||
|
appendSql( " )" );
|
||||||
|
|
||||||
|
registerAffectedTable( tableReference );
|
||||||
|
final Clause currentClause = getClauseStack().getCurrent();
|
||||||
|
if ( rendersTableReferenceAlias( currentClause ) ) {
|
||||||
|
final String identificationVariable = tableReference.getIdentificationVariable();
|
||||||
|
if ( identificationVariable != null ) {
|
||||||
|
appendSql( ' ' );
|
||||||
|
appendSql( identificationVariable );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.renderNamedTableReference( tableReference, lockMode );
|
||||||
|
renderLockHint( lockMode );
|
||||||
|
}
|
||||||
|
// Just always return true because SQL Server doesn't support the FOR UPDATE clause
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderLockHint(LockMode lockMode) {
|
||||||
if ( LockMode.READ.lessThan( lockMode ) ) {
|
if ( LockMode.READ.lessThan( lockMode ) ) {
|
||||||
appendSql( " holdlock" );
|
appendSql( " holdlock" );
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -124,7 +124,7 @@ public class SybaseASESqlAstTranslator<T extends JdbcOperation> extends Abstract
|
||||||
appendSql( UNION_ALL );
|
appendSql( UNION_ALL );
|
||||||
searchIndex = unionIndex + UNION_ALL.length();
|
searchIndex = unionIndex + UNION_ALL.length();
|
||||||
}
|
}
|
||||||
append( tableExpression, searchIndex, tableExpression.length() - 2 );
|
append( tableExpression, searchIndex, tableExpression.length() - 1 );
|
||||||
renderLockHint( lockMode );
|
renderLockHint( lockMode );
|
||||||
appendSql( " )" );
|
appendSql( " )" );
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,10 @@ import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
|
import org.hibernate.LockOptions;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.query.sqm.ComparisonOperator;
|
import org.hibernate.query.sqm.ComparisonOperator;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||||
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||||
|
@ -25,6 +27,7 @@ import org.hibernate.sql.ast.tree.expression.Literal;
|
||||||
import org.hibernate.sql.ast.tree.expression.SqlTuple;
|
import org.hibernate.sql.ast.tree.expression.SqlTuple;
|
||||||
import org.hibernate.sql.ast.tree.expression.Summarization;
|
import org.hibernate.sql.ast.tree.expression.Summarization;
|
||||||
import org.hibernate.sql.ast.tree.from.NamedTableReference;
|
import org.hibernate.sql.ast.tree.from.NamedTableReference;
|
||||||
|
import org.hibernate.sql.ast.tree.from.UnionTableReference;
|
||||||
import org.hibernate.sql.ast.tree.select.QueryPart;
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
import org.hibernate.sql.exec.spi.JdbcOperation;
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
@ -36,6 +39,8 @@ import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
*/
|
*/
|
||||||
public class SybaseSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
public class SybaseSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
private static final String UNION_ALL = " union all ";
|
||||||
|
|
||||||
public SybaseSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
public SybaseSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
super( sessionFactory, statement );
|
super( sessionFactory, statement );
|
||||||
}
|
}
|
||||||
|
@ -99,11 +104,43 @@ public class SybaseSqlAstTranslator<T extends JdbcOperation> extends AbstractSql
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean renderNamedTableReference(NamedTableReference tableReference, LockMode lockMode) {
|
protected boolean renderNamedTableReference(NamedTableReference tableReference, LockMode lockMode) {
|
||||||
super.renderNamedTableReference( tableReference, lockMode );
|
final String tableExpression = tableReference.getTableExpression();
|
||||||
|
if ( tableReference instanceof UnionTableReference && lockMode != LockMode.NONE && tableExpression.charAt( 0 ) == '(' ) {
|
||||||
|
// SQL Server requires to push down the lock hint to the actual table names
|
||||||
|
int searchIndex = 0;
|
||||||
|
int unionIndex;
|
||||||
|
while ( ( unionIndex = tableExpression.indexOf( UNION_ALL, searchIndex ) ) != -1 ) {
|
||||||
|
append( tableExpression, searchIndex, unionIndex );
|
||||||
|
renderLockHint( lockMode );
|
||||||
|
appendSql( UNION_ALL );
|
||||||
|
searchIndex = unionIndex + UNION_ALL.length();
|
||||||
|
}
|
||||||
|
append( tableExpression, searchIndex, tableExpression.length() - 1 );
|
||||||
|
renderLockHint( lockMode );
|
||||||
|
appendSql( " )" );
|
||||||
|
|
||||||
|
registerAffectedTable( tableReference );
|
||||||
|
final Clause currentClause = getClauseStack().getCurrent();
|
||||||
|
if ( rendersTableReferenceAlias( currentClause ) ) {
|
||||||
|
final String identificationVariable = tableReference.getIdentificationVariable();
|
||||||
|
if ( identificationVariable != null ) {
|
||||||
|
appendSql( ' ' );
|
||||||
|
appendSql( identificationVariable );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.renderNamedTableReference( tableReference, lockMode );
|
||||||
|
renderLockHint( lockMode );
|
||||||
|
}
|
||||||
|
// Just always return true because SQL Server doesn't support the FOR UPDATE clause
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderLockHint(LockMode lockMode) {
|
||||||
if ( LockMode.READ.lessThan( lockMode ) ) {
|
if ( LockMode.READ.lessThan( lockMode ) ) {
|
||||||
appendSql( " holdlock" );
|
appendSql( " holdlock" );
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -9,12 +9,14 @@ package org.hibernate.orm.test.locking.jpa;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.hibernate.dialect.HSQLDialect;
|
||||||
import org.hibernate.query.spi.QueryImplementor;
|
import org.hibernate.query.spi.QueryImplementor;
|
||||||
|
|
||||||
import org.hibernate.testing.jdbc.SQLStatementInspector;
|
import org.hibernate.testing.jdbc.SQLStatementInspector;
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.SkipForDialect;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@ -32,6 +34,7 @@ import static org.hibernate.jpa.SpecHints.HINT_SPEC_QUERY_TIMEOUT;
|
||||||
*/
|
*/
|
||||||
@DomainModel(annotatedClasses = { Employee.class, Department.class })
|
@DomainModel(annotatedClasses = { Employee.class, Department.class })
|
||||||
@SessionFactory(useCollectingStatementInspector = true)
|
@SessionFactory(useCollectingStatementInspector = true)
|
||||||
|
@SkipForDialect(dialectClass = HSQLDialect.class, reason = "Seems HSQLDB doesn't cancel the query if it waits for a lock?!")
|
||||||
public class FollowOnLockingTest {
|
public class FollowOnLockingTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue