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 ответа:
По умолчанию постоянные свойства загружаются с нетерпением, и вы не можете управлять этим из 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");