Spring JPA中@Lob标注ArrayList报错的原因咨询
问题分析与解答
两种写法的核心差异
- 第一种是直接给集合类型加
@Lob注解,JPA的持久化提供者(比如Hibernate)会把它当成需要特殊处理的集合结构,而非单个可序列化对象; - 第二种是给实现了
Serializable的自定义类加@Lob,这个类是一个完整的可序列化对象,集合只是它的内部属性,JPA会直接把整个类实例序列化为Blob存储。
第一种写法报错的原因
虽说ArrayList和Integer都实现了Serializable,但JPA对@Lob标注的直接集合类型,处理逻辑和单个可序列化对象完全不一样:
- JPA规范里,集合类型本来是用来映射关联表(用
@ElementCollection)或者嵌入式集合的,不是用来直接当大对象存的; - 底层持久化工具(比如Hibernate)碰到
@Lob标注的集合时,不会自动触发序列化逻辑,反而在尝试把集合转成Blob的时候,因为集合本身不是单个的“大对象实例”,直接导致类型转换失败; - 但把集合包在自定义
Serializable类里时,这个类的实例是单一的可序列化对象,@Lob会按预期把整个对象转成字节流存成Blob,集合作为对象的一部分自然被包含在序列化后的字节流里,所以能正常运行。
额外补充
如果想直接用集合加@Lob存储,可以自己写个转换器,用@Converter注解指定集合和字节数组的转换逻辑,比如:
@Lob @Convert(converter = ListToBlobConverter.class) List<Integer> bla = new ArrayList<>();
这里的ListToBlobConverter需要实现AttributeConverter<List<Integer>, byte[]>,手动完成集合的序列化和反序列化操作。
内容的提问来源于stack exchange,提问作者Jumboman
相关产品推荐
相关产品推荐

