JPA ленивый на уровне простого байта [] - PullRequest
9 голосов
/ 26 октября 2011

К сожалению, приведенный ниже код не работает. Изображение всегда получается!

@Entity
public Car implements Serializable {
    ...
    @Basic(fetch = FetchType.LAZY) //Neither with @Lob
    private byte[] image;
    ...
}

НАСТРОЙКА : JPA 2.0 / Hibernate 3.5 / MySQL 5.5

Ответы [ 4 ]

3 голосов
/ 26 октября 2011

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

JPA Технические характеристики 2.0 11.1.6

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

2 голосов
/ 07 ноября 2014

Хитрость, как этого добиться, описана в этой теме: http://justonjava.blogspot.it/2010/09/lazy-one-to-one-and-one-to-many.html

Я проверил это на Hibernate v.4.3.5 и JPA v.1.5.0, PostgreSQL 9.3. Работал как шарм. Пример:

public class Attachment implements FieldHandled{
    @Transient
    private FieldHandler fieldHandler;
...
...
    @Lob
    @Column(name=CONTENT, nullable=false)
    @Basic(fetch = FetchType.LAZY, optional = false)
    private byte[] content;

...
...
    public byte[] getContent() {
    if(fieldHandler!=null){
        return (byte[])fieldHandler.readObject(this, "content", content);
    }
    return content;
    }

    public void setContent(byte[] content) {
    if(fieldHandler!=null){
        fieldHandler.writeObject(this, "content", this.content, content);
        return;
    }
    this.content = content;
    }

}

Примечание. Если вы используете CGLib, реализуйте net.sf.cglib.transform.impl.InterceptFieldEnabled вместо FieldHandled, используя тот же подход.

1 голос
/ 12 октября 2012

Насколько мне известно, отложенная загрузка возможна только при наличии отношения @OneToMany (если только вы не используете классное переплетение).По крайней мере, так EclipseLink объясняет это http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Mapping/Basic_Mappings/Lazy_Basics,, и это имеет смысл с точки зрения языка Java.Когда у вас есть

@OneToMany (fetch = FetchType.LAZY)
Collection<Employee> employees;

Collection - это интерфейс, поэтому JPA может легко использовать свою собственную реализацию Collections, которая лениво загружает данные, когда вы начинаете итерацию по ним.Если у вас есть объект с полем типа byte[], его значение либо равно нулю, либо содержит все данные, так работает Java.Единственный способ обойти это - использовать ткачество классов и создать байт-код, который выглядит как байтовый массив, но не содержит никаких данных, пока вы не получите к нему доступ.

0 голосов
/ 26 октября 2011

Я помню, что это был вопрос, давным-давно (около 2007 г.): а именно, почему байтовые массивы охотно выбираются, даже если они объявлены как ленивые. Видимо, ребята из Hibernate до сих пор не исправили эту проблему.

Вот несколько жизнеспособных альтернатив:

Кулак, попробуйте также пометить свое поле с помощью @Lob и посмотреть, работает ли оно как ожидалось.

Во-вторых, замените ваш byte[] на java.sql.Blob, у него есть удобные методы для установки и получения фактического байтового массива, так что это не будет большой рефакторинг, и это должно фактически решить проблему отложенной загрузки:

http://download.oracle.com/javase/1.4.2/docs/api/java/sql/Blob.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...