简体   繁体   中英

@Basic(fetch = FetchType.LAZY) does not work?

I use JPA (Hibernate) with Spring. When I want to lazy load a String property, i use this syntax:

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

Lazy Lob loading would require bytecode instrumentation to work properly, so it is not available by default in any JPA implementation I'm aware of.

Your best bet is to put the Lob into a separate entity, like HtmlSummary , and use a lazily loaded one-to-one association.

Use FieldHandled with @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;
@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;
    }
}

I use Hibernate4 h2database.I am sure lazy loading can work fine by my code.

Hibernate: 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=?

Hibernate: select user_.img as img3_0_ from User user_ where user_.uid=?

if use repository.save(User) to add a new User will be ok, but update a User will throw a exception

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

I suggest use repository.delete(userid) before repository.save in one transactional, then it will work fine.

First of all, you should know that the JPA specs clearly specifies that LAZY is only a hint to JPA providers, so it's not a mandatory requirement.

For basic type lazy fetching to work, you need to enable bytecode enhancement and explicitly set the enableLazyInitialization configuration property to 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>

from the specification of JPA they say that even if you use annotate a property to be fetched lazily, this is not guaranteed to be applied, so the properties may or may not be loaded lazily (depends on the implementer of JPA), however if you specify that you should fetch them Eagerly then the JPA implementer must load them eagerly.

Bottom line: @Basic(fetch = FetchType.LAZY) may or may not work, depends on the JPA implementer.

I think that it would be similar to EclipseLink, there you need to have enabled weaving otherwise, the fetch setting takes no effect. The weaving requires bytecode access. This could help: https://stackoverflow.com/a/18423704/7159396

I had my column annotated with @Lob<\/code> and its type was byte[]<\/code> but it was always eager loaded.

  • <\/li>
  • <\/li><\/ul>

    But none of these solutions worked.

Lazy fetching only applies to references to other entities or collections of entities. It does not apply to values like String or int.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM