Сохранить BLOB-объект, используя поток из EJB в базу данных (эффективным способом памяти) - PullRequest
7 голосов
/ 28 марта 2012

Я хочу сохранить в базе данных большие вложения (500 МБ, возможно, если возможно, даже> 2 ГБ). Я знаю, что плюсы и минусы этого обсуждаются очень часто, но это не главное в моем вопросе.

Обычный способ хранения полей BLOB-объектов в EJB3 с помощью JPA - использовать следующий код:

@Lob
private byte[] data;

Это становится проблемой при работе с огромными источниками данных, поскольку весь байтовый массив сохраняется в памяти.

Я пытался изменить его на Blob:

@Lob
private Blob data;

Но это приводит к той же проблеме. При звонке

// 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);

метод createBlob создает byteArray из inputStream.

Из-за сопоставления ORM мне также интересно, как обрабатывать вставку данных. Одна идея состояла в том, чтобы сделать переменную сущности

@Lob
private byte[] data;

Это я никогда не буду использовать. Таким образом, схема базы данных получает сборку. Но поскольку аннотация @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);

Одно решение, с которым я столкнулся, выглядит красиво, но не использует JPA: Самый удобный способ хранить BLOB в базе данных?

У кого-нибудь есть совет, как это сделать?

1 Ответ

1 голос
/ 30 ноября 2012

@ Аннотация объекта может быть применена к сериализуемому объекту.Затем вы можете объявить:

@Lob
private MySmartLOB data;

и

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
    }
}

Это может сработать, в надежде, что базовая реализация JPA достаточно умна, чтобы предоставить ObjectOutputStream, напрямую переданный в поток JDBCа не какой-то уродливый ByteArrayOutputStream .

...