我们使用的JPA注释类型如下(groovy代码):
@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如何实现文本类型,也不需要理论上的理解.然而,我们的生产数据库已经有许多使用旧代码存储的笔记,而没有@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和文本类型?提前致谢.
基于
Postgres large object docs,您需要将每个文本块写入文件并单独导入.这不是你应该在sql中做的事情.
我不了解JPA的任何内容,但是@Lob与DDL或数据库切换有什么关系?您已经完全改变了列的类型; Postgres的文字类型有什么问题?
真正的问题是@Lob创建一个Postgres文本列,但是Hibernate treats it是一个本地的Postgres“大对象”,它将数据存储在其他位置,并在表中留下一个oid(根据列类型将其保存为文本) .这通常不是你想要的文字.
OP的解决方案是拍摄@Type(type =“org.hibernate.type.StringClobType”),以强制Hibernate存储常规文本.
Postgres通常不会将文本存储为五位数的整数.