JPA N + 1继承问题

时间:2016-11-10 07:15:09

标签: jpa eclipselink

如果我遇到n + 1问题的情况我通常使用JPA“join fetch”关键字,如果它只是一个间接(即从Person p join fetch p.address中选择p)或者它是不止一个间接我使用JPA提供程序专有的查询提示,在我的情况下是eclipselink(即从查询提示eclipselink.join-fetch = p.address.city的人中选择p)。这在文章Java Persistence Performance中得到了很好的解释。

无论如何,最近我偶然发现了一个数据模型,其中两个实体被另一个实体子类化。 我有Account拥有Contact。联系人本身是一个抽象的超类,它由PersonCompany扩展。并且一个人确实与Hobby的列表有关系。

@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 {}

我需要加载一个帐户列表select a from Account a。由于兴趣爱好,我肯定遇到了n + 1问题。没问题,我想,通过上面提到的两个探讨良好的解决方案,我可以解决n + 1问题。但很快我意识到这不起作用。

select a from Account a join fetch a.contacts无法获取兴趣爱好。查询提示select a from Account a eclipselink.join-fetch=a.contacts也不行。查询提示select a from Account a的{​​{1}}会抛出一个。{1}} eclipselink.join-fetch=a.contacts.hobbies - 异常

我也试过使用JPA治疗功能i。即... navigated to a non-existent relationship,但这不会带来爱好,只能吸引人而非公司。

有没有人知道如何使用join fetch或eclipselink查询提示来完成这样的查询优化?

修改

为了回答克里斯的评论。 业余爱好中的select a from Account a join fetch treat(a.contact as Person) p join fetch p.hobbies注释对查询没有任何影响。没有它的查询没有区别。

以下是每个查询使用@BatchFetch注释生成的sqls

@BatchFetch

select a from Account a

1 SELECT id, contact_id FROM account 2 SELECT DISTINCT DTYPE FROM contact WHERE (ID = ?) 3 SELECT t0.ID, t0.DTYPE, t1.ID, t1.FOUNDED FROM contact t0, company t1 WHERE ((t0.ID = ?) AND ((t1.ID = t0.ID) AND t0.DTYPE = ?)) 4 SELECT DISTINCT DTYPE FROM contact WHERE (ID = ?) 5 SELECT t0.ID, t0.DTYPE, t1.ID, t1.NAME FROM contact t0, person t1 WHERE ((t0.ID = ?) AND ((t1.ID = t0.ID) AND (t0.DTYPE = ?))) 6 SELECT ID, OUTDOOR, PERSON_ID FROM hobby WHERE (PERSON_ID = ?) ... (repetition of lines 2 to 6)

select a from Account a join fetch a.contacts

0 个答案:

没有答案