@Basic(fetch = FetchType.LAZY) не работает?

Я использую JPA (Hibernate) с Spring. Когда я хочу использовать ленивую загрузку свойства Stirng, я использую этот синтаксис:

@Lob
@Basic(fetch = FetchType.LAZY)
public String getHtmlSummary() {
    return htmlSummary;
}

Но когда я смотрю на sql, созданный спящим режимом, кажется, что это свойство не загружено без лени? Я также использую этот класс org.hibernate.tool.instrument.javassist.InstrumentTask в ANT script, чтобы применить это свойство, но кажется, что он не работает.

Пожалуйста, помогите мне.

Хосро.

Ответы

Ответ 1

Для загрузки Lazy Lob требуется, чтобы инструментарий байт-кода работал правильно, поэтому он недоступен по умолчанию в любой реализации JPA, о которой я знаю.

Лучше всего поставить Lob в отдельный объект, например HtmlSummary, и использовать лениво загруженную взаимную связь.

Ответ 2

Использовать FieldHandled с @Basic(fetch=FetchType.LAZY) works:

public class myFile implements Serializable, FieldHandled
{

    private FieldHandler      fieldHandler;

    @Lob
    @Basic(fetch = FetchType.LAZY)
    @Column(name = "CONTENT")
    protected byte[]          content;

Ответ 3

@Entity
public class User implements FieldHandled {

    @Id
    private String uid;

    private String uname;

    private int age;

    @Lob
    @Basic(fetch = FetchType.LAZY)
    private byte[] img;

    private FieldHandler fieldHandler;

    public User() {
    }

    // getter() and setter() of uid, uname, age

    public byte[] getImg() {
        // if User user = new User() then fieldHandler is null
        // if User user = entityManager.find(User.class, "001") then fieldHandler is not null
       if(img != null) { 
           return img;
       }

       if (fieldHandler != null) { 
           return (byte[]) fieldHandler.readObject(this, "img", img);
       } else {
           return null;
       }  
    }

    public void setImg(byte[] img) {
        this.img = img;
    }

    public void setFieldHandler(FieldHandler fieldHandler) {
        this.fieldHandler = fieldHandler;
    }

    public FieldHandler getFieldHandler() {
        return fieldHandler;
    }
}

Я использую Hibernate4 h2database.I уверен, что ленивая загрузка может отлично работать с моим кодом.

Спящий режим: select user0_.uid as uid1_0_0_, user0_.age as age2_0_0_, user0_.uname as uname4_0_0_ from User user0_ where user0_.uid=?

Спящий режим: select user_.img as img3_0_ from User user_ where user_.uid=?

если использование repository.save(User) для добавления нового пользователя будет в порядке, но обновление пользователя приведет к исключению

java.lang.ClassCastException: org.hibernate.bytecode.instrumentation.spi.LazyPropertyInitializer$1 cannot be cast to java.sql.Blob

Я предлагаю использовать repository.delete(userid) до repository.save в одной транзакции, тогда она будет работать нормально.

Ответ 4

Прежде всего, вы должны знать, что спецификации JPA четко указывают, что LAZY является лишь намеком на поставщиков JPA, поэтому это не обязательное требование.

Для базового типа ленивой выборки для работы вам необходимо включить усиление байт-кода и явно установить для свойства конфигурации enableLazyInitialization значение true

<plugin>
    <groupId>org.hibernate.orm.tooling</groupId>
    <artifactId>hibernate-enhance-maven-plugin</artifactId>
    <version>${hibernate.version}</version>
    <executions>
        <execution>
            <configuration>
                <enableLazyInitialization>true</enableLazyInitialization>
            </configuration>
            <goals>
                <goal>enhance</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Ответ 5

из спецификации JPA они говорят, что даже если вы используете аннотировать свойство, которое можно получить лениво, это не гарантируется, что оно может быть применено, поэтому свойства могут или не могут быть загружены лениво (зависит от исполнителя JPA), однако, если вы укажете, что вы должны получить их с нетерпением, тогда разработчик JPA должен загружать их с нетерпением.

Нижняя строка: @Basic (fetch = FetchType.LAZY) может работать или не работать, зависит от разработчика JPA.

Ответ 6

Я думаю, что он будет похож на EclipseLink, там вам нужно включить плетение в противном случае, настройка выборки не будет иметь никакого эффекта. Для плетения требуется доступ к байт-коду. Это может помочь: fooobar.com/questions/391017/...

Ответ 7

Лестная выборка применяется только к ссылкам на другие сущности или коллекции объектов. Это не относится к значениям типа String или int.