Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate - Out of memory inserting big 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.

like image 907
user1255418 Avatar asked Nov 14 '22 09:11

user1255418


1 Answers

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.

like image 195
GreyBeardedGeek Avatar answered Nov 16 '22 02:11

GreyBeardedGeek