You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Hibernate 6.4不将@Column(text)字段存为PostgreSQL大对象?

解决Hibernate 6.4中Externalizable类型字段存为LOB的问题

不用修改实体类的话,这几个配置方案可以直接尝试:

方案1:全局类型映射配置

直接在Hibernate配置文件中为MyExternalizableType指定TextType处理逻辑,覆盖默认的LOB映射规则:

如果使用hibernate.cfg.xml:

<hibernate-configuration>
    <session-factory>
        <!-- 保留原有其他配置 -->
        <typedef name="externalizable-to-text" class="org.hibernate.type.TextType">
            <param name="javaType">com.yourpackage.MyExternalizableType</param>
        </typedef>
    </session-factory>
</hibernate-configuration>

Spring Boot项目可在application.properties中添加:

spring.jpa.hibernate.type_definitions=com.yourpackage.MyExternalizableType:org.hibernate.type.TextType

方案2:自定义类型全局注册

编写自定义Hibernate类型,专门处理MyExternalizableType的序列化与反序列化,将其转换为字符串存入text列:

public class MyExternalizableTextType extends AbstractSingleColumnStandardBasicType<MyExternalizableType> {
    public MyExternalizableTextType() {
        super(VarcharTypeDescriptor.INSTANCE, new MyExternalizableJavaTypeDescriptor());
    }

    @Override
    public String getName() {
        return "my-externalizable-text";
    }
}

class MyExternalizableJavaTypeDescriptor extends AbstractTypeDescriptor<MyExternalizableType> {
    public MyExternalizableJavaTypeDescriptor() {
        super(MyExternalizableType.class);
    }

    @Override
    public String toString(MyExternalizableType value) {
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
             ObjectOutputStream oos = new ObjectOutputStream(baos)) {
            value.writeExternal(oos);
            oos.flush();
            return new String(baos.toByteArray(), StandardCharsets.UTF_8);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public MyExternalizableType fromString(String string) {
        try (ByteArrayInputStream bais = new ByteArrayInputStream(string.getBytes(StandardCharsets.UTF_8));
             ObjectInputStream ois = new ObjectInputStream(bais)) {
            MyExternalizableType instance = new MyExternalizableType();
            instance.readExternal(ois);
            return instance;
        } catch (IOException | ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
}

然后在Hibernate配置文件中注册该类型并全局关联到MyExternalizableType:

<hibernate-configuration>
    <session-factory>
        <!-- 保留原有其他配置 -->
        <typedef name="my-externalizable-text" class="com.yourpackage.MyExternalizableTextType"/>
        <type-mapping>
            <type-for-class class="com.yourpackage.MyExternalizableType" type="my-externalizable-text"/>
        </type-mapping>
    </session-factory>
</hibernate-configuration>

方案3:调整LOB相关配置参数

修改Hibernate的LOB处理配置,强制优先使用TextType:

在application.properties中添加:

hibernate.jdbc.lob.non_contextual_creation=true
hibernate.type.preferred_for_lob=org.hibernate.type.TextType

这个方案操作最简单,建议先测试是否适配你的业务场景。

内容的提问来源于stack exchange,提问作者Krzysztof Grabowski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 00:52:20