如何解决带有 Postgres 的 JPA 在@Lob 列中异常地将文本写入为数字
我正在尝试使用具有 Java @Lob
类型的 String
列将其内容映射到 Postgres 中的 TEXT
。这是相关实体:
@Entity(name="Metadata")
public class Metadata {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "created_on")
@ColumnDefault(value="CURRENT_TIMESTAMP")
@Generated(GenerationTime.INSERT)
private LocalDateTime createdOn;
@Lob
@Column(name = "content")
private String content;
@Column(name = "draft")
private Boolean draft;
@OnetoMany(cascade = javax.persistence.CascadeType.ALL,fetch = FetchType.LAZY,mappedBy = "Metadata")
private List<Attachment> attachments;
public void addAttachment(Attachment attachment) {
if (attachments == null) {
attachments = new ArrayList<>();
}
attachments.add(attachment);
attachment.setMetadata(this);
}
// getters and setters
}
我有基于使用输入创建新 Metadata
实体的代码。我在 IntelliJ 调试模式下手动验证该实体将 content
设置为其预期值(恰好是 JSON 字符串)。然而,当我在运行代码后检查 Postgres 时,我看到了这个数据:
my_db=> select * from Metadata;
id | content | created_on | draft
----+---------+-------------------------+-------
1 | 49289 | 2021-04-26 14:21:25.733 | t
(1 row)
请注意,奇怪的值 49289
出现在我们希望看到 JSON 字符串的位置。请注意,我还从命令行验证了正确的表是创建的:
CREATE TABLE scarfon_attachment (
id bigint NOT NULL,contents text,filename character varying(255),scarfon_id bigint NOT NULL
);
实体/表中的所有其他列都按预期工作。 @Lob
注释可能有什么问题。作为参考,我正在运行一个相当旧版本的 Postgres (9.2),但它并不是那么古老。
解决方法
当使用 @Lob
时,Hibernate ORM 会期望数据库中有一个 text
类型的列,您可以使用它来保存最大为 1 Gb 的文本文件。
您可以避免使用它,它会将列的类型更改为 VARCHAR(255)
。
不同之处在于您可以限制 VARCHAR
的大小,ORM 的默认值为 255,但您不能限制 text
的大小。
您还可以更改默认列类型(我认为 varchar 可以大到 1Gb):
@Column(name = "content",columnDefinition = "varchar(500)")
String content
因此,最终使用哪种方法取决于您。我假设对于大字符串 text
更好,但您需要评估您的用例。
我在这里的第一个疑问是由于许多来源提出了创建 TEXT
列的多种方法。例如,this Baeldung post 建议除了使用带有 @Lob
注释的定义外还使用 @Column
。
事实证明,并非所有数据库都对 @Lob
进行了相同的解释。在 Postgres 的情况下,仅使用 @Lob
将导致 Postgres 将列内容存储在不同 表中,使用 @Lob
注释的列仅存储每个的 ID该表中的条目。虽然有人建议 here 通过 @Type
注释指定正确的类型也可以解决这个问题,但我决定采用 Baledung 帖子的第二个建议,它使用 @Column
:
@Lob
@Column(columnDefinition="TEXT")
private String content;
这工作正常,并且生成的 Postgres 表具有预期的 TEXT
定义。上述唯一的潜在问题可能集中在对其他 SQL 数据库的可移植性,这些数据库可能不支持 TEXT
类型,或者可能支持某些替代方案。我没有在 Postgres 和 H2 之外进行测试,但在这两种情况下,上述方法都没有问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。