【问题标题】:Hibernate - Out of memory inserting big blob休眠 - 内存不足插入大 blob
【发布时间】:2012-03-07 18:48:48
【问题描述】:

在 POJO 中我有:

public void setBlob(InputStream in, Long l) {
        this.blob = Hibernate.getLobCreator(SessionFactoryHelper.sessionFactory.getCurrentSession()).createBlob(in, l);
}

我在配置中将 hibernate.jdbc.use_streams_for_binary 设为 true,但它真的改变了什么吗?

保存实体时,在 session.flush() 上我得到:

   org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl release
INFO: HHH000010: On release of batch it still contained JDBC statements
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
Heap dump file created [46180174 bytes in 1.662 secs]
    at java.util.Arrays.copyOf(Arrays.java:2271)
    at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:113)
    at java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:93)
    at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:140)
    at org.hibernate.type.descriptor.java.DataHelper.extractBytes(DataHelper.java:171)
    at org.hibernate.type.descriptor.java.BlobTypeDescriptor.unwrap(BlobTypeDescriptor.java:121)
    at org.hibernate.type.descriptor.java.BlobTypeDescriptor.unwrap(BlobTypeDescriptor.java:45)
    at org.hibernate.type.descriptor.sql.BlobTypeDescriptor$4$1.doBind(BlobTypeDescriptor.java:105)
    at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:92)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:305)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:300)
    at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:57)
    at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2599)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2853)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3291)
    at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:88)
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:354)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:275)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1127)

休眠 4.1。 为什么休眠解包流到bytea?如何使休眠以使用准备好的语句 setBinaryStream?真的需要这方面的帮助。

【问题讨论】:

    标签: java hibernate insert blob


    【解决方案1】:

    我认为问题在于您的内存对象仍然填充了它的字节数组。 这与是否使用流将其持久化到数据库是一个单独的问题。

    我建议一种解决方法:不要将 blob 存储在 POJO 中。 通过直接 JDBC 将 blob 单独存储在数据库中或磁盘上,然后在 POJO 中保留对 blob 的引用(数据库主键或磁盘路径/文件名)。

    然后,当您需要返回 blob 时,从 POJO 获取引用并使用基于流的方法将其取回。

    每次需要时获取/保存 blob 的工作量更大,但如果 blob 对内存来说太大,您可能别无选择。

    【讨论】:

      【解决方案2】:

      我不知道为什么它不工作并且它应该工作,但我所做的是使用 Hibernate 将 blob 保存到数据库:

      在 POJO 中映射到一个表:

          private byte[] serializedDocx; // + getter and setter
      

      在方法中:

          ...
           SessionFactory mf = ...
           sess = mf.openSession();
           //open connection
           sess.beginTransaction();
          ...
            ByteArrayOutputStream docxBos = new ByteArrayOutputStream();
            [write to docxBos]
            someEntity.setDocx(docxBos.toByteArray());
            sess.save(someEntity);
      

      在 myEntity.hbm.xml 中

        <property name="serializedDocx" type="binary">
            <column name="serialized_docx" not-null="true"/>
          </property>
      

      在 MySQL 中:

      CREATE TABLE IF NOT EXISTS `docx` (
        `serialized_docx` longblob NOT NULL, ...
      

      HTH。

      【讨论】:

      • 感谢您的回复。我要保存的 blob 是 1gb 文件,而且我的内存有限。我不能调用 toByteArray()。是否可以让休眠使用准备好的语句setBinaryStream(int parameterIndex, java.io.InputStream x)???
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-02
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多