How to release blobs with hibernate and spring @transactional?

有些话、适合烂在心里 提交于 2019-12-06 02:16:00

Since there were no answers for this, I'll post mine. The solution we could come up with was to write a class which wraps an input stream and closes it automatically once the reading is complete.

/**
 * Purpose of this class is to wrap an input stream and close it automatically once the reading is complete.
 *
 * @author Rajind Ruparathna
 */
public class SelfClosingInputStream extends FilterInputStream {

    private static final int EOF = -1;

    private boolean isClosed = false;
    private Long length;
    private Long count = 0L;

    public SelfClosingInputStream(InputStream is, Long length) {
        super(is);
        this.length = length;
    }

    public SelfClosingInputStream(InputStream is) {
        super(is);
        length = -1L;
    }

    @Override
    public int read() throws IOException {
        try {
            if (!isClosed)  {
                int val = super.read();
                count = count + 1;
                if ((length != -1L && count.equals(length)) || val == EOF) {
                    close();
                    isClosed = true;
                }
                return val;
            } else {
                return EOF;
            }
        } catch (IOException e) {
            close();
            isClosed = true;
            throw e;
        }
    }

    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        try {
            if (!isClosed)  {
                int val = super.read(b, off, len);
                count = count + val;
                if ((length != -1L && count.equals(length)) || val == EOF) {
                    close();
                    isClosed = true;
                }
                return val;
            } else {
                return EOF;
            }
        } catch (IOException e) {
            close();
            isClosed = true;
            throw e;
        }
    }
}

This class was used in the AbstractContentAwareBean class as follows.

public void setContent(Session currentSession, InputStream inputStream, long size) {
    Blob blob = Hibernate.getLobCreator(currentSession).createBlob(new SelfClosingInputStream(inputStream, size), size);
    setContent(blob);
}

Would like to thank the folks including the people who answered my question at code review for helping me write the SelfClosingInputStream class.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!