eclipselink - JPA N+1 issue with inheritance -


if in situation have n+1 problem use jpa "join fetch" keyword if 1 indirection (i. e. select p person p join fetch p.address) or if more 1 indirection use jpa provider-proprietary query hint, in case eclipselink (i. e. select p person query hint eclipselink.join-fetch=p.address.city). thats explained in article java persistence performance.

anyway, lately stumbled on datamodel 2 entities subclassed one. have account owns contact. contact abstract superclass extended person or company. , person have relationship list of hobbyies.

@entity public class account {     @onetoone     private contact contact; } 
@entity @inheritance(strategy = inheritancetype.joined) public abstract class contact {} 
@entity public class person extends contact {     @onetomany     private list<hobby> hobbies; } 
@entity public class company extends contact {} 

i need load list of accounts, select account a. surely ran n+1 problem, because of hobbies. no problem thought, 2 above mentioned , probed solutions can cope n+1 problem. realized not work.

select account join fetch a.contacts not fetch hobbies. nor select account a query hint eclipselink.join-fetch=a.contacts. , select account a query hint eclipselink.join-fetch=a.contacts.hobbies throws ... navigated non-existent relationship-exception.

i tried use jpa treat-function i. e. select account join fetch treat(a.contact person) p join fetch p.hobbies, not fetch hobbies , fetches persons , not companies along.

does have idea how use join fetch or eclipselink query hints accomplish such query optimization?


edit

in order answer comment chris. @batchfetch annotation @ hobbies not have impact on query. there no difference queries without it.

here sqls generated each query @batchfetch annotation

select account a

1 select id, contact_id account 2 select distinct dtype contact (id = ?) 3 select t0.id, t0.dtype, t1.id, t1.founded contact t0, company t1 ((t0.id = ?) , ((t1.id = t0.id) , t0.dtype = ?)) 4 select distinct dtype contact (id = ?) 5 select t0.id, t0.dtype, t1.id, t1.name contact t0, person t1 ((t0.id = ?) , ((t1.id = t0.id) , (t0.dtype = ?))) 6 select id, outdoor, person_id hobby (person_id = ?) ... (repetition of lines 2 6) 

select account join fetch a.contacts

select t3.id, t3.contact_id, t0.id, t0.dtype, t1.name, t2.id, t2.founded contacts t0 left outer join person t1 on (t1.id = t0.id) left outer join company t2 on (t2.id = t0.id), account t3 (t0.id = t3.contact_id) select id, outdoor, person_id hobby (person_id = ?) select id, outdoor, person_id hobby (person_id = ?) select id, outdoor, person_id hobby (person_id = ?) select id, outdoor, person_id hobby (person_id = ?) select id, outdoor, person_id hobby (person_id = ?) ... 


Comments

Popular posts from this blog

aws api gateway - SerializationException in posting new Records via Dynamodb Proxy Service in API -

asp.net - Problems sending emails from forum -