我们正在使用一个 JPA 注释类型,看起来像这样(常规代码):
@Entity
@EqualsAndHashCode
class TextNote extends Serializable {
@Id Long id
String text
}
当第一次编写它时,我对 JPA 还很陌生,首先编写了 SQL,然后使带注释的类与 SQL 相匹配。阅读有关 PostgreSQL 的资料,似乎下表是我想要的表:
CREATE TABLE textnote (
id bigint NOT NULL,
text text
);
这行得通,我们的表看起来像这样:
id | text
-----+------------------------
837 | really long text here
我现在要做的是将 JPA 实体更正为如下所示:
@Entity
@EqualsAndHashCode
class TextNote extends Serializable {
@Id Long id
@Lob String text
}
通过添加 @Lob
注释,JPA 提供程序(在我的例子中是 hibernate)可以为我正确生成 DDL,以防我们想要换出数据库。它还准确地记录了我想要的文本字段。现在,当一个笔记被创建时,我会看到类似这样的东西:
id | text
-----+------------------------
837 | 33427
这对于新笔记来说很好,因为当我在代码中使用 String getText() 读取它时,它会返回非常长的文本。老实说,我不知道 PostgreSQL 如何实现 text
类型,理论上我也不需要知道。然而,我们的生产数据库已经有许多使用没有 @Lob
注释的旧代码存储的注释。在现有数据库上运行新代码会产生如下问题:
org.springframework.dao.DataIntegrityViolationException: Bad value for type long : not a number this time; SQL [n/a]; nested exception is org.hibernate.exception.DataException: Bad value for type long : not a number this time
对于现有笔记,SQL 中是否有一种方法可以将旧笔记迁移到正确使用 @Lob
和 text
类型?提前致谢。
最佳答案
基于Postgres large object docs看起来您必须将每个文本 block 写入一个文件并单独导入。这不是您应该在 SQL 中执行的操作。
我对JPA一无所知,但是@Lob
与DDL或切换数据库有什么关系?您已经完全更改了列的类型; Postgres 的 text
类型出了什么问题?
在此处关闭循环,以免在评论中丢失:
真正的问题是 @Lob
创建了一个 Postgres text
列,但是 Hibernate treats it作为本地 Postgres“大对象”,它在别处存储数据并在表中只留下一个 oid(然后根据列类型将其存储为文本)。这通常不是您想要的文本。
OP 的解决方案是使用 @Type(type="org.hibernate.type.StringClobType")
来强制 Hibernate 存储常规文本。
Postgres 通常不会将文本存储为五位整数。 :)
关于postgresql - 如何将 PostgreSQL 字符串迁移到文本类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14512771/