使用 Hibernate 和 Spring 创建 Blob
Posted
技术标签:
【中文标题】使用 Hibernate 和 Spring 创建 Blob【英文标题】:Blob creation using Hibernate and Spring 【发布时间】:2016-01-13 12:09:03 【问题描述】:我正在使用 Spring 4.2.3、Hibernate 5.0.4、JPA 2.1 来进行 ORM 的自我训练。今天我正在学习如何在 Oracle 11.2.0.4 DB 中存储Blob。
在我的应用程序中,我有 Service 和 Dao 层。
问题: 为什么我应该使用需要当前会话的Hibernate.getLobCreator 创建Blob 实例?为什么不能再使用 [Hibernate.createBlob][3] (不访问当前会话)?
在某些情况下,我可能需要初始化 Blob 字段的瞬态域模型,而无需使用 Dao 将其持久化到数据库中。
是因为(如BlobJavaDoc 中所写):
Blob 对象在创建的事务期间有效。
很抱歉问了这么愚蠢的问题,但我找不到满意的答案。
[3]:https://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/Hibernate.html#createBlob(java.io.InputStream,长)
【问题讨论】:
或者更重要的是,当其他 JPA 提供者不需要时,为什么有必要使用供应商特定的方法来持久化 Blob? 为什么要手动创建 blob?为此,有@Lob
注释...只需将其添加到byte[]
或String
参数即可。不要自己乱搞(B / C)Lobs(很久以前就是这样做的)。
@M.Deinum 谢谢你的回答。您的意思是应该在映射中使用 byte[] 或 String 而不是 (B/C)Lobs 吗?但是在Hibernate 5.0 Lobs Documentation java.sql.Clob 中也使用了字段。
将为您完成映射。您真的希望您的实体依赖于 sql 特定类型吗?这基本上将您的整个应用程序与 sql 联系起来。但是 @Lob
注释也适用于 Blob
或 Clob
字段,但你真的想要这样吗,因为它使编写这些东西变得更加复杂。
我想到的另一件事:在我的模型与 Java 字符串池中将 (B/C)Lob 映射为 String
不是问题 - 这不是一些原因JVM内存问题?
【参考方案1】:
因为 Hibernate.createBlob 现在由于某些增强功能已从休眠中删除(我不记得确切的 jira 问题 :)。你可以在网上找到)。
所以你可以使用新的 Hibernate.getLobCreator,如下所示:
public Blob createBlob(your param)
return Hibernate.getLobCreator(currentSession()).createBlob();
// check different method for createBlob as you want to pass params.
// currentSession is method of HibernateDaoSupport
// pass your session object instead of above
这里的 Blob 是 java.sql.Blob 的类型。不同类的其他 blob 方法正在实现此接口。因此,无论您使用 oracle 或 sql server 还是其他任何东西,您都将获得正确的 Blob....
因此,如果您使用的是 Hibernate 5.x.x,请按上述方式使用。
【讨论】:
如果您使用任何最新版本的 Hibernate,请使用带有@Lob
注释的字段。
在 5.5.7 上,在尝试 Hibernate.getLobCreator(session)
时遇到了一些问题(来自 Hibernate 内部代码的类转换异常!)(已经使用了很长时间);所以改用session.getLobHelper().createBlob..
【参考方案2】:
好的,我找到了一些关于如何在不访问会话对象的情况下初始化 Blob 的软解决方案。
我使用了SerialBlob 实现。下面是简单的源代码示例:
private Blob getBlob(String classpathLocation)
ClassPathResource imageFile = new ClassPathResource(classpathLocation);
Blob resource = null;
if (imageFile.exists())
try
try (InputStream inputStream = imageFile.getInputStream())
resource = new SerialBlob(StreamUtils.copyToByteArray(inputStream));
LOG.warn("Resource loaded from ", classpathLocation);
catch (Exception e)
LOG.error(MessageFormat.format("Unable to load resource from 0", classpathLocation), e);
else
LOG.warn("Resource do not exist on ", classpathLocation);
return resource;
【讨论】:
以上是关于使用 Hibernate 和 Spring 创建 Blob的主要内容,如果未能解决你的问题,请参考以下文章
Hibernate 和 Spring:尝试创建事务时出现异常
java - 如何在java桌面应用程序中使用spring(事务)和hibernate创建嵌入式H2 DB?
当实体自引用时,Spring Boot 和 Hibernate 无法自动创建表
如果不存在,则通过将 spring Jpa 与 hibernate 一起使用来创建模式