Unionsubclass 2nd level caching no longer works for XML mappings in 5.3 and 5.4
Description
Attachments
1
- 31 Dec 2018, 09:26 AM
Activity
Show:
Lars Karlström February 17, 2020 at 1:37 PM
Created pull request: https://github.com/hibernate/hibernate-orm/pull/3244
Possible root cause for this regression is “HHH-12146 - Support enabling caching at any level within a mapped hierarchy”
The ModelBinder used for initializing hbm based mappings did not set that subclasses should inherit isCached from their super class.
Former user January 8, 2019 at 9:29 PM
https://hibernate.atlassian.net/browse/HHH-13173#icft=HHH-13173 affects joined-subclasses mapped using XML.
Fixed
Details
Details
Assignee
Lars Karlström
Lars KarlströmReporter
Emanuel Kupcik
Emanuel KupcikLabels
Worked in
Components
Fix versions
Priority
Created December 31, 2018 at 9:23 AM
Updated December 1, 2023 at 11:28 AM
Resolved April 19, 2021 at 10:55 AM
After updating an application that still uses XML mapping definition from 5.2 to 5.4 some requests suddenly started to take 10 times or even more time.
If figured out that the 2nd level caching was no longer working for some classes. Those classes are using the unionsubclass mapping. Even multiple simple session.get(unionsubclass, id) (in multiple sessions) don't fetch the entity from the 2nd level cache anymore but always hit the database. But where it hurts most is if these entities are reference from a cached collection. In this case the performance is much worse than without any caching at all as each cache miss (which is everytime now) hits the database for each entity with the ID instead of selecting them all with a single select using the foreign key.
After switching back to 5.2.17 the caching worked again as expected. I know that there were some changes regardging enabling caching on different levels in class hierarchies. But I didn't find anythign that says that the existing definitions must be changed and you cannot define any caching on the unionsubclass level anyway so I suppose this is a bug. When using annotations and MappedSuperclass it works as expected.
The attached test case inserts 2 entities, one using HBM and unionsubclass and the other annotations and mappedsuperclass. Then it fetches them using session.get() in 3 separate sessions.
Session s = openSession(); Transaction tx = s.beginTransaction(); s.save(new HbmConcrete(1L, "name", "property")); tx.commit(); s.close(); for(int i=0; i<3; ++i) { Session s1 = openSession(); Transaction tx1 = s1.beginTransaction(); HbmConcrete o = s1.get(HbmConcrete.class, 1L); assertNotNull(o); assertEquals("name", o.name); assertEquals("property", o.property); tx1.commit(); s1.close(); }
When you run it with 5.2.17 you get the follow SQL
Hibernate: insert into AnnotationConcrete (name, property, id) values (?, ?, ?) Hibernate: insert into HbmConcrete (name, property, id) values (?, ?, ?)
So there is no select at all. But when you run it with 5.4 you get this
Hibernate: insert into AnnotationConcrete (name, property, id) values (?, ?, ?) Hibernate: insert into HbmConcrete (name, property, id) values (?, ?, ?) Hibernate: select hbmconcret0_.id as id1_1_0_, hbmconcret0_.name as name2_1_0_, hbmconcret0_.property as property1_2_0_ from HbmConcrete hbmconcret0_ where hbmconcret0_.id=? Hibernate: select hbmconcret0_.id as id1_1_0_, hbmconcret0_.name as name2_1_0_, hbmconcret0_.property as property1_2_0_ from HbmConcrete hbmconcret0_ where hbmconcret0_.id=? Hibernate: select hbmconcret0_.id as id1_1_0_, hbmconcret0_.name as name2_1_0_, hbmconcret0_.property as property1_2_0_ from HbmConcrete hbmconcret0_ where hbmconcret0_.id=?
and the HBM version is fetched 3 times from the database