Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to lazy load an entity attribute using JPA

I have a JSF application with JPA and EclipseLink. There is an entity with several attributes including a Lob type to store large binary data.

I need to frequently search the entities and display them in a list. Only when the user wants to view that, the Large Binary data is needed.

Can I have a method to lazy load the binary data? Or do I have to take it out as another entity with one to one relationship?

like image 456
Buddhika Ariyaratne Avatar asked Jan 13 '23 07:01

Buddhika Ariyaratne


2 Answers

You either use bytecode enhancement along with @Basic(fetch=FetchType.LAZY) on attributes that are to be loaded lazily:

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

Or you can define multiple subentities to the same database table. Considering you have an attachment table that has a content column which stores BLOBs.

You can map the non-lazy attributes in a common base class:

@MappedSuperclass
public class BaseAttachment {
 
    @Id
    @GeneratedValue
    private Long id;
 
    private String name;
 
    @Enumerated
    @Column(name = "media_type")
    private MediaType mediaType;
 
    //Getters and setters omitted for brevity
}

If you only need to fetch the non-lazy attributes, you need an entity which just extends the base class:

@Entity @Table(name = "attachment")
public class AttachmentSummary extends BaseAttachment {}

This will never fetch the content column.

If you need to fetch all columns including the content one, then you can use this entity:

@Entity @Table(name = "attachment")
public class Attachment 
    extends BaseAttachment {
 
    @Lob
    private byte[] content;
 
    //Getters and setters omitted for brevity
}
like image 165
Vlad Mihalcea Avatar answered Jan 21 '23 19:01

Vlad Mihalcea


Can be done easily. Use the following annotation.

@Basic(fetch=FetchType.LAZY)

like image 28
Buddhika Ariyaratne Avatar answered Jan 21 '23 18:01

Buddhika Ariyaratne