Criteria API忽略JOIN

时间:2014-02-02 17:25:13

标签: java sql jpa eclipselink inner-join

我有一个简单的条件api查询与(内部)连接

public void find(Category category) {
 CriteriaBuilder b = getQueryBuilder();
 CriteriaQuery<Product> q = createQuery();
 Root<Product> root = q.from(Product.class);
 Join<Product, Category> myCategory= root.join("category");        
 q.where(b.equal(myCategory, category));
 entityManager.createQuery(q).getResultList();
}

查询有效,但如果我在persistence.xml中启用sql日志记录,我可以看到查询是

SELECT * FROM product, category WHERE ...

且没有

SELECT * FROM product join category on category.id = product.category ...

知道这是什么原因吗? where语句非常慢,所以真正的连接会更好。

我正在使用eclipselink 2.5.1,Java EE7和postgres

我还有一个Product

的超类
@Entity
@Audit
public class SuperClass {}

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Product extends SuperClass {}

但这应该没问题?

2 个答案:

答案 0 :(得分:2)

实际上正在执行连接,但用于执行连接的SQL是以隐式连接表示法编写的。连接将具有与显式连接表示法相同的性能(使用JOIN和ON表示法)。正在执行“真正的”连接,但它不是您期望的显式连接表示法(即ANSI SQL 92)。

答案 1 :(得分:0)

您正在Product.class选择Product,但您需要从加入中进行选择。 我认为你加入的结果必须映射到某个类,包含实体CategoryCriteriaBuilder b = getQueryBuilder(); CriteriaQuery<Product> q1 = createQuery(); CriteriaQuery<Product> q2 = createQuery(); Root<Product> root = q1.from(Product.class); q2.select(root.as(Product.class)).from(root.join("category")) entityManager.createQuery(q2).getResultList(); 。如果您只想从加入中获得产品,可以写下这样的内容:

// If this is your actual data ...
var numberOfHours = 10;
var showSunAt = 3;

// ... and this is your desired "resolution" for the path ...
var resolution = 16;

// ... map your data to work with this resolution.
var mapped = showSunAt / numberOfHours * resolution;

// Define the "space" to leave between segments.
var spaceBetweenSegments = 1;

// Then, dynamically set the start/end points for each segment.
var firstSegmentEndsAt = mapped - (spaceBetweenSegmenets / 2);
var secondSegmenetStartsAt = mapped + (spaceBetweenSegmenets / 2);