diff --git a/.github/workflows/ci-hibernate-dialect.yaml b/.github/workflows/ci-hibernate-dialect.yaml index a3034a60..4d295aab 100644 --- a/.github/workflows/ci-hibernate-dialect.yaml +++ b/.github/workflows/ci-hibernate-dialect.yaml @@ -20,7 +20,7 @@ jobs: strategy: matrix: - java: [ '17', '21' ] + java: [ '11', '17', '21' ] steps: - uses: actions/checkout@v5 @@ -47,6 +47,7 @@ jobs: run: mvn $MAVEN_ARGS install - name: Tests with Hibernate 7 + if: matrix.java != '11' working-directory: ./hibernate-dialect run: mvn $MAVEN_ARGS clean install -Phibernate7 @@ -57,9 +58,11 @@ jobs: path: examples - name: Download dependencies + if: matrix.java != '11' working-directory: ./examples/jdbc/spring-data-jpa run: mvn $MAVEN_ARGS -Dhibernate.ydb.dialect.version=$HIBERNATE_DIALECT_VERSION dependency:go-offline - name: Test examples with Maven + if: matrix.java != '11' working-directory: ./examples/jdbc/spring-data-jpa run: mvn $MAVEN_ARGS -Dhibernate.ydb.dialect.version=$HIBERNATE_DIALECT_VERSION test diff --git a/hibernate-dialect/CHANGELOG.md b/hibernate-dialect/CHANGELOG.md index 2bef9d40..5e816624 100644 --- a/hibernate-dialect/CHANGELOG.md +++ b/hibernate-dialect/CHANGELOG.md @@ -2,6 +2,7 @@ - Renamed `hibernate-dialect-v6` to `hibernate-dialect`, removed `hibernate-dialect-v7` - Support Hibernate 7 +- Support Java 11 for Hibernate 6 profile - Support OFFSET without LIMIT - Dropped `current time` in HQL diff --git a/hibernate-dialect/README.md b/hibernate-dialect/README.md index 7e42adf5..023bcd90 100644 --- a/hibernate-dialect/README.md +++ b/hibernate-dialect/README.md @@ -21,10 +21,10 @@ features while using YDB as your underlying database. ### Requirements -To use this Hibernate V6 YDB Dialect, you'll need: +To use this Hibernate YDB Dialect, you'll need: -- Java 17 or above. -- Hibernate version 6.* +- Java 11 or above for Hibernate version 6.* +- Java 17 or above for Hibernate version 7.* - [YDB JDBC Driver](https://github.com/ydb-platform/ydb-jdbc-driver) - Access to a YDB Database instance diff --git a/hibernate-dialect/pom.xml b/hibernate-dialect/pom.xml index f954a1d8..1737fa5c 100644 --- a/hibernate-dialect/pom.xml +++ b/hibernate-dialect/pom.xml @@ -33,13 +33,13 @@ UTF-8 17 - 17 17 6.2.7.Final 5.9.3 2.17.2 + 1.18.38 2.3.13 2.3.18 @@ -102,7 +102,7 @@ org.projectlombok lombok - 1.18.30 + ${lombok.version} test @@ -114,12 +114,12 @@ maven-compiler-plugin 3.13.0 - 17 + ${maven.compiler.release} org.projectlombok lombok - 1.18.30 + ${lombok.version} @@ -129,7 +129,7 @@ maven-javadoc-plugin 3.5.0 - 17 + ${maven.compiler.source} @@ -195,12 +195,18 @@ 6.2.7.Final + 11 + 11 + 11 hibernate7 7.1.4.Final + 17 + 17 + 17 diff --git a/hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/YdbDialect.java b/hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/YdbDialect.java index d10b34fc..0a8ed5b7 100644 --- a/hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/YdbDialect.java +++ b/hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/YdbDialect.java @@ -106,27 +106,62 @@ public YdbDialect(DialectResolutionInfo dialectResolutionInfo) { @Override protected String columnType(int sqlTypeCode) { - return switch (sqlTypeCode) { - case BOOLEAN, BIT -> "Bool"; - case TINYINT -> "Int8"; - case SMALLINT -> "Int16"; - case INTEGER -> "Int32"; - case BIGINT -> "Int64"; - case REAL, FLOAT -> "Float"; - case DOUBLE -> "Double"; - case NUMERIC, DECIMAL -> "Decimal($p, $s)"; - case DATE -> "Date"; - case INTERVAL_SECOND -> "Interval"; - case TIME_WITH_TIMEZONE -> "TzDateTime"; - case TIMESTAMP, TIMESTAMP_UTC -> "Timestamp"; - case TIMESTAMP_WITH_TIMEZONE -> "TzTimestamp"; - case CHAR, VARCHAR, CLOB, NCHAR, NVARCHAR, NCLOB, - LONG32VARCHAR, LONG32NVARCHAR, LONGVARCHAR, LONGNVARCHAR -> "Text"; - case BINARY, VARBINARY, BLOB, LONGVARBINARY, LONG32VARBINARY -> "Bytes"; - case JSON -> "Json"; - case UUID, YdbJdbcCode.UUID -> "Uuid"; - default -> super.columnType(sqlTypeCode); - }; + switch (sqlTypeCode) { + case BOOLEAN: + case BIT: + return "Bool"; + case TINYINT: + return "Int8"; + case SMALLINT: + return "Int16"; + case INTEGER: + return "Int32"; + case BIGINT: + return "Int64"; + case REAL: + case FLOAT: + return "Float"; + case DOUBLE: + return "Double"; + case NUMERIC: + case DECIMAL: + return "Decimal($p, $s)"; + case DATE: + return "Date"; + case INTERVAL_SECOND: + return "Interval"; + case TIME_WITH_TIMEZONE: + return "TzDateTime"; + case TIMESTAMP: + case TIMESTAMP_UTC: + return "Timestamp"; + case TIMESTAMP_WITH_TIMEZONE: + return "TzTimestamp"; + case CHAR: + case VARCHAR: + case CLOB: + case NCHAR: + case NVARCHAR: + case NCLOB: + case LONG32VARCHAR: + case LONG32NVARCHAR: + case LONGVARCHAR: + case LONGNVARCHAR: + return "Text"; + case BINARY: + case VARBINARY: + case BLOB: + case LONGVARBINARY: + case LONG32VARBINARY: + return "Bytes"; + case JSON: + return "Json"; + case UUID: + case YdbJdbcCode.UUID: + return "Uuid"; + default: + return super.columnType(sqlTypeCode); + } } @Override @@ -471,13 +506,11 @@ public void appendLiteral(SqlAppender appender, String literal) { public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() { return (sqlException, message, sql) -> { String msg = sqlException.getMessage(); - - return switch (extractErrorCode(sqlException)) { - case 400120 -> msg != null && msg.contains("Conflict with existing key") - ? new ConstraintViolationException(message, sqlException, sql, null) - : null; - default -> null; - }; + int errorCode = extractErrorCode(sqlException); + if (errorCode == 400120 && msg != null && msg.contains("Conflict with existing key")) { + return new ConstraintViolationException(message, sqlException, sql, null); + } + return null; }; } diff --git a/hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/identity/YdbIdentityColumnSupport.java b/hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/identity/YdbIdentityColumnSupport.java index 3dcecccf..6d86d4ee 100644 --- a/hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/identity/YdbIdentityColumnSupport.java +++ b/hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/identity/YdbIdentityColumnSupport.java @@ -22,13 +22,18 @@ public boolean hasDataTypeInIdentityColumn() { @Override public String getIdentityColumnString(int type) throws MappingException { - return switch (type) { - case TINYINT, SMALLINT -> "SmallSerial"; - case INTEGER -> "Serial"; - case BIGINT -> "BigSerial"; - default -> throw new MappingException( - "Ydb does not support identity key generation for sqlType: " + JDBCType.valueOf(type)); - }; + switch (type) { + case TINYINT: + case SMALLINT: + return "SmallSerial"; + case INTEGER: + return "Serial"; + case BIGINT: + return "BigSerial"; + default: + throw new MappingException( + "Ydb does not support identity key generation for sqlType: " + JDBCType.valueOf(type)); + } } @Override diff --git a/hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/translator/YdbSqlAstTranslator.java b/hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/translator/YdbSqlAstTranslator.java index c6077210..b96a2d9b 100644 --- a/hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/translator/YdbSqlAstTranslator.java +++ b/hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/translator/YdbSqlAstTranslator.java @@ -75,13 +75,16 @@ protected void renderLikePredicate(LikePredicate likePredicate) { } private void acceptEscapeCharacter(LikePredicate likePredicate) { - if (likePredicate.getEscapeCharacter() instanceof QueryLiteral queryLiteral - && queryLiteral.getLiteralValue() instanceof Character value) { - appendSql('\''); - appendSql(value); - appendSql('\''); - } else { - likePredicate.getEscapeCharacter().accept(this); + if (likePredicate.getEscapeCharacter() instanceof QueryLiteral) { + QueryLiteral queryLiteral = (QueryLiteral) likePredicate.getEscapeCharacter(); + if (queryLiteral.getLiteralValue() instanceof Character) { + Character value = (Character) queryLiteral.getLiteralValue(); + appendSql('\''); + appendSql(value); + appendSql('\''); + return; + } } + likePredicate.getEscapeCharacter().accept(this); } } diff --git a/hibernate-dialect/src/test/java/tech/ydb/hibernate/exception/ExceptionConversionTest.java b/hibernate-dialect/src/test/java/tech/ydb/hibernate/exception/ExceptionConversionTest.java index 605c1ff7..f077f0a0 100644 --- a/hibernate-dialect/src/test/java/tech/ydb/hibernate/exception/ExceptionConversionTest.java +++ b/hibernate-dialect/src/test/java/tech/ydb/hibernate/exception/ExceptionConversionTest.java @@ -25,13 +25,12 @@ static void setUp() { inTransaction(session -> { session.createNativeQuery( - """ - CREATE TABLE exception_test_dup ( - id Int32 NOT NULL, - name Text, - PRIMARY KEY (id), - INDEX idx_dup_name GLOBAL UNIQUE ON (name) - )""" + "CREATE TABLE exception_test_dup (" + + " id Int32 NOT NULL," + + " name Text," + + " PRIMARY KEY (id)," + + " INDEX idx_dup_name GLOBAL UNIQUE ON (name)" + + ")" ).executeUpdate(); }); } diff --git a/hibernate-dialect/src/test/java/tech/ydb/hibernate/types/YdbJdbcCodeTest.java b/hibernate-dialect/src/test/java/tech/ydb/hibernate/types/YdbJdbcCodeTest.java index 07a1f529..d846b61a 100644 --- a/hibernate-dialect/src/test/java/tech/ydb/hibernate/types/YdbJdbcCodeTest.java +++ b/hibernate-dialect/src/test/java/tech/ydb/hibernate/types/YdbJdbcCodeTest.java @@ -116,35 +116,34 @@ public void integrationTest() { 2.2f, 2.2 ); inTransaction(session -> { + String updateQuery = "UPDATE YdbAllTypes e " + + "SET " + + "e.bool = :bool, " + + "e.uint8 = :uint8, " + + "e.int8 = :int8, " + + "e.uint16 = :uint16, " + + "e.int16 = :int16, " + + "e.uint32 = :uint32, " + + "e.int32 = :int32, " + + "e.uint64 = :uint64, " + + "e.int64 = :int64, " + + "e.date = :date, " + + "e.datetime = :datetime, " + + "e.timestamp = :timestamp, " + + "e.interval = :interval, " + + "e.date32 = :date32, " + + "e.datetime64 = :datetime64, " + + "e.timestamp64 = :timestamp64, " + + "e.interval64 = :interval64, " + + "e.text = :text, " + + "e.json = :json, " + + "e.jsonDocument = :jsonDocument, " + + "e.bytes = :bytes, " + + "e.yson = :yson, " + + "e.aFloat = :aFloat, " + + "e.aDouble = :aDouble"; session.createQuery( - """ - UPDATE YdbAllTypes e - SET - e.bool = :bool, - e.uint8 = :uint8, - e.int8 = :int8, - e.uint16 = :uint16, - e.int16 = :int16, - e.uint32 = :uint32, - e.int32 = :int32, - e.uint64 = :uint64, - e.int64 = :int64, - e.date = :date, - e.datetime = :datetime, - e.timestamp = :timestamp, - e.interval = :interval, - e.date32 = :date32, - e.datetime64 = :datetime64, - e.timestamp64 = :timestamp64, - e.interval64 = :interval64, - e.text = :text, - e.json = :json, - e.jsonDocument = :jsonDocument, - e.bytes = :bytes, - e.yson = :yson, - e.aFloat = :aFloat, - e.aDouble = :aDouble - """) + updateQuery) .setParameter("bool", newYdbAllEntity.isBool()) .setParameter("uint8", newYdbAllEntity.getUint8()) .setParameter("int8", newYdbAllEntity.getInt8())