diff --git a/openGaussDialect/.gitignore b/openGaussDialect/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..b83d22266ac8aa2f8df2edef68082c789727841d
--- /dev/null
+++ b/openGaussDialect/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/openGaussDialect/.idea/.gitignore b/openGaussDialect/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..13566b81b018ad684f3a35fee301741b2734c8f4
--- /dev/null
+++ b/openGaussDialect/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/openGaussDialect/.idea/compiler.xml b/openGaussDialect/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b60f12a66df622f62aa67332420202bf2179495e
--- /dev/null
+++ b/openGaussDialect/.idea/compiler.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/openGaussDialect/.idea/encodings.xml b/openGaussDialect/.idea/encodings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..aa00ffab7828f4818589659c804ec2cfd99baed3
--- /dev/null
+++ b/openGaussDialect/.idea/encodings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/openGaussDialect/.idea/jarRepositories.xml b/openGaussDialect/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2661ae018a21e65e2d95a613d0d5fb3891b1f45e
--- /dev/null
+++ b/openGaussDialect/.idea/jarRepositories.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/openGaussDialect/.idea/misc.xml b/openGaussDialect/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d5cd61439e42be16778fe0d90f206a2b02d987e8
--- /dev/null
+++ b/openGaussDialect/.idea/misc.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/openGaussDialect/.idea/modules.xml b/openGaussDialect/.idea/modules.xml
new file mode 100644
index 0000000000000000000000000000000000000000..466a0c6d846d334a015eafa5608d02996ead69ec
--- /dev/null
+++ b/openGaussDialect/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/openGaussDialect/.idea/uiDesigner.xml b/openGaussDialect/.idea/uiDesigner.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2b63946d5b31084bbb7dda418ceb3d75eb686373
--- /dev/null
+++ b/openGaussDialect/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/openGaussDialect/.idea/vcs.xml b/openGaussDialect/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6c0b8635858dc7ad44b93df54b762707ce49eefc
--- /dev/null
+++ b/openGaussDialect/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/openGaussDialect/docs/Hibernate \345\205\263\344\272\216 OpenGauss \346\226\271\350\250\200\345\214\205_\345\274\200\345\217\221\346\211\213\345\206\214.pdf" "b/openGaussDialect/docs/Hibernate \345\205\263\344\272\216 OpenGauss \346\226\271\350\250\200\345\214\205_\345\274\200\345\217\221\346\211\213\345\206\214.pdf"
new file mode 100644
index 0000000000000000000000000000000000000000..b6718237576a6991c93a78724ef3bdd24f446f95
Binary files /dev/null and "b/openGaussDialect/docs/Hibernate \345\205\263\344\272\216 OpenGauss \346\226\271\350\250\200\345\214\205_\345\274\200\345\217\221\346\211\213\345\206\214.pdf" differ
diff --git "a/openGaussDialect/docs/\346\265\213\350\257\225\346\226\207\346\241\243.md" "b/openGaussDialect/docs/\346\265\213\350\257\225\346\226\207\346\241\243.md"
new file mode 100644
index 0000000000000000000000000000000000000000..ac3e124d541157de46c26b2291093a9d72a7db9c
--- /dev/null
+++ "b/openGaussDialect/docs/\346\265\213\350\257\225\346\226\207\346\241\243.md"
@@ -0,0 +1,113 @@
+## 1 测试目标
+
+**功能验证**:验证 `OpenGaussDialect` 类的功能,确保其能够正确地与 Hibernate 和 openGauss 数据库协同工作。。
+
+**性能验证**:验证分页查询、批量操作等性能是否达到预期。
+
+## 2 测试范围
+
+**单元测试**:针对 `OpenGaussDialect` 类中的各个方法,进行方法级别的测试,验证其逻辑正确性。
+
+**集成测试**:在实际的 Hibernate 环境中,使用 `OpenGaussDialect` 进行数据库操作,验证其功能和兼容性。
+
+**性能测试**:对分页查询、批量插入和更新等操作进行性能测试,验证其效率。
+
+**异常处理测试**:验证方言对异常的处理是否符合预期,特别是对数据库异常的转换。
+
+## 3 测试环境
+
+- **操作系统**:Linux(CentOS 7/8)
+- **JDK 版本**:jdk1.8.0_202
+- **Hibernate 版本**:5.6.15.Final
+- **openGauss 版本**:opengauss:5.0.0 LTS
+- **openGauss 数据库驱动**:5.0.0-og
+
+### 4 测试工具
+
+- **测试框架**:JUnit 5
+- **Mock 框架**:Mockito
+
+## 5 测试内容
+
+### 5.1 数据类型映射测试
+
+验证 Java 类型与 openGauss 数据库类型之间的映射关系是否正确。
+
+### 5.2 SQL 函数支持测试
+
+测试注册的 openGauss 特定 SQL 函数是否能够正确使用。
+
+### 5.3 分页和限制功能测试
+
+验证分页查询的 SQL 生成是否正确,`limit` 和 `offset` 参数是否正确处理。
+
+### 5.4 序列和标识支持测试
+
+测试序列的创建、使用和删除,以及标识列的支持情况。
+
+### 5.5 异常处理测试
+
+测试数据库异常是否能够正确地转换为 Hibernate 的异常类型。
+
+### 5.6 DDL 生成测试
+
+验证生成的 DDL 语句是否符合 openGauss 的语法要求。
+
+### 5.7 锁机制支持测试
+
+测试数据库锁机制的支持情况,验证生成的 SQL 是否正确。
+
+### 5.8 当前时间戳函数支持测试
+
+测试获取当前时间戳的函数是否正常工作。
+
+### 5.9 命名限定符支持测试
+
+验证方言对模式、表等命名限定符的支持。
+
+### 5.10 性能测试
+
+对分页查询、批量插入和更新操作进行性能测试。
+
+## 测试步骤
+
+#### 6.1 单元测试
+
+- 编写针对 `OpenGaussDialect` 类各个方法的单元测试,使用 JUnit 5 和 Mockito。
+- 覆盖所有重写的方法和新增的功能,确保逻辑正确。
+
+#### 6.2 集成测试
+
+- 配置 Hibernate,使用 `OpenGaussDialect`,连接到 openGauss 数据库。
+- 编写实体类,进行 CRUD 操作,验证数据库交互的正确性。
+- 测试分页查询、序列生成、锁机制等功能。
+
+#### 6.3 性能测试
+
+- 在 openGauss 数据库中插入大量数据,测试分页查询的性能。
+- 测试批量插入和更新操作的性能。
+
+## 7 测试通过标准
+
+- 所有测试用例均通过,无功能性缺陷。
+- 性能测试结果达到预期,性能优化有效。
+- 异常处理符合预期,能够正确捕获和转换数据库异常。
+- 在不同环境下运行正常,无兼容性问题。
+
+### 测试结果记录
+
+对于每个测试用例,执行后记录实际结果。如果与预期结果一致,则标记为**通过**;如果不一致,则记录问题,分析原因,进行修复后再次测试。
+
+### 测试总结
+
+- **功能测试**:所有功能测试用例均通过,`OpenGaussDialect` 的功能符合预期。
+- **性能测试**:性能测试结果达到预期,分页查询和批量操作性能良好。
+- **兼容性测试**:在不同版本的 Hibernate 和 openGauss 数据库上测试,均无兼容性问题。
+
+### 问题和改进
+
+在测试过程中,如果发现任何问题,需要及时修复,并更新测试用例和测试结果。针对发现的问题,分析其根本原因,优化代码,实现改进。
+
+## 结论
+
+通过本测试计划和测试文档,全面验证了 `OpenGaussDialect` 的功能和性能,确保其能够正确、高效地与 Hibernate 和 openGauss 数据库协同工作。测试结果良好,方言实现满足项目需求,可以在实际项目中使用。建议在后续的开发和维护中,持续完善测试用例,保持对新功能和变更的测试覆盖,确保方言的稳定性和可靠性。
diff --git "a/openGaussDialect/docs/\350\256\276\350\256\241\346\226\207\346\241\243.md" "b/openGaussDialect/docs/\350\256\276\350\256\241\346\226\207\346\241\243.md"
new file mode 100644
index 0000000000000000000000000000000000000000..0330b0aaadda4eb57e440403ad8079e1fa246faa
--- /dev/null
+++ "b/openGaussDialect/docs/\350\256\276\350\256\241\346\226\207\346\241\243.md"
@@ -0,0 +1,165 @@
+## 1. 概述
+
+本文档旨在为 OpenGauss 数据库编写一个自定义的 Hibernate Dialect 类。该类的作用是为 Hibernate 提供特定于 OpenGauss 数据库的 SQL 方言支持,使其能够与 OpenGauss 数据库进行无缝集成。
+
+## 2. 背景
+
+Hibernate 是一个广泛使用的对象关系映射(ORM)框架,用于将 Java对象 与关系数据库表进行映射。为了支持多种数据库系统,Hibernate 引入了 Dialect 类,用来处理数据库的特定 SQL 方言。方言(Dialect)在 Hibernate 中的主要作用是**告诉 Hibernate 如何将 HQL 或标准** **SQL** **转换为特定数据库的 SQL 语句**。由于不同数据库的 SQL 语法和数据类型有所不同,Hibernate 通过方言实现对多种数据库的兼容性。每个方言定义了数据类型、函数、特性等,并对数据库的特定行为提供支持。为支持 OpenGauss,需要编写一个符合OpenGauss SQL特性的 Dialect 类。
+
+## 3. 目标
+
+为了在 Hibernate 和 OpenGauss 之间提供兼容性。通过实现数据库特定的行为、SQL 语法、数据类型和函数,使 Hibernate 能够正确地生成适用于 OpenGauss 的 SQL 语句。
+
+## 4. 范围
+
+- 分析 OpenGauss 的 SQL 方言特性。
+- 确定需要在 `Dialect` 中重写的方法。
+- 实现 Hibernate 与 OpenGauss 之间的数据类型映射。
+- 支持 OpenGauss 特定的 SQL 函数和关键字。
+- 处理限制、偏移和分页的特定细节。
+- 实现标识、序列和主键生成策略。
+- 解决与事务隔离、锁定和批量更新相关的特殊行为。
+
+## 5. 设计概述
+
+- **类结构**:
+ - **类名**:`OpenGaussDialect`
+ - **包名**:`org.hibernate.dialect`
+- **继承关系**:继承自 `org.hibernate.dialect.Dialect`
+
+## 6. 实现细节
+
+### 6.1 数据类型映射
+
+**目标**:定义 openGauss 数据类型与 Java 类型之间的映射关系。
+
+**实现**:在构造方法中使用 `registerColumnType()` 方法注册数据类型。
+
+```java
+public class OpenGaussDialect extends Dialect {
+ public OpenGaussDialect() {
+ super();
+
+ // 注册数据类型
+ registerColumnType(Types.BIT, "bit");
+ registerColumnType(Types.BOOLEAN, "bool");
+ // ... 其他数据类型注册
+ }
+}
+```
+
+### 6.2 SQL 函数映射
+
+**目标**:支持 openGauss 特定的 SQL 函数。
+
+**实现**:使用 `registerFunction()` 方法注册函数。
+
+```java
+registerFunction("abs", new StandardSQLFunction("abs", StandardBasicTypes.DOUBLE));
+registerFunction("cbrt", new StandardSQLFunction("cbrt", StandardBasicTypes.DOUBLE));
+registerFunction("ceil", new StandardSQLFunction("ceil", StandardBasicTypes.DOUBLE));
+...
+```
+
+### 6.3 限制和分页支持
+
+**目标**:实现限制和偏移支持,以处理分页查询。
+
+**实现**:实现 `getLimitHandler()`,返回适用于 OpenGauss 的 `LimitHandler`
+
+```java
+@Override
+public LimitHandler getLimitHandler() {
+ return new OpenGaussLimitHandler();
+}
+
+public class OpenGaussLimitHandler extends AbstractLimitHandler {
+ // 实现应用 LIMIT 和 OFFSET 子句的方法
+}
+```
+
+### 6.4 标识和序列支持
+
+**目标**:处理主键生成策略,包括标识列和序列。
+
+**实现**:确定 OpenGauss 是否支持标识列(`GENERATED AS IDENTITY`),提供一个 `IdentityColumnSupport` 的实现。
+
+```java
+@Override
+public IdentityColumnSupport getIdentityColumnSupport() {
+ return new OpenGaussIdentityColumnSupport();
+}
+
+public class OpenGaussIdentityColumnSupport extends IdentityColumnSupportImpl {
+ // 根据需要重写方法
+}
+```
+
+### 6.5 保留关键字
+
+目标:注册 OpenGauss 的保留关键字,以防止与实体和列名冲突。
+
+### 6.6 锁定策略
+
+目标:实现 OpenGauss 特定的锁定机制,包括 `FOR UPDATE` 子句。
+
+```java
+@Override
+public String getForUpdateString() {
+ return " for update";
+}
+
+@Override
+public boolean supportsOuterJoinForUpdate() {
+ return true;
+}
+```
+
+### 6.7 批量操作
+
+目标:优化批量插入、更新和删除操作的性能。
+
+```java
+@Override
+public int getDefaultBatchSize() {
+ return 50; // 根据 OpenGauss 的性能特性进行调整
+}
+```
+
+### 6.8 模式支持
+
+目标:处理特定于 OpenGauss 的模式创建、修改和删除。
+
+```java
+@Override
+public String[] getCreateSchemaCommand(String schemaName) {
+ return new String[] {"CREATE SCHEMA IF NOT EXISTS " + schemaName};
+}
+
+@Override
+public boolean canCreateSchema() {
+ return true;
+}
+```
+
+### 6.9 其他重写
+
+...
+
+## 测试计划
+
+- **单元测试**:为每个重写的方法编写单元测试,确保正确的 SQL 生成。
+- **集成测试**:使用 Hibernate 和 OpenGaussDialect 对接 OpenGauss 数据库,测试 CRUD 操作。
+- **性能测试**:对批量操作和分页查询进行基准测试,验证性能优化。
+
+## 依赖项
+
+- **JDK 版本**:jdk1.8.0_202
+- **Hibernate 版本**:5.6.15.Final
+- **openGauss 数据库驱动**:5.0.0-og
+
+# 参考资料
+
+- openGauss 官方文档:https://docs-opengauss.osinfra.cn/zh/docs/5.0.0-lite/docs/GettingStarted/GettingStarted.html
+- Hibernate 官方文档:https://hibernate.org/orm/documentation/5.6/
+- JDBC API 文档:https://docs.oracle.com/javase/8/docs/api/java/sql/package-summary.html
\ No newline at end of file
diff --git a/openGaussDialect/openGaussDialect.iml b/openGaussDialect/openGaussDialect.iml
new file mode 100644
index 0000000000000000000000000000000000000000..39cf9e32b4b24a9cc3193ea32113e44c164bd356
--- /dev/null
+++ b/openGaussDialect/openGaussDialect.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/openGaussDialect/pom.xml b/openGaussDialect/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c2984613b3f16c7d602dd785571d66e4de947de8
--- /dev/null
+++ b/openGaussDialect/pom.xml
@@ -0,0 +1,76 @@
+
+ 4.0.0
+
+ org.hibernate.dialect
+ openGaussDialect
+ jar
+ 1.0-SNAPSHOT
+ openGaussDialect
+ http://maven.apache.org
+
+
+
+ central
+ https://repo.maven.apache.org/maven2
+
+
+
+
+ 8
+ 8
+ UTF-8
+ 5.0.0-og
+ 5.6.15.Final
+ 1.18.34
+ 5.10.3
+ 2.17.2
+
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson-databind.version}
+
+
+ org.opengauss
+ opengauss-jdbc
+ ${opengauss-jdbc.version}
+
+
+ org.hibernate
+ hibernate-core
+ ${hibernate-core.version}
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit.version}
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${junit.version}
+ test
+
+
+ com.jcraft
+ jsch
+ 0.1.55
+ test
+
+
+ org.mockito
+ mockito-core
+ 4.11.0
+ test
+
+
+
diff --git a/openGaussDialect/src/main/java/org/hibernate/dialect/OpenGaussDialect.java b/openGaussDialect/src/main/java/org/hibernate/dialect/OpenGaussDialect.java
new file mode 100644
index 0000000000000000000000000000000000000000..8a7bb9f797e71b7d6f2080a4e850799cd79fd323
--- /dev/null
+++ b/openGaussDialect/src/main/java/org/hibernate/dialect/OpenGaussDialect.java
@@ -0,0 +1,660 @@
+package org.hibernate.dialect;
+
+import org.hibernate.*;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.function.*;
+import org.hibernate.dialect.identity.IdentityColumnSupport;
+import org.hibernate.dialect.identity.OpenGaussIdentityColumnSupport;
+import org.hibernate.dialect.pagination.AbstractLimitHandler;
+import org.hibernate.dialect.pagination.LimitHandler;
+import org.hibernate.dialect.pagination.LimitHelper;
+import org.hibernate.engine.jdbc.env.spi.IdentifierCaseStrategy;
+import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
+import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
+import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport;
+import org.hibernate.engine.spi.RowSelection;
+import org.hibernate.exception.ConstraintViolationException;
+import org.hibernate.exception.DataException;
+import org.hibernate.exception.JDBCConnectionException;
+import org.hibernate.exception.LockAcquisitionException;
+import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
+import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
+import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
+import org.hibernate.hql.spi.id.IdTableSupportStandardImpl;
+import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
+import org.hibernate.hql.spi.id.local.AfterUseAction;
+import org.hibernate.hql.spi.id.local.LocalTemporaryTableBulkIdStrategy;
+import org.hibernate.internal.util.JdbcExceptionHelper;
+import org.hibernate.type.StandardBasicTypes;
+import org.hibernate.type.descriptor.sql.BlobTypeDescriptor;
+import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
+import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
+
+import java.sql.*;
+
+public class OpenGaussDialect extends Dialect {
+ public OpenGaussDialect() {
+ super();
+ registerColumnType(Types.BIT, "bit");
+ registerColumnType(Types.BOOLEAN, "bool");
+
+ registerColumnType(Types.TINYINT, "int1");
+ registerColumnType(Types.SMALLINT, "int2");
+ registerColumnType(Types.INTEGER, "int4");
+ registerColumnType(Types.BIGINT, "int8");
+ registerColumnType(Types.REAL, "float4");
+ registerColumnType(Types.FLOAT, "float8");
+ registerColumnType(Types.DOUBLE, "float8");
+ registerColumnType(Types.DECIMAL, "decimal($p,$s)");
+ registerColumnType(Types.NUMERIC, "numeric($p,$s)");
+
+ registerColumnType(Types.CHAR, "char(1)");
+
+ registerColumnType(Types.VARCHAR, "varchar($l)");
+ registerColumnType(Types.LONGVARCHAR, "text");
+ registerColumnType(Types.NCHAR, "nchar($l)");
+ registerColumnType(Types.NVARCHAR, "nvarchar2($l)");
+
+ registerColumnType(Types.DATE, "date");
+ registerColumnType(Types.TIME, "time");
+ registerColumnType(Types.TIMESTAMP, "timestamp");
+ registerColumnType(Types.TIME_WITH_TIMEZONE, "timetz");
+ registerColumnType(Types.TIMESTAMP_WITH_TIMEZONE, "timestamptz");
+
+ registerColumnType(Types.BINARY, "bytea");
+ registerColumnType(Types.VARBINARY, "bytea");
+ registerColumnType(Types.LONGVARBINARY, "bytea");
+
+
+ registerColumnType(Types.BLOB, "blob");
+ registerColumnType(Types.CLOB, "clob");
+ registerColumnType(Types.NCLOB, "text");
+
+ registerColumnType(Types.JAVA_OBJECT, "json");
+ registerColumnType(Types.SQLXML, "xml");
+ registerColumnType(Types.OTHER, "uuid");
+
+ registerOpenGaussFunctions();
+
+ getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
+ getDefaultProperties().setProperty(Environment.NON_CONTEXTUAL_LOB_CREATION, "false");
+ }
+
+ protected void registerOpenGaussFunctions() {
+ // https://docs-opengauss.osinfra.cn/zh/docs/5.0.0-lite/docs/BriefTutorial/%E5%87%BD%E6%95%B0.html
+ // mathematical functions
+ registerFunction("abs", new StandardSQLFunction("abs", StandardBasicTypes.DOUBLE));
+ registerFunction("cbrt", new StandardSQLFunction("cbrt", StandardBasicTypes.DOUBLE));
+ registerFunction("ceil", new StandardSQLFunction("ceil", StandardBasicTypes.DOUBLE));
+ registerFunction("degrees", new StandardSQLFunction("degrees", StandardBasicTypes.DOUBLE));
+ registerFunction("exp", new StandardSQLFunction("exp", StandardBasicTypes.DOUBLE));
+ registerFunction("floor", new StandardSQLFunction("floor", StandardBasicTypes.DOUBLE));
+ registerFunction("ln", new StandardSQLFunction("ln", StandardBasicTypes.DOUBLE));
+ registerFunction("log", new StandardSQLFunction("log", StandardBasicTypes.DOUBLE));
+ registerFunction("mod", new StandardSQLFunction("mod", StandardBasicTypes.INTEGER));
+ registerFunction("pi", new NoArgSQLFunction("pi", StandardBasicTypes.DOUBLE, true));
+ registerFunction("power", new StandardSQLFunction("power", StandardBasicTypes.DOUBLE));
+ registerFunction("radians", new StandardSQLFunction("radians", StandardBasicTypes.DOUBLE));
+ registerFunction("random", new NoArgSQLFunction("random", StandardBasicTypes.DOUBLE));
+ registerFunction("round", new StandardSQLFunction("round", StandardBasicTypes.DOUBLE));
+ registerFunction("sign", new StandardSQLFunction("sign", StandardBasicTypes.INTEGER));
+ registerFunction("sqrt", new StandardSQLFunction("sqrt", StandardBasicTypes.DOUBLE));
+ registerFunction("trunc", new StandardSQLFunction("trunc", StandardBasicTypes.DOUBLE));
+
+ // trigonometric functions
+ registerFunction("acos", new StandardSQLFunction("acos", StandardBasicTypes.DOUBLE));
+ registerFunction("asin", new StandardSQLFunction("asin", StandardBasicTypes.DOUBLE));
+ registerFunction("atan", new StandardSQLFunction("atan", StandardBasicTypes.DOUBLE));
+ registerFunction("atan2", new StandardSQLFunction("atan2", StandardBasicTypes.DOUBLE));
+ registerFunction("cos", new StandardSQLFunction("cos", StandardBasicTypes.DOUBLE));
+ registerFunction("cot", new StandardSQLFunction("cot", StandardBasicTypes.DOUBLE));
+ registerFunction("sin", new StandardSQLFunction("sin", StandardBasicTypes.DOUBLE));
+ registerFunction("tan", new StandardSQLFunction("tan", StandardBasicTypes.DOUBLE));
+
+ // string functions
+ registerFunction("concat", new VarArgsSQLFunction(StandardBasicTypes.STRING, "", "||", ""));
+ registerFunction("bit_length", new StandardSQLFunction("bit_length", StandardBasicTypes.LONG));
+ registerFunction("convert", new SQLFunctionTemplate(StandardBasicTypes.BINARY, "convert(?1, ?2, ?3)"));
+ registerFunction("lower", new StandardSQLFunction("lower", StandardBasicTypes.STRING));
+ registerFunction("octet_length", new StandardSQLFunction("octet_length", StandardBasicTypes.LONG));
+ registerFunction("overlay", new SQLFunctionTemplate(StandardBasicTypes.STRING, "overlay(?1 placing ?2 from ?3 for ?4)"));
+ registerFunction("position", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "position(?1 in ?2)"));
+ registerFunction("substring", new SubstringFunction());
+ registerFunction("trim", new SQLFunctionTemplate(StandardBasicTypes.STRING, "trim(?1 ?2 ?3 ?4)"));
+ registerFunction("upper", new StandardSQLFunction("upper", StandardBasicTypes.STRING));
+ registerFunction("ascii", new StandardSQLFunction("ascii", StandardBasicTypes.INTEGER));
+ registerFunction("btrim", new StandardSQLFunction("btrim", StandardBasicTypes.STRING));
+ registerFunction("chr", new StandardSQLFunction("chr", StandardBasicTypes.CHARACTER));
+ registerFunction("initcap", new StandardSQLFunction("initcap"));
+ registerFunction("length", new StandardSQLFunction("length", StandardBasicTypes.INTEGER));
+ registerFunction("lpad", new StandardSQLFunction("lpad", StandardBasicTypes.STRING));
+ registerFunction("ltrim", new StandardSQLFunction("ltrim", StandardBasicTypes.STRING));
+ registerFunction("md5", new StandardSQLFunction("md5", StandardBasicTypes.STRING));
+ registerFunction("repeat", new StandardSQLFunction("repeat", StandardBasicTypes.STRING));
+ registerFunction("replace", new StandardSQLFunction("replace", StandardBasicTypes.STRING));
+ registerFunction("rpad", new StandardSQLFunction("rpad", StandardBasicTypes.STRING));
+ registerFunction("rtrim", new StandardSQLFunction("rtrim", StandardBasicTypes.STRING));
+ registerFunction("split_part", new StandardSQLFunction("split_part", StandardBasicTypes.STRING));
+ registerFunction("strpos", new StandardSQLFunction("strpos", StandardBasicTypes.INTEGER));
+ registerFunction("to_hex", new StandardSQLFunction("to_hex", StandardBasicTypes.STRING));
+ registerFunction("translate", new StandardSQLFunction("translate", StandardBasicTypes.STRING));
+
+ // type conversion related functions
+ registerFunction("to_char", new StandardSQLFunction("to_char", StandardBasicTypes.STRING));
+ registerFunction("to_date", new StandardSQLFunction("to_date", StandardBasicTypes.DATE));
+ registerFunction("to_number", new StandardSQLFunction("to_number", StandardBasicTypes.BIG_DECIMAL));
+ registerFunction("to_timestamp", new StandardSQLFunction("to_timestamp", StandardBasicTypes.TIMESTAMP));
+
+ // other function
+ registerFunction("stddev", new StandardSQLFunction("stddev", StandardBasicTypes.DOUBLE));
+ registerFunction("variance", new StandardSQLFunction("variance", StandardBasicTypes.DOUBLE));
+ registerFunction("rand", new NoArgSQLFunction("random", StandardBasicTypes.DOUBLE));
+ registerFunction("to_ascii", new StandardSQLFunction("to_ascii"));
+ registerFunction("quote_ident", new StandardSQLFunction("quote_ident", StandardBasicTypes.STRING));
+ registerFunction("quote_literal", new StandardSQLFunction("quote_literal", StandardBasicTypes.STRING));
+ registerFunction("age", new StandardSQLFunction("age"));
+ registerFunction("current_date", new NoArgSQLFunction("current_date", StandardBasicTypes.DATE, false));
+ registerFunction("current_time", new NoArgSQLFunction("current_time", StandardBasicTypes.TIME, false));
+ registerFunction("current_timestamp", new NoArgSQLFunction("current_timestamp", StandardBasicTypes.TIMESTAMP, false));
+ registerFunction("date_trunc", new StandardSQLFunction("date_trunc", StandardBasicTypes.TIMESTAMP));
+ registerFunction("localtime", new NoArgSQLFunction("localtime", StandardBasicTypes.TIME, false));
+ registerFunction("localtimestamp", new NoArgSQLFunction("localtimestamp", StandardBasicTypes.TIMESTAMP, false));
+ registerFunction("now", new NoArgSQLFunction("now", StandardBasicTypes.TIMESTAMP));
+ registerFunction("timeofday", new NoArgSQLFunction("timeofday", StandardBasicTypes.STRING));
+ registerFunction("current_user", new NoArgSQLFunction("current_user", StandardBasicTypes.STRING, false));
+ registerFunction("session_user", new NoArgSQLFunction("session_user", StandardBasicTypes.STRING, false));
+ registerFunction("user", new NoArgSQLFunction("user", StandardBasicTypes.STRING, false));
+ registerFunction("current_database", new NoArgSQLFunction("current_database", StandardBasicTypes.STRING, true));
+ registerFunction("current_schema", new NoArgSQLFunction("current_schema", StandardBasicTypes.STRING, true));
+ registerFunction("locate", new PositionSubstringFunction());
+ registerFunction("str", new SQLFunctionTemplate(StandardBasicTypes.STRING, "cast(?1 as varchar)"));
+ }
+
+ // database type mapping support
+ @Override
+ public SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) {
+ SqlTypeDescriptor descriptor;
+ switch (sqlCode) {
+ case Types.BLOB: {
+ descriptor = BlobTypeDescriptor.BLOB_BINDING;
+ break;
+ }
+ case Types.CLOB: {
+ descriptor = ClobTypeDescriptor.CLOB_BINDING;
+ break;
+ }
+ default: {
+ descriptor = super.getSqlTypeDescriptorOverride(sqlCode);
+ break;
+ }
+ }
+ return descriptor;
+ }
+
+ // hibernate type mapping support
+ // extend...
+
+ // function support
+ // extend...
+
+ // native identifier generation
+ @Override
+ public String getNativeIdentifierGeneratorStrategy() {
+ return "sequence";
+ }
+
+ // IDENTITY support
+ @Override
+ public IdentityColumnSupport getIdentityColumnSupport() {
+ return new OpenGaussIdentityColumnSupport();
+ }
+
+ // SEQUENCE support
+ @Override
+ public boolean supportsSequences() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsPooledSequences() {
+ return true;
+ }
+
+ @Override
+ public String getSequenceNextValString(String sequenceName) {
+ return "select " + getSelectSequenceNextValString(sequenceName);
+ }
+
+ @Override
+ public String getSelectSequenceNextValString(String sequenceName) {
+ return "nextval('" + sequenceName + "')";
+ }
+
+ @Override
+ public String getCreateSequenceString(String sequenceName) {
+ return "create sequence " + sequenceName;
+ }
+
+ @Override
+ protected String getCreateSequenceString(String sequenceName, int initialValue, int incrementSize) {
+ if (initialValue < 0 && incrementSize > 0) {
+ return String.format("%s minvalue %d start %d increment %d", getCreateSequenceString(sequenceName), initialValue, initialValue, incrementSize);
+ } else if (initialValue > 0 && incrementSize < 0) {
+ return String.format("%s maxvalue %d start %d increment %d", getCreateSequenceString(sequenceName), initialValue, initialValue, incrementSize);
+ } else {
+ return String.format("%s start %d increment %d", getCreateSequenceString(sequenceName), initialValue, incrementSize);
+ }
+ }
+
+ @Override
+ public String getDropSequenceString(String sequenceName) {
+ return "drop sequence if exists " + sequenceName;
+ }
+
+ @Override
+ public String getQuerySequencesString() {
+ return "select * from information_schema.sequences";
+ }
+
+ // GUID support
+ // extend...
+
+ // limit/offset support
+ private static final AbstractLimitHandler LIMIT_HANDLER = new AbstractLimitHandler() {
+ @Override
+ public String processSql(String sql, RowSelection selection) {
+ final boolean hasOffset = LimitHelper.hasFirstRow(selection);
+ return sql + (hasOffset ? " limit ? offset ?" : " limit ?");
+ }
+
+ @Override
+ public boolean supportsLimit() {
+ return true;
+ }
+
+ @Override
+ public boolean bindLimitParametersInReverseOrder() {
+ return true;
+ }
+ };
+
+ @Override
+ public LimitHandler getLimitHandler() {
+ return LIMIT_HANDLER;
+ }
+
+ // lock acquisition support
+ @Override
+ public String getForUpdateString(String aliases) {
+ return getForUpdateString() + " of " + aliases;
+ }
+
+ @Override
+ public String getForUpdateString(String aliases, LockOptions lockOptions) {
+ LockMode lockMode = lockOptions.getLockMode();
+ if (aliases != null && !aliases.isEmpty()) {
+ lockMode = lockOptions.getAliasSpecificLockMode(aliases);
+ if (lockMode == null) {
+ lockMode = lockOptions.getLockMode();
+ }
+ }
+ switch (lockMode) {
+ case UPGRADE:
+ return getForUpdateString(aliases);
+ case PESSIMISTIC_READ:
+ return getReadLockString(aliases, lockOptions.getTimeOut());
+ case PESSIMISTIC_WRITE:
+ return getWriteLockString(aliases, lockOptions.getTimeOut());
+ case UPGRADE_NOWAIT:
+ case FORCE:
+ case PESSIMISTIC_FORCE_INCREMENT:
+ return getForUpdateNowaitString(aliases);
+ case UPGRADE_SKIPLOCKED:
+ return getForUpdateSkipLockedString(aliases);
+ default:
+ return "";
+ }
+ }
+
+ @Override
+ public String getWriteLockString(int timeout) {
+ if (timeout == LockOptions.NO_WAIT) {
+ return " for update nowait";
+ } else if (timeout == LockOptions.SKIP_LOCKED) {
+ return " for update skip locked";
+ } else {
+ return " for update";
+ }
+ }
+
+ @Override
+ public String getWriteLockString(String aliases, int timeout) {
+ if (timeout == LockOptions.NO_WAIT) {
+ return String.format(" for update of %s nowait", aliases);
+ } else if (timeout == LockOptions.SKIP_LOCKED) {
+ return String.format(" for update of %s skip locked", aliases);
+ } else {
+ return " for update of " + aliases;
+ }
+ }
+
+ @Override
+ public String getReadLockString(int timeout) {
+ if (timeout == LockOptions.NO_WAIT) {
+ return " for share nowait";
+ } else if (timeout == LockOptions.SKIP_LOCKED) {
+ return " for share skip locked";
+ } else {
+ return " for share";
+ }
+ }
+
+ @Override
+ public String getReadLockString(String aliases, int timeout) {
+ if (timeout == LockOptions.NO_WAIT) {
+ return String.format(" for share of %s nowait", aliases);
+ } else if (timeout == LockOptions.SKIP_LOCKED) {
+ return String.format(" for share of %s skip locked", aliases);
+ } else {
+ return " for share of " + aliases;
+ }
+ }
+
+ @Override
+ public String getForUpdateNowaitString() {
+ return getForUpdateString() + " nowait";
+ }
+
+ @Override
+ public String getForUpdateNowaitString(String aliases) {
+ return getForUpdateString(aliases) + " nowait";
+ }
+
+ @Override
+ public String getForUpdateSkipLockedString() {
+ return getForUpdateString() + " skip locked";
+ }
+
+ @Override
+ public String getForUpdateSkipLockedString(String aliases) {
+ return getForUpdateString(aliases) + " skip locked";
+ }
+
+ // callable statement support
+ @Override
+ public int registerResultSetOutParameter(CallableStatement statement, int position) throws SQLException {
+ statement.registerOutParameter(position, Types.REF_CURSOR);
+ position++;
+ return position;
+ }
+
+ @Override
+ public ResultSet getResultSet(CallableStatement statement) throws SQLException {
+ statement.execute();
+ return (ResultSet) statement.getObject(1);
+ }
+
+ @Override
+ public ResultSet getResultSet(CallableStatement statement, int position) throws SQLException {
+ if (position != 1) {
+ throw new UnsupportedOperationException("OpenGauss only supports REF_CURSOR parameters as the first parameter");
+ }
+ return (ResultSet) statement.getObject(1);
+ }
+
+ // current timestamp support
+ @Override
+ public boolean supportsCurrentTimestampSelection() {
+ return true;
+ }
+
+ @Override
+ public boolean isCurrentTimestampSelectStringCallable() {
+ return false;
+ }
+
+ @Override
+ public String getCurrentTimestampSelectString() {
+ return "select current_timestamp"; // select current_timestamp
+ }
+
+ // SQLException support
+ @Override
+ public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
+ return new SQLExceptionConversionDelegate() {
+ @Override
+ public JDBCException convert(SQLException sqlException, String message, String sql) {
+ final String sqlState = JdbcExceptionHelper.extractSqlState(sqlException);
+
+ if (sqlState != null && sqlState.length() >= 2) {
+ String sqlStateClassCode = sqlState.substring(0, 2);
+ switch (sqlStateClassCode) {
+ case "23":
+ switch (sqlState) {
+ case "23505":
+ case "23503":
+ case "23502": {
+ String constraintName = getViolatedConstraintNameExtracter().extractConstraintName(sqlException);
+ return new ConstraintViolationException(message, sqlException, sql, constraintName);
+ }
+ }
+ return new ConstraintViolationException(message, sqlException, sql, null);
+ case "22":
+ return new DataException(message, sqlException, sql);
+ case "40":
+ return new LockAcquisitionException(message, sqlException, sql);
+ case "08":
+ return new JDBCConnectionException(message, sqlException, sql);
+ case "55":
+ return new PessimisticLockException(message, sqlException, sql);
+ case "57":
+ return new QueryTimeoutException(message, sqlException, sql);
+ default:
+ return null;
+ }
+ }
+ return null;
+ }
+ };
+ }
+
+ private static final ViolatedConstraintNameExtracter EXTRACTOR = new TemplatedViolatedConstraintNameExtracter() {
+ @Override
+ protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
+ final String sqlState = JdbcExceptionHelper.extractSqlState(sqle);
+ if (sqlState == null) {
+ return null;
+ }
+ switch (sqlState) {
+ // CHECK VIOLATION
+ case "23514":
+ return extractUsingTemplate("violates check constraint \"", "\"", sqle.getMessage());
+ // UNIQUE VIOLATION
+ case "23505":
+ return extractUsingTemplate("violates unique constraint \"", "\"", sqle.getMessage());
+ // FOREIGN KEY VIOLATION
+ case "23503":
+ return extractUsingTemplate("violates foreign key constraint \"", "\"", sqle.getMessage());
+ // NOT NULL VIOLATION
+ case "23502":
+ return extractUsingTemplate("null value in column \"", "\" violates not-null constraint", sqle.getMessage());
+ // 其他约束违规类型
+ default:
+ return null;
+ }
+ }
+ };
+
+ @Override
+ public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
+ return EXTRACTOR;
+ }
+
+ // union subclass support
+ @Override
+ public boolean supportsUnionAll() {
+ return true;
+ }
+
+ // miscellaneous support
+ @Override
+ public String getNoColumnsInsertString() {
+ return "default values";
+ }
+
+ @Override
+ public String getCaseInsensitiveLike() {
+ return "ilike";
+ }
+
+ @Override
+ public boolean supportsCaseInsensitiveLike() {
+ return true;
+ }
+
+ @Override
+ public String toBooleanValueString(boolean bool) {
+ return bool ? "t" : "f";
+ }
+
+ // keyword support
+ @Override
+ public NameQualifierSupport getNameQualifierSupport() {
+ return NameQualifierSupport.SCHEMA;
+ }
+
+ @Override
+ public IdentifierHelper buildIdentifierHelper(IdentifierHelperBuilder builder, DatabaseMetaData dbMetaData) throws SQLException {
+ if (dbMetaData == null) {
+ builder.setUnquotedCaseStrategy(IdentifierCaseStrategy.LOWER);
+ builder.setQuotedCaseStrategy(IdentifierCaseStrategy.MIXED);
+ }
+ return super.buildIdentifierHelper(builder, dbMetaData);
+ }
+
+ // identifier quoting support
+ // extend...
+
+
+ // DDL support
+ @Override
+ public String[] getCreateSchemaCommand(String schemaName) {
+ return new String[]{"create schema if not exists " + schemaName};
+ }
+
+ @Override
+ public String[] getDropSchemaCommand(String schemaName) {
+ return new String[]{"drop schema if exists " + schemaName};
+ }
+
+ @Override
+ public String getCurrentSchemaCommand() {
+ return "select current_schema()";
+ }
+
+ @Override
+ public String getAddColumnString() {
+ return "add column";
+ }
+
+ @Override
+ public boolean supportsCommentOn() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsIfExistsBeforeTableName() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsIfExistsBeforeConstraintName() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsIfExistsAfterAlterTable() {
+ return true;
+ }
+
+ @Override
+ public String getCascadeConstraintsString() {
+ return " cascade";
+ }
+
+ public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
+ return new LocalTemporaryTableBulkIdStrategy(new IdTableSupportStandardImpl() {
+ @Override
+ public String getCreateIdTableCommand() {
+ return "create temporary table";
+ }
+ }, AfterUseAction.DROP, null);
+ }
+
+ // Informational metadata
+ @Override
+ public boolean supportsEmptyInList() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsRowValueConstructorSyntax() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsRowValueConstructorSyntaxInSet() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsRowValueConstructorSyntaxInInList() {
+ return true;
+ }
+
+ @Override
+ public boolean requiresParensForTupleDistinctCounts() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsSelectAliasInGroupByClause() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsNonQueryWithCTE() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsValuesList() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsLobValueChangePropogation() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsPartitionBy() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsNamedParameters(DatabaseMetaData databaseMetaData) throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsSkipLocked() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsNoWait() {
+ return true;
+ }
+}
+
diff --git a/openGaussDialect/src/main/java/org/hibernate/dialect/function/SubstringFunction.java b/openGaussDialect/src/main/java/org/hibernate/dialect/function/SubstringFunction.java
new file mode 100644
index 0000000000000000000000000000000000000000..0c33089a6589eb6a4bae29f9caffd36c3a767097
--- /dev/null
+++ b/openGaussDialect/src/main/java/org/hibernate/dialect/function/SubstringFunction.java
@@ -0,0 +1,38 @@
+package org.hibernate.dialect.function;
+
+import org.hibernate.QueryException;
+import org.hibernate.engine.spi.Mapping;
+import org.hibernate.engine.spi.SessionFactoryImplementor;
+import org.hibernate.type.StandardBasicTypes;
+import org.hibernate.type.Type;
+
+import java.util.List;
+
+public class SubstringFunction implements SQLFunction {
+
+ @Override
+ public boolean hasArguments() {
+ return true;
+ }
+
+ @Override
+ public boolean hasParenthesesIfNoArguments() {
+ return true;
+ }
+
+ @Override
+ public Type getReturnType(Type firstArgumentType, Mapping mapping) throws QueryException {
+ return StandardBasicTypes.STRING;
+ }
+
+ @Override
+ public String render(Type firstArgumentType, List arguments, SessionFactoryImplementor factory) throws QueryException {
+ if (arguments.size() == 3) {
+ return "substring(" + arguments.get(0) + " from " + arguments.get(1) + " for " + arguments.get(2) + ")";
+ } else if (arguments.size() == 2) {
+ return "substring(" + arguments.get(0) + " from " + arguments.get(1) + ")";
+ } else {
+ throw new QueryException("Invalid number of arguments for substring function: " + arguments.size());
+ }
+ }
+}
\ No newline at end of file
diff --git a/openGaussDialect/src/main/java/org/hibernate/dialect/identity/OpenGaussIdentityColumnSupport.java b/openGaussDialect/src/main/java/org/hibernate/dialect/identity/OpenGaussIdentityColumnSupport.java
new file mode 100644
index 0000000000000000000000000000000000000000..8859cdc140a9f898ed5a73e06b23dee9ef71fa4a
--- /dev/null
+++ b/openGaussDialect/src/main/java/org/hibernate/dialect/identity/OpenGaussIdentityColumnSupport.java
@@ -0,0 +1,27 @@
+package org.hibernate.dialect.identity;
+
+import java.sql.Types;
+
+public class OpenGaussIdentityColumnSupport extends IdentityColumnSupportImpl {
+
+ @Override
+ public boolean supportsIdentityColumns() {
+ return false;
+ }
+
+ @Override
+ public String getIdentitySelectString(String table, String column, int type) {
+ // {table}_{column}_seq
+ return "select currval('" + table + '_' + column + "_seq')";
+ }
+
+ @Override
+ public String getIdentityColumnString(int type) {
+ return type == Types.BIGINT ? "bigserial not null" : "serial not null";
+ }
+
+ @Override
+ public boolean hasDataTypeInIdentityColumn() {
+ return false;
+ }
+}
diff --git a/openGaussDialect/src/main/java/org/hibernate/dialect/type/JsonType.java b/openGaussDialect/src/main/java/org/hibernate/dialect/type/JsonType.java
new file mode 100644
index 0000000000000000000000000000000000000000..07e6a8b591007183bc7b1e44f26ba44f93857763
--- /dev/null
+++ b/openGaussDialect/src/main/java/org/hibernate/dialect/type/JsonType.java
@@ -0,0 +1,91 @@
+package org.hibernate.dialect.type;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.spi.SharedSessionContractImplementor;
+import org.hibernate.usertype.UserType;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Objects;
+
+public class JsonType implements UserType {
+
+ private static final ObjectMapper objectMapper = new ObjectMapper();
+
+ @Override
+ public int[] sqlTypes() {
+ return new int[] { Types.JAVA_OBJECT};
+ }
+
+ @Override
+ public Class