休眠 - 内存不足插入大块 [英] Hibernate - Out of memory inserting big blob
问题描述
在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屋!