【问题标题】:How to change database type for @Lob property with Hibernate如何使用 Hibernate 更改 @Lob 属性的数据库类型
【发布时间】:2023-01-22 11:29:46
【问题描述】:

我需要让我们的应用程序与 Postgresql、Oracle 和 SQL Server 一起工作。除了字符串属性中的 @Lob 映射外,所有 3 个数据库都工作正常。对于 Oracle 和 SQLServer 工作正常(varchar(max) 和 clob),但对于 Postgresql,我想要的是文本类型,但它被映射为 oid。

我所做的是为 Postgresql 创建一个方言并覆盖 getTypeName 和 remapSqlTypeDescriptor

@Override
public String getTypeName(int code, long length, int precision, int scale) throws HibernateException {
    if (code == Types.CLOB) {
        return super.getTypeName(Types.VARCHAR, length, precision, scale);
    }
    return super.getTypeName(code, length, precision, scale);

}

@Override
public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
    if (sqlTypeDescriptor.getSqlType() == Types.CLOB) {
        return VarcharTypeDescriptor.INSTANCE;
    }
    return super.remapSqlTypeDescriptor(sqlTypeDescriptor);
}

有没有更好的方法来做到这一点?

实体中的属性

@Size(max = 300000)
@Column(name = "value")
@Lob
private String value;

通过这个映射,我得到了相同的结果

@Size(max = 300000)
@Column(name = "value")
@Type(type = "org.hibernate.type.MaterializedClobType")
@Lob
private String value;

从 Hibernate 创建句子: org.hibernate.SQL : create table table (id int4 not null, value oid, primary key (id))

【问题讨论】:

    标签: hibernate


    【解决方案1】:

    正如我在其他几个问题上的回答几乎和这个问题一样,不要为此使用@Lob。只需使用@Column(length=SOME_BIG_NUMBER)

    @Lob 表示:使用JDBC Clob API 来读/写字符串。

    但你不需要那个。您(我想)只是在滥用 @Lob 来让 Hibernate 的模式导出器生成您想要的列类型。那是不是@Lob 的语义。无论如何,Hibernate(6,我相信也是 5)会自动地如果您只指定列的长度,请选择一个合理的列类型,这样就没有必要了。

    我所做的是为 Postgresql 创建一个方言并覆盖 getTypeName 和 remapSqlTypeDescriptor

    请不要这样做;这只是一件愚蠢的事情。您只是将 @Lob 重新定义为“常规字符串处理”。只需删除 @Lob 注释即可。

    更新:所以看起来实际的真正问题是 Hibernate 5 对长字符串使用了已弃用的 long 数据类型在甲骨文上.也就是说,问题不在于 Postgres 的方言,而在于 Oracle 的方言。这实际上是三年前到今天我在 Hibernate 6 中修复的东西,但出于向后兼容性的原因,无法在 H5 中更改。

    不过没关系,应该是非常OracleXyDialect 的自定义子类中很容易更改长字符串的类型映射。只需编写如下内容:

    registerColumnType( Types.VARCHAR, "clob" );
    

    这比试图让 @Lob 意味着 not-a-lob 在 Postgres 上要简单得多。

    (我没有测试过这个。)

    或者,您可以简单地迁移到 Hibernate 6,其中这个和很多别的方言问题已经解决。

    【讨论】:

    • 感谢您的回复!我已经尝试过这种方法,Oracle 将此列生成为“long”并且数据插入正常但是当我选择 Hibernate 时抛出 GenericJDBCException(SQL 错误:17027,SQLState:99999 和 HHH000327:执行加载命令时出错)出于这个原因,我尝试使用 @Lob 注释,因为 Hibernate 正在将列生成为 clob
    • 好的,如果你包括了就好了原帖中的信息!那么,这是 Hibernate 5 吗?
    • 我已经更新了我的答案,并提出了如何进行的建议。
    猜你喜欢
    • 1970-01-01
    • 2019-10-25
    • 2018-12-22
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 2013-07-06
    • 2020-07-06
    • 1970-01-01
    相关资源
    最近更新 更多