使用从EJB到数据库的流保存blob(以内存有效的方式)

Tho*_*her 7 ejb jpa blob java-ee-6 jboss7.x

我想在数据库中保存大附件(500Mb,如果可能,甚至> 2Gb).我知道这样做的利弊经常被讨论,但这不是我的问题的焦点.

使用JPA在EJB3中存储Blob字段的传统方法是使用如下代码:

@Lob
private byte[] data;
Run Code Online (Sandbox Code Playgroud)

处理大量数据源时会出现问题,因为整个字节数组都保存在内存中.

我试图将其更改为Blob:

@Lob
private Blob data;
Run Code Online (Sandbox Code Playgroud)

但这会导致同样的问题.打电话的时候

// session: Hibernate session.
// Actually, I'd like to stay with JPA's abstraction and not
// reference Hibernate directly, if possible
Blob data = session.createBlob(inputStream, lengthOfStream);
Run Code Online (Sandbox Code Playgroud)

createBlob方法从inputStream创建一个byteArray.

由于ORM映射,我也想知道如何处理数据的插入.一个想法是创建一个实体变量

@Lob
private byte[] data;
Run Code Online (Sandbox Code Playgroud)

我永远不会用.这样,数据库模式就可以构建了.但是因为@Lob注释是懒惰的,所以它不会让我的记忆膨胀.

然后写

entityManager.persist(dataObject);
// The following lines are _completely_ imaginatory!!
query.prepare("update DataObject d set d.data = :dataInputStream where d = :dataObject");
query.setProperty("dataObject", dataObject);
query.setProperty("dataInputStream", someDataInputStream);
Run Code Online (Sandbox Code Playgroud)

我偶然发现的一个解决方案看起来不错,但是没有使用JPA: Grooviest方法将BLOB存储在数据库中?

有人建议怎么做吗?

Car*_*ini 1

@Lob 注释可以应用于可序列化对象。然后你可以声明:

@Lob
private MySmartLOB data;
Run Code Online (Sandbox Code Playgroud)

public class MySmartLOB implements Serializable {
    private void writeObject(java.io.ObjectOutputStream out)
            throws IOException {
        // tranfer data from local storage to 'out'
    }
    private void readObject(java.io.ObjectInputStream in)
            throws IOException, ClassNotFoundException {
        // tranfer data from 'in' to local storage
    }
}
Run Code Online (Sandbox Code Playgroud)

这是可行的,希望底层 JPA 实现足够智能,能够提供直接通过管道传输到 JDBC 流的 ObjectOutputStream 而不是某种丑陋的 ByteArrayOutputStream