java - 字节 [] 上的休眠 @Lob 导致“long 类型的值错误”
问题描述
我试图byte[] content
在 Spring Boot 下使用 Hibernate 懒惰地获取单个 java 属性,访问 PostgreSQL 数据库。所以我把测试应用程序放在一起来测试不同的解决方案。其中一个要求我@Lob
在所述属性上使用注释,所以我做到了。现在从数据库中读取实体会导致非常奇怪的错误,确切地说:
Bad value for type long : \x454545454545445455
该值\x45...
是 bytea 列的值而不是 bigint 列,为什么即使它是错误的列,它也试图强制它进入 long?为什么一列上的注释会以某种方式影响另一列?至于修复,删除@Lob
似乎有效(至少在我的堆栈中),但问题仍然无法解释,我想知道发生了什么,而不是盲目地继续前进。是错误还是我完全误解了某些东西?
实体:
@Entity
@Table(name = "blobentity")
public class BlobEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Lob //this annotation breaks code
@Column(name = "content")
@Basic(fetch = FetchType.LAZY)
private byte[] content;
@Column(name = "name")
private String name;
//getters/setters
}
存储库:
@Repository
public interface BlobRepo extends JpaRepository<BlobEntity, Long> {
}
调用代码:
@Autowired
BlobRepo blobrepo;
@GetMapping("lazyBlob")
public String blob () {
var t = blobrepo.findAll().get(0);
var name = t.getName();
var dataAccessedIfLazy = t.getContent();
return t.getName();
}
Postgres DDL:
CREATE TABLE test.blobentity (
id bigserial NOT NULL DEFAULT nextval('test.blobentity_id_seq'::regclass),
"name" varchar NULL,
"content" bytea NULL,
CONSTRAINT blobentity_pk PRIMARY KEY (id)
);
选择结果:
使用版本:
PostgreSQL 10.4;springframework.boot 2.4.2;这个 Spring Boot 版本附带的休眠版本
解决方案
该bytea
类型被内联到表中,而其他类型被分块到一个单独的表中,该表在 PostgreSQL 上称为 TOAST。为了访问这些值,数据库有一个通常被称为 LOB 定位器的概念,它本质上只是一个用于查找的 id。一些驱动程序/数据库只是以任何一种方式工作,但其他驱动程序/数据库可能需要匹配实际的物理表示。在您的情况下,使用@Lob
是错误的,因为 AFAIKbytea
被内联到一定大小并且 de-TOASTed 即在必要时在幕后自动物化。如果您使用的是 varbinary/blob 类型或类似的类型,则必须@Lob
像在这种情况下那样使用,主表只包含这个长的 LOB 定位器。然后,驱动程序会知道您何时使用getBlob
它必须执行一些select get_lob(?)
查询来检索实际内容。
推荐阅读
- stripe-payments - 条纹表格未正确显示
- google-cloud-platform - 使用需要 oAuth 的负载均衡器来保护我的后端应用程序
- model - 获取模型的实际数据
- laravel - 如果新价格较低,Laravel Eloquent 更新记录
- php - WordPress:获取并显示具有相同术语的帖子
- xamarin - 在 Android 和 iOS 平台上使用 Xamarin 表单从 webView 打印文档
- python - BS4 getText 函数产生意外输出
- java - 我收到 JerseyClientBuilder 的编译错误
- julia - Julia:Julia 中的数组中的 undef 是什么
- c# - 替换字符串中的ab |var11=ab|var12=100|var21=cd|var22=200| 使用正则表达式