diff --git a/hibernate-dialect/CHANGELOG.md b/hibernate-dialect/CHANGELOG.md
index 9c1388d..15b7585 100644
--- a/hibernate-dialect/CHANGELOG.md
+++ b/hibernate-dialect/CHANGELOG.md
@@ -1,3 +1,5 @@
+- Fixed @JdbcTypeCode annotation on fields: Json, JsonDocument and others with YdbJdbcCode
+
## 1.5.0 ##
- Support for `GenerationType.IDENTITY` with JDBC YDB Driver **2.3.11** and later.
diff --git a/hibernate-dialect/pom.xml b/hibernate-dialect/pom.xml
index b013da3..ecb40d8 100644
--- a/hibernate-dialect/pom.xml
+++ b/hibernate-dialect/pom.xml
@@ -6,7 +6,7 @@
tech.ydb.dialects
hibernate-ydb-dialect
- 1.5.0
+ 1.5.1
jar
@@ -42,7 +42,7 @@
2.17.2
2.3.13
- 2.3.11
+ 2.3.18
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 70cfdc2..b6e5274 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
@@ -144,6 +144,27 @@ public void contributeTypes(TypeContributions typeContributions, ServiceRegistry
typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.DATETIME_64, LocalDateTime.class));
typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.TIMESTAMP_64, Instant.class));
typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.INTERVAL_64, Duration.class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.JSON, String.class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.JSON_DOCUMENT, String.class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.BOOL, Boolean.class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.INT8, Integer.class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.INT16, Integer.class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.UINT16, Integer.class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.INT32, Integer.class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.UINT32, Integer.class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.INT64, Integer.class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.UINT64, Integer.class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.FLOAT, Float.class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.DOUBLE, Double.class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.BYTES, byte[].class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.TEXT, String.class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.YSON, byte[].class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.JSON, String.class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.UUID, java.util.UUID.class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.DATE, LocalDate.class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.DATETIME, LocalDateTime.class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.TIMESTAMP, Instant.class));
+ typeContributions.contributeJdbcType(new YdbJdbcType(YdbJdbcCode.INTERVAL, Duration.class));
typeContributions.contributeJavaType(BigDecimalJavaType.INSTANCE_22_9);
typeContributions.contributeJdbcType(new DecimalJdbcType(YdbJdbcCode.DECIMAL_22_9));
@@ -171,6 +192,26 @@ protected void registerColumnTypes(TypeContributions typeContributions, ServiceR
ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.DECIMAL_31_9, "Decimal(31, 9)", "Decimal(31, 9)", this));
ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.DECIMAL_35_0, "Decimal(35, 0)", "Decimal(35, 0)", this));
ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.DECIMAL_35_9, "Decimal(35, 9)", "Decimal(35, 9)", this));
+ ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.JSON, "Json", "Json", this));
+ ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.JSON_DOCUMENT, "JsonDocument", "JsonDocument", this));
+ ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.BOOL, "Bool", "Bool", this));
+ ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.INT8, "Int8", "Int8", this));
+ ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.INT16, "Int16", "Int16", this));
+ ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.UINT16, "Uint16", "Uint16", this));
+ ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.INT32, "Int32", "Int32", this));
+ ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.UINT32, "Uint32", "Uint32", this));
+ ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.INT64, "Int64", "Int64", this));
+ ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.UINT64, "Uint64", "Uint64", this));
+ ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.FLOAT, "Float", "Float", this));
+ ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.DOUBLE, "Double", "Double", this));
+ ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.BYTES, "Bytes", "Bytes", this));
+ ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.TEXT, "Text", "Text", this));
+ ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.YSON, "Yson", "Yson", this));
+ ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.UUID, "Uuid", "Uuid", this));
+ ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.DATE, "Date", "Date", this));
+ ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.DATETIME, "Datetime", "Datetime", this));
+ ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.TIMESTAMP, "Timestamp", "Timestamp", this));
+ ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.INTERVAL, "Interval", "Interval", this));
}
@Override
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
new file mode 100644
index 0000000..07a1f52
--- /dev/null
+++ b/hibernate-dialect/src/test/java/tech/ydb/hibernate/types/YdbJdbcCodeTest.java
@@ -0,0 +1,283 @@
+package tech.ydb.hibernate.types;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import jakarta.persistence.Table;
+import java.nio.charset.StandardCharsets;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.util.UUID;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.hibernate.annotations.JdbcTypeCode;
+import org.hibernate.cfg.AvailableSettings;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import tech.ydb.hibernate.TestUtils;
+import static tech.ydb.hibernate.TestUtils.basedConfiguration;
+import static tech.ydb.hibernate.TestUtils.inTransaction;
+import static tech.ydb.hibernate.TestUtils.jdbcUrl;
+import tech.ydb.hibernate.dialect.code.YdbJdbcCode;
+import tech.ydb.test.junit5.YdbHelperExtension;
+
+/**
+ * @author Kirill Kurdyukov
+ */
+public class YdbJdbcCodeTest {
+
+ @RegisterExtension
+ private static final YdbHelperExtension ydb = new YdbHelperExtension();
+
+ @BeforeAll
+ static void beforeAll() {
+ TestUtils.SESSION_FACTORY = basedConfiguration()
+ .addAnnotatedClass(YdbAllTypes.class)
+ .setProperty(AvailableSettings.URL, jdbcUrl(ydb))
+ .buildSessionFactory();
+ }
+
+ @Test
+ public void integrationTest() {
+ /*
+ * create table ydb_all_types (
+ * aDouble Double,
+ * aFloat Float,
+ * bool Bool,
+ * bytes Bytes,
+ * date Date,
+ * date32 Date32,
+ * datetime Datetime,
+ * datetime64 Datetime64,
+ * int16 Int16,
+ * int32 Int32,
+ * int64 Int64,
+ * int8 Int8,
+ * interval Interval,
+ * interval64 Interval64,
+ * json Json,
+ * jsonDocument JsonDocument,
+ * text Text,
+ * timestamp Timestamp,
+ * timestamp64 Timestamp64,
+ * uint16 Uint16,
+ * uint32 Uint32,
+ * uint64 Uint64,
+ * uint8 Uint8,
+ * uuid Uuid not null,
+ * yson Yson,
+ * primary key (uuid)
+ * )
+ */
+ var ydbAllEntity = new YdbAllTypes(
+ UUID.randomUUID(),
+ true, 1, 1, 1, 1, 1, 1, 1, 1,
+ LocalDate.now(),
+ LocalDateTime.of(2000, 1, 1, 1, 1, 1),
+ Instant.parse("2025-10-02T11:06:32.779087Z"),
+ Duration.ofSeconds(1),
+ LocalDate.ofYearDay(1000, 1),
+ LocalDateTime.of(1000, 1, 1, 1, 1, 1),
+ LocalDateTime.of(1000, 1, 1, 1, 1, 1).toInstant(ZoneOffset.UTC),
+ Duration.ofSeconds(-1),
+ "text",
+ "{\"a\":\"a\"}",
+ "{\"a\":\"a\"}",
+ new byte[]{10, 20},
+ "{a=1u}".getBytes(StandardCharsets.UTF_8),
+ 1.1f, 1.1
+ );
+
+ inTransaction(session -> session.persist(ydbAllEntity));
+ inTransaction(session -> assertEquals(ydbAllEntity, session.find(YdbAllTypes.class, ydbAllEntity.getUuid())));
+
+ var newYdbAllEntity = new YdbAllTypes(
+ ydbAllEntity.getUuid(),
+ false, 2, 2, 2, 2, 2, 2, 2, 2,
+ LocalDate.now(),
+ LocalDateTime.of(2000, 2, 2, 2, 2, 2),
+ Instant.parse("2023-10-02T11:06:32.779087Z"),
+ Duration.ofSeconds(2),
+ LocalDate.ofYearDay(1000, 2),
+ LocalDateTime.of(1000, 2, 2, 2, 2, 2),
+ LocalDateTime.of(1000, 2, 2, 2, 2, 2).toInstant(ZoneOffset.UTC),
+ Duration.ofSeconds(-2),
+ "new_text",
+ "{\"b\":\"b\"}",
+ "{\"b\":\"b\"}",
+ new byte[]{20, 20},
+ "{a=2u}".getBytes(StandardCharsets.UTF_8),
+ 2.2f, 2.2
+ );
+ inTransaction(session -> {
+ 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
+ """)
+ .setParameter("bool", newYdbAllEntity.isBool())
+ .setParameter("uint8", newYdbAllEntity.getUint8())
+ .setParameter("int8", newYdbAllEntity.getInt8())
+ .setParameter("uint16", newYdbAllEntity.getUint16())
+ .setParameter("int16", newYdbAllEntity.getInt16())
+ .setParameter("uint32", newYdbAllEntity.getUint32())
+ .setParameter("int32", newYdbAllEntity.getInt32())
+ .setParameter("uint64", newYdbAllEntity.getUint64())
+ .setParameter("int64", newYdbAllEntity.getInt64())
+ .setParameter("date", newYdbAllEntity.getDate())
+ .setParameter("datetime", newYdbAllEntity.getDatetime())
+ .setParameter("timestamp", newYdbAllEntity.getTimestamp())
+ .setParameter("interval", newYdbAllEntity.getInterval())
+ .setParameter("date32", newYdbAllEntity.getDate32())
+ .setParameter("datetime64", newYdbAllEntity.getDatetime64())
+ .setParameter("timestamp64", newYdbAllEntity.getTimestamp64())
+ .setParameter("interval64", newYdbAllEntity.getInterval64())
+ .setParameter("text", newYdbAllEntity.getText())
+ .setParameter("json", newYdbAllEntity.getJson())
+ .setParameter("jsonDocument", newYdbAllEntity.getJsonDocument())
+ .setParameter("bytes", newYdbAllEntity.getBytes())
+ .setParameter("yson", newYdbAllEntity.getYson())
+ .setParameter("aFloat", newYdbAllEntity.getAFloat())
+ .setParameter("aDouble", newYdbAllEntity.getADouble())
+ .executeUpdate();
+ assertEquals(newYdbAllEntity, session.find(YdbAllTypes.class, newYdbAllEntity.getUuid()));
+ });
+ }
+
+ @Entity(name = "YdbAllTypes")
+ @Table(name = "ydb_all_types")
+ @Data
+ @AllArgsConstructor
+ @NoArgsConstructor
+ public static class YdbAllTypes {
+ @Id
+ @JdbcTypeCode(YdbJdbcCode.UUID)
+ private UUID uuid;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.BOOL)
+ private boolean bool;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.UINT8)
+ private int uint8;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.INT8)
+ private int int8;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.UINT16)
+ private int uint16;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.INT16)
+ private int int16;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.UINT32)
+ private int uint32;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.INT32)
+ private int int32;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.UINT64)
+ private int uint64;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.INT64)
+ private int int64;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.DATE)
+ private LocalDate date;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.DATETIME)
+ private LocalDateTime datetime;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.TIMESTAMP)
+ private Instant timestamp;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.INTERVAL)
+ private Duration interval;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.DATE_32)
+ private LocalDate date32;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.DATETIME_64)
+ private LocalDateTime datetime64;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.TIMESTAMP_64)
+ private Instant timestamp64;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.INTERVAL_64)
+ private Duration interval64;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.TEXT)
+ private String text;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.JSON)
+ private String json;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.JSON_DOCUMENT)
+ private String jsonDocument;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.BYTES)
+ private byte[] bytes;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.YSON)
+ private byte[] yson;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.FLOAT)
+ private float aFloat;
+
+ @Column
+ @JdbcTypeCode(YdbJdbcCode.DOUBLE)
+ private double aDouble;
+ }
+}