Spring,Hibernate,Blob懒加载

Ale*_*kov 25 java mysql hibernate blob lazy-loading

我需要帮助在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>
Run Code Online (Sandbox Code Playgroud)

实体类的一部分

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

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

Pas*_*ent 31

我糊涂了.Emmanuel Bernard在ANN-418中写道,@Lob默认是懒惰的(即你甚至不需要使用@Basic(fetch = FetchType.LAZY)注释).

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

有些用户报告说它在使用字节码检测时起作用(javassit?cglib?).

但是我在文档中找不到任何明确的参考.

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

  • 在我的例子中,这有帮助:父:@OneToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)@PrimaryKeyJoinColumn private FileBlobBean ... Child:just id,no parent to parent (4认同)
  • 父类@OneToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)private FileBlobBean fileBlobBean; 子类:@Id @GeneratedValue(strategy = GenerationType.IDENTITY)@Basic(optional = false)@Column(name ="Uid",nullable = false)private Long uid; @Lob @Basic(fetch = FetchType.LAZY)@Column(name ="BlobField",columnDefinition ="LONGBLOB")private byte [] blobField; @OneToOne(mappedBy ="fileBlobBean")@ JoinColumn(name ="Uid",referencedColumnName ="Uid",nullable = false)public FileBean fileBean; (3认同)

Ben*_*rge 7

延迟属性加载需要构建时字节码检测。

Hibernate 文档:使用惰性属性获取

如果您想避免字节码检测,一种选择是创建两个使用同一表的实体,一个包含 blob,另一个不包含 blob。然后仅在需要 blob 时才将实体与 blob 一起使用。


Dar*_*rov 5

我建议您使用继承来处理这种情况。有一个没有 blob 的基类和一个包含字节数组的派生类。仅当需要在 UI 上显示 blob 时才使用派生类。


Hon*_*ons 5

当然,您可以提取该值并将其放入具有惰性"@OneToOne"关系的新表中,但是在我们的应用程序中,只需使用此配置即可轻松地按需加载LOB

@Lob
@Fetch(FetchMode.SELECT)
@Type(type="org.hibernate.type.PrimitiveByteArrayBlobType")
byte[] myBlob;
Run Code Online (Sandbox Code Playgroud)

这在我们的项目中同时在PostgreSQL,MySQL,SQLServer和Oracle上进行了测试,所以它应该适用于你