Hibernate – 插入大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: 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。 为什么hibernate将流解包到bytea? 如何让hibernate使用预处理语句setBinaryStream? 真的需要帮助。

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

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

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

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

我不知道为什么它不工作它应该,但我用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中

     

在MySQL中:

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

HTH。