如何让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
相关产品推荐
相关产品推荐

