
# Hibernate框架插入数据开启校验时报错
#### 问题现象
客户从ORA模式数据库迁移到GaussDB数据库，表结构使用DRS工具进行迁移，迁移后客户原业务代码不可用，Hibernate框架校验表结构报错。
```
Schema-validation: wrong column type encountered in column [execute_time] in table [abnormal_event]; found [int8 (Types#BIGINT)], but expecting [int4 (Types#INTEGER)]
```
示例：
- 原ORA模式数据库中Student表结构为如下格式：
  ```
  id number(15,0)
  sid number(15,0)
  age number(10,0)
  ```
  
- 使用DRS工具迁移到GaussDB数据库后，Student表结构为如下格式：
  ```
  id bigint
  sid bigint
  age Integer
  ```
  
- 当实际数据库中Student实体类信息如下时：
  ```
  Long id
  Long sid
  Long age  --Hibernate框架校验表结构报错
  ```
  
hibernate.cfg.xml配置文件：
```
<hibernate-configuration>
    <session-factory>
        <!--GaussDB连接信息-->
        <property name="connection.driver_class">com.huawei.opengauss.jdbc.Driver</property>
        <property name="connection.url">jdbc:opengauss://x.x.x.x:xx/postgres?currentSchema=public</property>
        <property name="connection.username">xxxxxx</property>
        <property name="connection.password">xxxxxx</property>
        <!-- 以下为可选配置 -->
        <!--是否支持方言 -->
        <!--在pgsql兼容模式下，必须有如下配置-->
         <property name="dialect">org.hibernate.dialect.PostgreSQL92Dialect</property>
        <!--在ORA数据库兼容模式下，推荐换如下配置-->
<!--        <property name="dialect">org.hibernate.dialect.OracleDialect</property>-->
        <property name="met"></property>
        <!--执行CURD时是否打印sql语句  -->
        <property name="show_sql">true</property>
        <!--自动建表-->
<!--         <property name="hbm2ddl.auto">create</property>-->
        <!--插入数据时开启校验-->
        <property name="hbm2ddl.auto">validate</property>
        <!--关闭校验-->
<!--         <property name="hbm2ddl.auto">none</property>-->
        <!-- 资源注册 (实体类映射文件)-->
        <mapping resource="student.xml"/>
    </session-factory>
</hibernate-configuration>
```
插入数据的主函数：
```
// 创建要测试的对象
Student student = new Student();
student.setId(20L);
student.setAge(222L);
student.setSid(222L);
// 开启事务,基于session得到
Configuration conf = new Configuration().configure();
SessionFactory sessionFactory = conf.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
// 通过session保存数据
session.save(student);
// 提交事务
transaction.commit();
// 操作完毕,关闭session连接对象
session.close();
```
#### 原因分析
- ORA模式数据库能够插入成功并通过校验：Hibernate框架在校验数据时，通过判断插入数据类型java.lang.Long的TypeCode，与表结构的number类型的TypeCode进行对比，结果不一致，随后会把插入数据的long类型的sqlType与表结构的Type作比较，将long类型转成number(19,0)（对应关系由org.hibernate.dialect.OracleDialect进行维护），因为表结构的type是number，number(19,0)以number开头，所以校验可以通过。使用ORA模式数据库时，业务代码涉及整数类型的数据，可以使用java.lang.Long类型插入。
- GaussDB数据库校验不同，关闭校验后数据插入成功：Hibernate框架在插入数据做校验时，业务代码是java.lang.Long类型，和表数据类型bigint的TypeCode是对应的，所以不报错。但是表数据类型是Integer时无法对应，首先判断业务代码java.lang.Long类型的TypeCode，与表数据Integer的TypeCode比较，结果不一致，之后根据org.hibernate.dialect.PostgreSQLDialect对应关系，会将long类型转换为int8，将表数据类型Integer转换为int4，无法对应，所以校验失败。使用GaussDB数据库时，业务代码涉及整数类型的数据，必须使用表类型对应的Java整型。
 
#### 处理方法
可使用以下方式进行问题处理：
- 关闭校验功能。
- 客户修改业务代码，针对不同的表数据类型，采用对应的Java整型。
 
