休眠 - 内存不足插入大块 [英] Hibernate - Out of memory inserting big blob

查看:149
本文介绍了休眠 - 内存不足插入大块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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:在批量发布时,它仍包含JDBC语句
线程AWT-EventQueue-0中的异常java .lang.OutOfMemoryError:Java堆空间
创建堆转储文件[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(BlobTypeD escriptor.java:121)
在org.hibernate.type.descriptor.java.BlobTypeDescriptor.unwrap(BlobTypeDescriptor.java:45)
在org.hibernate.type.descriptor.sql.BlobTypeDescriptor $ 4 $ 1。 doBind(BlobTypeDescriptor.java:105)
在org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:92)
在org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType。
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:300)
at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:57)
在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.hibern ate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:88)
位于org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362)
位于org.hibernate.engine。 spi.ActionQueue.executeActions(ActionQueue.java:354)
在org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:275)
在org.hibernate.event.internal.AbstractFlushingEventListener。在org.hibernate.internal.SessionImpl.flush(SessionImpl.java: 1127)

Hibernate 4.1。
为什么hibernate将数据流解包为bytea?我怎样才能让休眠使用准备语句setBinaryStream?真的需要帮助。

解决方案

我相信问题在于你的内存中的对象仍然有它的字节数组填充。
这是一个单独的问题,不同于流是否用于将其持久保存到数据库。



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



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



每次需要时获取/保存blob的工作量更大,但如果blob对于内存来说太大,则可能没有其他选择。


In POJO i have:

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

I made hibernate.jdbc.use_streams_for_binary true in config, but does it really change something?

when saving entity, on session.flush() i get:

   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)

Hibernate 4.1. Why hibernate unwrapping stream to bytea? How can i make hibernate to use prepared statement setBinaryStream? Really need help on this.

解决方案

I believe that the problem is that your in-memory object still has it's byte array populated. This is a separate issue from whether or not a stream is used to persist it to the database.

I suggest a work-around: don't store the blob in the POJO. Store the blob separately, either in the database via straight JDBC, or on disk, and then just keep a reference to the blob in your POJO (either the database primary key or the disk path/filename).

Then, when you need the blob back, get the reference from the POJO and use stream-based methods to get it back.

It's more work to get / save the blob every time that you need to, but if the blob is too large for memory, you may not have any other choice.

这篇关于休眠 - 内存不足插入大块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆