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 hobby
ies.
@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
Post a Comment