otter606
otter606

Reputation: 355

hibernate join fetch and second-level cache

Hi I am trying to combine the benefits of fetch joins with second-level cache but am struggling to accomplish this. I have two classes, ImageMetadata, and ImageBlob which contains a byte [] of image data. ImageMetadata has a OneToOne association with an Image blob. In my application, I sometimes just want to load the metadata, and sometimes load the ImageBlob data as well.

I've tried 2 types of mapping: 1. Eager load and cache ImageBlob

@Entity
class ImageMetadata {
 // various simple fields and ID omitted for brevity
@OneToOne(optional=false)
private ImageBlob blob;
}

@Entity
@Cache(usage=CacheConcurrencyStrategy.READ)
class ImageBlob {
 @Lob
 private byte [] data;   
 //id omitted for brevity
}

If I call session.get(imageMetadataId), the Image blob is now always loaded via the default EAGER fetch strategy, even when it's not needed, but after the 1st load it is fetched from the 2nd level cache.

So, approach 2 is to mark the association as LAZY, so that I'm not getting the ImageBlob when it's not needed, but whenever I do need it, to issue a query from ImageMetadata i left join fetch i.blob where i.id=?. But in this case, the ImageBlob is never retrieved from the second-level cache.

Is it possible to get the best of both worlds? I.e. keep the lazy association, and also benefit from 2nd-level cache?

Thanks for any advice.

Upvotes: 2

Views: 1783

Answers (1)

JCasso
JCasso

Reputation: 5523

No,

In case 1, Hibernate will always load blob whenever it loads ImageMetadata

In case 2, Join Fetch will always retrieve data from database server.

The best approach is using LAZY without combining with "join fetch".

Whenever your app calls getBlob() method, Hibernate will try to bring it from cache (1st and 2nd) If cache does not have it, Hibernate will query DB and put it to the cache (again 1st and 2nd) Recurring calls with the same id will be retrieved from cache (1st or 2nd).

Upvotes: 1

Related Questions