Hi. In our app business data is associated with dictionary entities via join tables.
I’m trying to improve the performance of my app and I made some dictionary entities cacheable. Lookup by id now works as expected, but I thought that Hibernate would also make the lazy collection SQL smaller and take the @Basic fields of dictionary entities from the cache, but it didn’t happen.
After that I marked the @Basic dictionary fields as lazy and repeated my tests. Now indeed the lazy collection SQL only selects the dictionary id and the other side id from the join table, but there’s a new problem: if the dictionary entity was never looked up by id in the current Session, then taking it from the lazy collection returns an uninitialized proxy and accessing its fields causes another SQL! Is it possible to make the lazy collection load objects from second level cache?
final Set<Language> lazyCollection = book.getBookLanguages();
// Uncomment to load from 2nd-level cache into Session:
// findLang(em, 1L);
// findLang(em, 2L);
// findLang(em, 3L);
// good:
// select bl1_0."bookid",bl1_1."id" from "b2l" bl1_0 join "TestCache2$Language"
// bl1_1 on bl1_1."id"=bl1_0."langid" where bl1_0."bookid"=?
lazyCollection.size();
for (final Language lang : lazyCollection) {
final long id = lang.getId();
// bad:
// select l1_0."code",l1_0."name" from
// "TestCache2$Language" l1_0 where l1_0."id"=?
lang.getCode();
}
Upd: In org.hibernate.sql.results.graph.entity.AbstractEntityInitializer.resolveEntityInstance I see that entityDescriptor.canUseReferenceCacheEntries() (“hibernate.cache.use_reference_entries”) should do what I need, but when I apply this setting, 2lc stops working completely for the Language entity because of java.io.NotSerializableException: snippet.TestCache2$Language
. After adding “implements Serializable” the error changes to NotSerializableException: org.hibernate.persister.entity.SingleTableEntityPersister
isolated project to reproduce