jpql не загружает Blob-объекты


@Entity
@NamedQueries({
    @NamedQuery(name = "Item.findAll", query = "select i from Item i"),
})
public class Item implements Serializable, WithId, WithNameDescription {
    @Lob
    byte[] photo;
    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
    TextualInfo english = new TextualInfo();
// more entry field, getters and setters
}

Когда я вызываю запрос Item.findAll, я предполагаю, что все байты [] попадают в память. Но я им не воспользуюсь. Так что я не хочу, чтобы принести его. Есть ли способ, как указать тот факт, что я хочу лениво загрузить фотографию в запрос jpql?

2 2

2 ответа:

По умолчанию постоянные свойства загружаются с нетерпением, и вы не можете управлять этим из JPQL. Однако вы можете попробовать изменить поведение по умолчанию и сделать photo ленивым с аннотацией Basic. Из спецификации JPA:

9.1.18 Основная Аннотация

Основная аннотация является самой простой тип сопоставления со столбцом базы данных. Основная аннотация может быть применена к постоянное свойство или экземпляр переменная любого из следующих значений типы: Java примитивные типы, оболочки примитивных типов, Ява.яз..Строка, Ява.математика.Типа BigInteger, Ява.математика.У bigdecimal в Java.утиль.Дата, Ява.утиль.Календарь, Ява.язык SQL.Дата, Ява.язык SQL.Время, Ява.язык SQL.Отметка времени, byte [], Byte [], char [], Character[], перечисления, и любой другой тип, который реализует Serializable. Как описано в разделе 2.1.6 использование основных аннотация необязательна для постоянных поля и свойства этих типов.

@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface Basic {
FetchType fetch() default EAGER;
boolean optional() default true;

Перечисление FetchType определяет стратегии извлечения данных из база данных:

public enum FetchType { LAZY, EAGER };

Стратегия EAGER является требованием ко времени выполнения провайдера персистентности эти данные должны быть с нетерпением получены. То LAZY стратегия-это подсказка к выполнения провайдера персистентности данных должно быть принесено лениво, когда это так первый доступ. Реализация такова разрешено охотно извлекать данные для который подсказка стратегии LAZY имеет было оговорено. В частности, ленивый получение может только будьте доступны для Basic отображения, для которых используется доступ на основе свойств.

Что-то вроде этого:

@Lob @Basic(fetch=LAZY)
public byte[] getPhoto() { return photo; }
Но, как уже упоминалось в спецификации, это всего лишь намек и может не поддерживаться. В этом случае альтернативой было бы использование ленивой загруженной обязательной ассоциации один-к-одному с другой сущностью (удерживающей большой двоичный объект).

Ссылки

  • спецификация JPA 1.0
    • Раздел 9.1.18 "Основные Аннотации"
    • секция 9.1.19 "Lob Annotation"

В EclipseLink вы можете управлять этим, используя FetchGroups. Чтобы использовать его, добавьте специальную аннотацию EclipseLink FetchGroup поверх класса сущностей следующим образом:

@Entity
@Table(name="person")
@FetchGroup(name="personWithNoBlobs",attributes={@FetchAttribute(name="firstName"),@FetchAttribute(name="lastName"),@FetchAttribute(name="address")})
public class Person

Либо плетение должно быть включено, либо класс сущностей должен реализовать интерфейс FetchGroupTracker, предоставляемый EclipseLink. Для использования группы fetch в JPQL используйте следующее:

query.setHint(QueryHints.FETCH_GROUP_NAME, "personWithNoBlobs");