也许我在使用JPA / EclipseLink(Postgresql 9.2)和InheritanceStrategy.JOINED时忽略了一些重要的事情,但这对我来说没有意义。
我有一个像这样的层次结构:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@ClassExtractor(ProjectClassExtractor.class)
public class Project extends AbstractEntity {
@ManyToOne
Company c;
}
和另一个实体
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class MoreSpecificProject extends Project {
}
我现在尝试查询分配给给定一组公司的公司的所有项目(包括MoreSpecificProjects)。
标准守则如下:
public List<Project> getProjectsWithCompany(Company company) {
CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
CriteriaQuery<Project> query = cb.createQuery(Project.class);
Root<Project> projectRoot = query.from(Project.class);
query.select(projectRoot);
query.where(cb.equal(projectRoot.get(Project_.c), company));
query.distinct(true);
return getEntityManager().createQuery(query).getResultList();
}
我在数据库中有一个Project,而MoreSpecificProject表是空的。该项目已正确设置公司。
现在eclipseLink(Glassfish4.0)生成以下SQL(备注:我删除了无关列的长列表):
SELECT DISTINCT t0.*, t1.*
FROM PROJECT t0, MORESPECIFICPROJECT t1
WHERE ((t0.C_ID= 664) AND (t0.ID=t1.ID))
显然,这不会返回结果,因为MoreSpecificProject中没有匹配的条目。 但是它应该返回Project表中的一个Project。
如何让Eclipselink生成正确的SQL(例如在MoreSpecificProject上使用LEFT JOIN)?
请帮我解决这个问题。
提前致谢。
编辑: 我发现如果我用
限制结果 TypedQuery<Project> tQuery = entityManager.
createQuery(query);
tQuery.setFirstResult(0).setMaxResults(5);
return tQuery.getResultList();
正在创建正确的SQL:
SELECT t0.*, t1.* FROM PROJECT t0 LEFT OUTER JOIN MORESPECIFICPROJECT t1 ON (t1.ID = t0.ID) WHERE (t0.C_ID = 664) LIMIT 5 OFFSET 0
并且resultin列表包含正确的项目。 为什么限制结果集,从标准API导致正确的查询? 这可能是个错误吗?
答案 0 :(得分:1)
根据http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Entities/Inheritance#Outer_Joining_Subclasses,默认是查询所有子类并将结果连接到内存中。因此,您应该看到要返回的每个类的查询,而不仅仅是MoreSpecificProject类。