@Basic (fetch = FetchType.LAZY) не работает? - PullRequest
16 голосов
/ 21 января 2010

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

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

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

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

Хосро.

Ответы [ 7 ]

5 голосов
/ 21 января 2010

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

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

3 голосов
/ 31 марта 2016

Прежде всего, вы должны знать, что в спецификации 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>
3 голосов
/ 06 марта 2015
@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. Я уверен, что ленивая загрузка может нормально работать с моим кодом.

Спящий режим: 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 в одной транзакции, тогда он будет работать нормально.

3 голосов
/ 20 сентября 2012

Использование FieldHandled с @Basic(fetch=FetchType.LAZY) работает:

public class myFile implements Serializable, FieldHandled
{

    private FieldHandler      fieldHandler;

    @Lob
    @Basic(fetch = FetchType.LAZY)
    @Column(name = "CONTENT")
    protected byte[]          content;
1 голос
/ 21 января 2010

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

Итог: @Basic (fetch = FetchType.LAZY) может работать или не работать, зависит от реализации JPA.

0 голосов
/ 04 декабря 2017

Я думаю, что это будет похоже на EclipseLink, там вам нужно включить ткачество, иначе настройка выборки не действуетПлетение требует доступа к байт-коду.Это может помочь: https://stackoverflow.com/a/18423704/7159396

0 голосов
/ 21 января 2010

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

...