【发布时间】:2021-12-09 06:31:50
【问题描述】:
使用 Hibernate 将空字符串写入 Oracle CLOB 字段有时会导致字段中出现空 CLOB 而不是 NULL。
具有 varchar2、数字和 CLOB 字段的表 STEP 曾经被扩展为一个新的 CLOB 字段。
ALTER TABLE STEP
ADD (IN_PAR_A CLOB)
LOB(IN_PAR_A) STORE AS CLOB_STEP_IN_PAR_A
(NOCACHE FILESYSTEM_LIKE_LOGGING COMPRESS HIGH TABLESPACE <tblspace for LOBs>);
并在实体中添加了相应的字段
@Entity
@Table(name = "STEP")
@Data
public class Step {
//some other fields
@Column(name = "IN_PAR_A")
private String inParA;
}
当存储非空值时,所有工作都按预期工作。但是,当使用非空值存储的新记录后来更新为空(使用事务)时,有时字段中存储的是一个空的 CLOB 而不是 NULL。
Step entity = session.get(Step.class, "some ID");
entity.setInParA(null);
//other fields
session.update(entity);
主要问题是不稳定 - 非空值仅写入 1/3..1/4 的记录。我无法通过直接休眠存储 Step 实体在 step.inParA 字段中使用 NULL 和“”的任何组合在系统的开发实例中重现。但它发生在产品系统上。我可以通过添加触发器来调试一个小 Oracle,发现有时它会从驱动程序中获得“”,我再次无法在开发人员中重现。此外,我能够启动大约两打完全相同的序列,这导致了新的 STEP 记录,其中一些存储了空的 CLOB,而大多数存储了空。 我尝试添加一个触发器来将空替换为 NULL,但它破坏了记录 - 不知何故,而不是 NULL 或清空该字段存储了来自其他字段的一些随机数据。
要求 STEP.IN_PAR_A 包含 NULL 而不是空的 CLOB,但我不知道要修复什么。
任何建议将不胜感激。
UPD 正如建议的那样,添加 @Lob 注释会有所帮助。没有这个注释的 5 个表中的旧 14 列可以正常工作(但现在添加了注释)
【问题讨论】:
-
您是否尝试过改用
@Lob注释?我知道 Hibernate 支持 CLOB 使用 String,但也许对你的情况有帮助 -
非常感谢,这么简单的技巧帮了大忙!仍然存在疑问,为什么它在没有 @Lob 注释的情况下对所有其他 CLOB 列(5 个表中的 14 列)起作用,并且只有最后一个开始失败。但这不是那么重要。
-
我会把它作为答案。请接受它,因为其他人可以从中受益
-
我相信 Hibernate 在处理 clob 的字符串注释方面还有一些处理。
标签: java oracle hibernate clob