HHH-15958 much better support for @RowId annotation
- the rowid pseudo-column and type are now determined automatically from Dialect - works (after all these years) in Postgres (and also on h2) - introduce RowIdJdbcType (not strictly necessary, but a nicety)
This commit is contained in:
parent
6da38d0b05
commit
689cca1963
|
@ -15,6 +15,9 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
/**
|
/**
|
||||||
* Specifies that an Oracle-style {@code rowid} should be used in SQL
|
* Specifies that an Oracle-style {@code rowid} should be used in SQL
|
||||||
* {@code update} statements for an entity, instead of the primary key.
|
* {@code update} statements for an entity, instead of the primary key.
|
||||||
|
* <p>
|
||||||
|
* If the {@linkplain org.hibernate.dialect.Dialect SQL dialect} does
|
||||||
|
* not support some sort of {@code rowid}, this annotation is ignored.
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
|
@ -25,6 +28,10 @@ public @interface RowId {
|
||||||
* Specifies the {@code rowid} identifier.
|
* Specifies the {@code rowid} identifier.
|
||||||
* <p>
|
* <p>
|
||||||
* For example, on Oracle, this should be just {@code "rowid"}.
|
* For example, on Oracle, this should be just {@code "rowid"}.
|
||||||
|
*
|
||||||
|
* @deprecated the {@code rowid} identifier is now inferred
|
||||||
|
* automatically from the {@link org.hibernate.dialect.Dialect}
|
||||||
*/
|
*/
|
||||||
String value();
|
@Deprecated(since = "6.2")
|
||||||
|
String value() default "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,6 +215,7 @@ import static org.hibernate.type.SqlTypes.NCLOB;
|
||||||
import static org.hibernate.type.SqlTypes.NUMERIC;
|
import static org.hibernate.type.SqlTypes.NUMERIC;
|
||||||
import static org.hibernate.type.SqlTypes.NVARCHAR;
|
import static org.hibernate.type.SqlTypes.NVARCHAR;
|
||||||
import static org.hibernate.type.SqlTypes.REAL;
|
import static org.hibernate.type.SqlTypes.REAL;
|
||||||
|
import static org.hibernate.type.SqlTypes.ROWID;
|
||||||
import static org.hibernate.type.SqlTypes.SMALLINT;
|
import static org.hibernate.type.SqlTypes.SMALLINT;
|
||||||
import static org.hibernate.type.SqlTypes.TIME;
|
import static org.hibernate.type.SqlTypes.TIME;
|
||||||
import static org.hibernate.type.SqlTypes.TIMESTAMP;
|
import static org.hibernate.type.SqlTypes.TIMESTAMP;
|
||||||
|
@ -4622,4 +4623,23 @@ public abstract class Dialect implements ConversionContext {
|
||||||
ServiceRegistryImplementor registry) {
|
ServiceRegistryImplementor registry) {
|
||||||
return new HibernateSchemaManagementTool();
|
return new HibernateSchemaManagementTool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of a {@code rowid}-like pseudo-column which
|
||||||
|
* acts as a high-performance row locator, or null if
|
||||||
|
* this dialect has no such pseudo-column.
|
||||||
|
*/
|
||||||
|
public String rowId() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The JDBC type code of the {@code rowid}-like pseudo-column
|
||||||
|
* which acts as a high-performance row locator.
|
||||||
|
*
|
||||||
|
* @return {@link Types#ROWID} by default
|
||||||
|
*/
|
||||||
|
public int rowIdSqlType() {
|
||||||
|
return ROWID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,7 @@ import jakarta.persistence.TemporalType;
|
||||||
|
|
||||||
import static org.hibernate.query.sqm.TemporalUnit.SECOND;
|
import static org.hibernate.query.sqm.TemporalUnit.SECOND;
|
||||||
import static org.hibernate.type.SqlTypes.ARRAY;
|
import static org.hibernate.type.SqlTypes.ARRAY;
|
||||||
|
import static org.hibernate.type.SqlTypes.BIGINT;
|
||||||
import static org.hibernate.type.SqlTypes.BINARY;
|
import static org.hibernate.type.SqlTypes.BINARY;
|
||||||
import static org.hibernate.type.SqlTypes.CHAR;
|
import static org.hibernate.type.SqlTypes.CHAR;
|
||||||
import static org.hibernate.type.SqlTypes.DECIMAL;
|
import static org.hibernate.type.SqlTypes.DECIMAL;
|
||||||
|
@ -856,4 +857,14 @@ public class H2Dialect extends Dialect {
|
||||||
public UniqueDelegate getUniqueDelegate() {
|
public UniqueDelegate getUniqueDelegate() {
|
||||||
return uniqueDelegate;
|
return uniqueDelegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String rowId() {
|
||||||
|
return "_rowid_";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int rowIdSqlType() {
|
||||||
|
return BIGINT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1406,4 +1406,9 @@ public class OracleDialect extends Dialect {
|
||||||
public String getCreateUserDefinedTypeKindString() {
|
public String getCreateUserDefinedTypeKindString() {
|
||||||
return "object";
|
return "object";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String rowId() {
|
||||||
|
return "rowid";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1349,7 +1349,17 @@ public class PostgreSQLDialect extends Dialect {
|
||||||
// disabled foreign key constraints still prevent 'truncate table'
|
// disabled foreign key constraints still prevent 'truncate table'
|
||||||
// (these would help if we used 'delete' instead of 'truncate')
|
// (these would help if we used 'delete' instead of 'truncate')
|
||||||
|
|
||||||
// @Override
|
@Override
|
||||||
|
public String rowId() {
|
||||||
|
return "ctid";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int rowIdSqlType() {
|
||||||
|
return OTHER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
// public String getDisableConstraintsStatement() {
|
// public String getDisableConstraintsStatement() {
|
||||||
// return "set constraints all deferred";
|
// return "set constraints all deferred";
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.mapping.internal;
|
package org.hibernate.metamodel.mapping.internal;
|
||||||
|
|
||||||
import java.sql.Types;
|
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.mapping.IndexedConsumer;
|
import org.hibernate.mapping.IndexedConsumer;
|
||||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
|
@ -41,9 +41,9 @@ public class EntityRowIdMappingImpl implements EntityRowIdMapping {
|
||||||
this.rowIdName = rowIdName;
|
this.rowIdName = rowIdName;
|
||||||
this.tableExpression = tableExpression;
|
this.tableExpression = tableExpression;
|
||||||
this.declaringType = declaringType;
|
this.declaringType = declaringType;
|
||||||
this.rowIdType = declaringType.getEntityPersister().getFactory().getTypeConfiguration()
|
final SessionFactoryImplementor factory = declaringType.getEntityPersister().getFactory();
|
||||||
.getBasicTypeRegistry()
|
this.rowIdType = factory.getTypeConfiguration().getBasicTypeRegistry()
|
||||||
.resolve( Object.class, Types.ROWID );
|
.resolve( Object.class, factory.getJdbcServices().getDialect().rowIdSqlType() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -544,7 +544,13 @@ public abstract class AbstractEntityPersister
|
||||||
rootTableKeyColumnReaderTemplates = new String[identifierColumnSpan];
|
rootTableKeyColumnReaderTemplates = new String[identifierColumnSpan];
|
||||||
identifierAliases = new String[identifierColumnSpan];
|
identifierAliases = new String[identifierColumnSpan];
|
||||||
|
|
||||||
rowIdName = persistentClass.getRootTable().getRowId();
|
final String rowId = persistentClass.getRootTable().getRowId();
|
||||||
|
if ( rowId == null ) {
|
||||||
|
rowIdName = null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rowIdName = rowId.isEmpty() ? dialect.rowId() : rowId;
|
||||||
|
}
|
||||||
|
|
||||||
if ( persistentClass.getLoaderName() != null ) {
|
if ( persistentClass.getLoaderName() != null ) {
|
||||||
// We must resolve the named query on-demand through the boot model because it isn't initialized yet
|
// We must resolve the named query on-demand through the boot model because it isn't initialized yet
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* 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.type.descriptor.jdbc;
|
||||||
|
|
||||||
|
import org.hibernate.type.SqlTypes;
|
||||||
|
import org.hibernate.type.descriptor.ValueBinder;
|
||||||
|
import org.hibernate.type.descriptor.ValueExtractor;
|
||||||
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
|
|
||||||
|
import java.sql.CallableStatement;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.RowId;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Types;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Descriptor for {@link Types#ROWID ROWID} handling.
|
||||||
|
*
|
||||||
|
* @author Gavin King
|
||||||
|
*/
|
||||||
|
public class RowIdJdbcType implements JdbcType {
|
||||||
|
public static final RowIdJdbcType INSTANCE = new RowIdJdbcType();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getJdbcTypeCode() {
|
||||||
|
return SqlTypes.ROWID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "RowIdJdbcType";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <X> ValueBinder<X> getBinder(JavaType<X> javaType) {
|
||||||
|
return new BasicBinder<>( javaType, this ) {
|
||||||
|
@Override
|
||||||
|
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
|
||||||
|
throws SQLException {
|
||||||
|
st.setRowId( index, getJavaType().unwrap( value, RowId.class, options ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doBind(CallableStatement st, X value, String name, WrapperOptions options)
|
||||||
|
throws SQLException {
|
||||||
|
st.setRowId( name, getJavaType().unwrap( value, RowId.class, options ) );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
|
||||||
|
return new BasicExtractor<>( javaType, this ) {
|
||||||
|
@Override
|
||||||
|
protected X doExtract(ResultSet rs, int paramIndex, WrapperOptions options) throws SQLException {
|
||||||
|
return getJavaType().wrap( rs.getRowId( paramIndex ), options );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected X doExtract(CallableStatement statement, int index, WrapperOptions options) throws SQLException {
|
||||||
|
return getJavaType().wrap( statement.getRowId( index ), options );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected X doExtract(CallableStatement statement, String name, WrapperOptions options) throws SQLException {
|
||||||
|
return getJavaType().wrap( statement.getObject( name ), options );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,7 +15,6 @@ import java.sql.Types;
|
||||||
import org.hibernate.type.descriptor.ValueBinder;
|
import org.hibernate.type.descriptor.ValueBinder;
|
||||||
import org.hibernate.type.descriptor.ValueExtractor;
|
import org.hibernate.type.descriptor.ValueExtractor;
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
import org.hibernate.type.descriptor.java.BasicJavaType;
|
|
||||||
import org.hibernate.type.descriptor.java.JavaType;
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
import org.hibernate.type.descriptor.jdbc.internal.JdbcLiteralFormatterNumericData;
|
import org.hibernate.type.descriptor.jdbc.internal.JdbcLiteralFormatterNumericData;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.hibernate.type.descriptor.jdbc.LongVarbinaryJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.LongVarcharJdbcType;
|
import org.hibernate.type.descriptor.jdbc.LongVarcharJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.NumericJdbcType;
|
import org.hibernate.type.descriptor.jdbc.NumericJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.RealJdbcType;
|
import org.hibernate.type.descriptor.jdbc.RealJdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.RowIdJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.SmallIntJdbcType;
|
import org.hibernate.type.descriptor.jdbc.SmallIntJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.TimeJdbcType;
|
import org.hibernate.type.descriptor.jdbc.TimeJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.TimestampJdbcType;
|
import org.hibernate.type.descriptor.jdbc.TimestampJdbcType;
|
||||||
|
@ -84,5 +85,7 @@ public class JdbcTypeBaseline {
|
||||||
target.addDescriptor( Types.LONGNVARCHAR, LongVarcharJdbcType.INSTANCE );
|
target.addDescriptor( Types.LONGNVARCHAR, LongVarcharJdbcType.INSTANCE );
|
||||||
target.addDescriptor( Types.NCLOB, ClobJdbcType.DEFAULT );
|
target.addDescriptor( Types.NCLOB, ClobJdbcType.DEFAULT );
|
||||||
target.addDescriptor( new LongVarcharJdbcType(SqlTypes.LONG32NVARCHAR) );
|
target.addDescriptor( new LongVarcharJdbcType(SqlTypes.LONG32NVARCHAR) );
|
||||||
|
|
||||||
|
target.addDescriptor( RowIdJdbcType.INSTANCE );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link java.sql.Types#DATALINK DATALINK}</li>
|
* <li>{@link java.sql.Types#DATALINK DATALINK}</li>
|
||||||
* <li>{@link java.sql.Types#DISTINCT DISTINCT}</li>
|
* <li>{@link java.sql.Types#DISTINCT DISTINCT}</li>
|
||||||
* <li>{@link java.sql.Types#ROWID ROWID}</li>
|
|
||||||
* <li>{@link java.sql.Types#REF REF}</li>
|
* <li>{@link java.sql.Types#REF REF}</li>
|
||||||
* <li>{@link java.sql.Types#REF_CURSOR REF_CURSOR}</li>
|
* <li>{@link java.sql.Types#REF_CURSOR REF_CURSOR}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
|
|
|
@ -13,11 +13,9 @@ import jakarta.persistence.Id;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
import org.hibernate.annotations.RowId;
|
import org.hibernate.annotations.RowId;
|
||||||
import org.hibernate.dialect.OracleDialect;
|
|
||||||
|
|
||||||
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.RequiresDialect;
|
|
||||||
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.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
@ -33,14 +31,13 @@ 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)
|
|
||||||
public class RowIdTest {
|
public class RowIdTest {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp(SessionFactoryScope scope) {
|
void setUp(SessionFactoryScope scope) {
|
||||||
scope.inTransaction( session -> {
|
scope.inTransaction( session -> {
|
||||||
Product product = new Product();
|
Product product = new Product();
|
||||||
product.setId( 1L );
|
product.setId( "1L" );
|
||||||
product.setName( "Mobile phone" );
|
product.setName( "Mobile phone" );
|
||||||
product.setNumber( "123-456-7890" );
|
product.setNumber( "123-456-7890" );
|
||||||
session.persist( product );
|
session.persist( product );
|
||||||
|
@ -51,15 +48,19 @@ public class RowIdTest {
|
||||||
void testRowId(SessionFactoryScope scope) {
|
void testRowId(SessionFactoryScope scope) {
|
||||||
final String updatedName = "Smart phone";
|
final String updatedName = "Smart phone";
|
||||||
scope.inTransaction( session -> {
|
scope.inTransaction( session -> {
|
||||||
|
String rowId = scope.getSessionFactory().getJdbcServices().getDialect().rowId();
|
||||||
|
|
||||||
SQLStatementInspector statementInspector = (SQLStatementInspector) scope.getStatementInspector();
|
SQLStatementInspector statementInspector = (SQLStatementInspector) scope.getStatementInspector();
|
||||||
statementInspector.clear();
|
statementInspector.clear();
|
||||||
|
|
||||||
Product product = session.find( Product.class, 1L );
|
Product product = session.find( Product.class, "1L" );
|
||||||
|
|
||||||
List<String> sqls = statementInspector.getSqlQueries();
|
List<String> sqls = statementInspector.getSqlQueries();
|
||||||
|
|
||||||
assertThat( sqls, hasSize( 1 ) );
|
assertThat( sqls, hasSize( 1 ) );
|
||||||
assertThat( sqls.get(0).matches( "(?i).*\\bselect\\b.+\\.ROWID.*\\bfrom\\s+product\\b.*" ), is( true ) );
|
assertThat( rowId == null
|
||||||
|
|| sqls.get(0).matches( "(?i).*\\bselect\\b.+\\." + rowId + ".*\\bfrom\\s+product\\b.*" ),
|
||||||
|
is( true ) );
|
||||||
|
|
||||||
assertThat( product.getName(), not( is( updatedName ) ) );
|
assertThat( product.getName(), not( is( updatedName ) ) );
|
||||||
|
|
||||||
|
@ -71,7 +72,9 @@ public class RowIdTest {
|
||||||
sqls = statementInspector.getSqlQueries();
|
sqls = statementInspector.getSqlQueries();
|
||||||
|
|
||||||
assertThat( sqls, hasSize( 1 ) );
|
assertThat( sqls, hasSize( 1 ) );
|
||||||
assertThat( sqls.get( 0 ).matches( "(?i).*\\bupdate\\s+product\\b.+?\\bwhere\\s+ROWID\\s*=.*" ), is( true ) );
|
assertThat( rowId == null
|
||||||
|
|| sqls.get( 0 ).matches( "(?i).*\\bupdate\\s+product\\b.+?\\bwhere\\s+" + rowId + "\\s*=.*" ),
|
||||||
|
is( true ) );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
scope.inTransaction( session -> {
|
scope.inTransaction( session -> {
|
||||||
|
@ -82,11 +85,11 @@ public class RowIdTest {
|
||||||
|
|
||||||
@Entity(name = "Product")
|
@Entity(name = "Product")
|
||||||
@Table(name = "product")
|
@Table(name = "product")
|
||||||
@RowId("ROWID")
|
@RowId
|
||||||
public static class Product {
|
public static class Product {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
private Long id;
|
private String id;
|
||||||
|
|
||||||
@Column(name = "`name`")
|
@Column(name = "`name`")
|
||||||
private String name;
|
private String name;
|
||||||
|
@ -94,11 +97,11 @@ public class RowIdTest {
|
||||||
@Column(name = "`number`")
|
@Column(name = "`number`")
|
||||||
private String number;
|
private String number;
|
||||||
|
|
||||||
public Long getId() {
|
public String getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setId(Long id) {
|
public void setId(String id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@ import org.hibernate.dialect.NationalizationSupport;
|
||||||
import org.hibernate.dialect.PostgreSQLDialect;
|
import org.hibernate.dialect.PostgreSQLDialect;
|
||||||
import org.hibernate.dialect.TiDBDialect;
|
import org.hibernate.dialect.TiDBDialect;
|
||||||
|
|
||||||
import org.hibernate.testing.orm.junit.DialectFeatureCheck;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Container class for different implementation of the {@link DialectCheck} interface.
|
* Container class for different implementation of the {@link DialectCheck} interface.
|
||||||
*
|
*
|
||||||
|
@ -312,4 +310,11 @@ abstract public class DialectChecks {
|
||||||
return dialect.supportsRecursiveCTE();
|
return dialect.supportsRecursiveCTE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class SupportsRowId implements DialectCheck {
|
||||||
|
@Override
|
||||||
|
public boolean isMatch(Dialect dialect) {
|
||||||
|
return dialect.rowId() != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue