简体   繁体   中英

How to select BLOB in chunks using Hibernate and write to a File?

I need to select Blob data and write it to a File on disk. I need to do it using the Binary Stream we get from Blob, but I am facing OutOfMemoryError and I can't find my way around it.

Entity class:

@Entity
@Table(name = "Table1")
public class AttachmentData implements Serializable
{
    // member variables
    @Column(name = "CONTENT")
    @Lob
    private Blob content;
    // getters, setters
}

Implementation class:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("default");
EntityManager em = emf.createEntityManager();
EntityTransaction et = em.getTransaction();
et.begin();
Session session = (Session) em.getDelegate(); // hibernate session
attachmentData = (AttachmentData) session.get(AttachmentData.class, new Long(1000));
InputStream is = attachmentData.getContent().getBinaryStream();
FileOutputStream fos = new FileOutputStream(new File("D:\\MyFile.wmv"));
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte buf[] = new byte[2048];
int len;
while ((len = is.read(buf)) > 0)
{
    bos.write(buf, 0, len);
    bos.flush();
}

Using Hibernate 4.2.1 and JPA 1.

Here is how I could get it to work:

Session session = (Session) em.getDelegate(); // hibernate session
session.doWork(new Work()
{
    @Override
    public void execute(Connection connection) throws SQLException
    {
        try
        {
            String QUERY_STATEMENT = "SELECT * FROM Table1 WHERE ID= ?";
            PreparedStatement preparedStatement = connection.prepareStatement(QUERY_STATEMENT);
            preparedStatement.setLong(1, new Long(123123));
            ResultSet rs = preparedStatement.executeQuery();

            while (rs.next())
            {
                String fileName = rs.getString("FILE_NAME");
                FileOutputStream outStream = new FileOutputStream(location + fileName);
                InputStream inStream = rs.getBinaryStream("CONTENT");
                try
                {
                    IOUtils.copy(inStream, outStream);
                }
                catch (Exception exc)
                {
                    exc.printStackTrace();
                }
                finally
                {
                    IOUtils.closeQuietly(outStream);
                    IOUtils.closeQuietly(inStream);
                }
            }
        }
        catch (Exception exc)
        {
            exc.printStackTrace();
        }
    }
});

The problem was with MSSQL Driver that was loading the entire data into byte[] instead of providing me a stream. I am using Oracle and MSSQL databases. This provided generic solution for both.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM