Spring、Hibernate、Blob 延迟加载

新手上路,请多包涵

我需要有关在 Hibernate 中延迟加载 blob 的帮助。我的 Web 应用程序中有这些服务器和框架:MySQL、Tomcat、Spring 和 Hibernate。

数据库配置部分。

 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="user" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
    <property name="driverClass" value="${jdbc.driverClassName}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>

    <property name="initialPoolSize">
        <value>${jdbc.initialPoolSize}</value>
    </property>
    <property name="minPoolSize">
        <value>${jdbc.minPoolSize}</value>
    </property>
    <property name="maxPoolSize">
        <value>${jdbc.maxPoolSize}</value>
    </property>
    <property name="acquireRetryAttempts">
        <value>${jdbc.acquireRetryAttempts}</value>
    </property>
    <property name="acquireIncrement">
        <value>${jdbc.acquireIncrement}</value>
    </property>
    <property name="idleConnectionTestPeriod">
        <value>${jdbc.idleConnectionTestPeriod}</value>
    </property>
    <property name="maxIdleTime">
        <value>${jdbc.maxIdleTime}</value>
    </property>
    <property name="maxConnectionAge">
        <value>${jdbc.maxConnectionAge}</value>
    </property>
    <property name="preferredTestQuery">
        <value>${jdbc.preferredTestQuery}</value>
    </property>
    <property name="testConnectionOnCheckin">
        <value>${jdbc.testConnectionOnCheckin}</value>
    </property>
</bean>

<bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" />

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="configLocation" value="/WEB-INF/hibernate.cfg.xml" />
    <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${hibernate.dialect}</prop>
        </props>
    </property>
    <property name="lobHandler" ref="lobHandler" />
</bean>

<tx:annotation-driven transaction-manager="txManager" />

<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

实体类的一部分

@Lob
@Basic(fetch=FetchType.LAZY)
@Column(name = "BlobField", columnDefinition = "LONGBLOB")
@Type(type = "org.springframework.orm.hibernate3.support.BlobByteArrayType")
private byte[] blobField;

问题描述。我试图在网页上显示与文件相关的数据库记录,这些记录保存在 MySQL 数据库中。如果数据量很小,一切正常。但是数据量很大,我收到一个错误 java.lang.OutOfMemoryError: Java heap space 我试图在表的每一行上写入 blobFields 空值。在这种情况下,应用程序工作正常,内存不会耗尽。我得出的结论是,标记为惰性 ( @Basic(fetch=FetchType.LAZY) ) 的 blob 字段实际上并不惰性!

原文由 Alexey Khudyakov 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 379
1 个回答

我很困惑。 Emmanuel Bernard 在 ANN-418 中写道 @Lob 默认是惰性的(即你甚至不需要使用 @Basic(fetch = FetchType.LAZY) 注释)。

一些用户报告延迟加载 @Lob 不适用于所有驱动程序/数据库

一些用户报告说它在使用 字节码检测(javassit?cglib?)时有效。

但是我在文档中找不到所有这些的明确参考。

最后, 推荐的解决方法 是使用 “假的”一对一映射而不是属性。从现有类中删除 LOB 字段,创建引用相同表、相同主键并且仅将必要的 LOB 字段作为属性的新类。将映射指定为一对一,fetch=“select”, lazy=“true”。只要您的父对象仍在您的会话中,您就应该得到您想要的。 (只需将其转换为注释)。

原文由 Pascal Thivent 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题