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

Viewed 31154

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;
}

But when I look at the sql that hibernate creates, it seems this property is not lazy loaded? I also use this class org.hibernate.tool.instrument.javassist.InstrumentTask in ANT script to instrument this property but it seems it does not work.

8 Answers

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.

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 had my column annotated with @Lob and its type was byte[] but it was always eager loaded.

I tried to:

  • annotate it with @Basic(fetch = FetchType.LAZY)
  • set hibernate.bytecode.use_reflection_optimizer=false

But none of these solutions worked.

I ended up with using Blob instead of byte[]

@Column(name = "BlobField", nullable = false)
@Lob
@Basic(fetch = FetchType.LAZY)
private Blob blobField;

This one gets lazily loaded and if you need to retrieve its value access this field:

String value = IOUtils.toByteArray(entity.getBlobField().getBinaryStream());

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

Related