【问题标题】:Blob creation using Hibernate and Spring使用 Hibernate 和 Spring 创建 Blob
【发布时间】: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 注释也适用于 BlobClob 字段,但你真的想要这样吗,因为它使编写这些东西变得更加复杂。
  • 我想到的另一件事:在我的模型与 Java 字符串池中将 (B/C)Lob 映射为 String 不是问题 - 这不是一些原因JVM内存问题?

标签: java spring hibernate jpa jdbc


【解决方案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;
}

【讨论】:

    猜你喜欢
    • 2023-03-06
    • 2018-11-23
    • 2013-02-19
    • 1970-01-01
    • 2016-05-09
    • 1970-01-01
    • 2021-02-13
    • 2012-11-30
    • 1970-01-01
    相关资源
    最近更新 更多