2014-02-02 2 views
0

У меня есть простой критерий апите запрос с (внутренним) присоединитьсяКритерии 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

У меня также есть суперкласс от продукта

@Entity 
@Audit 
public class SuperClass {} 

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

Но это не должно быть никаких проблем?

ответ

2

Соединение является действительным, но SQL, используемый для выполнения соединения, записывается в неявной записи соединения. Соединение будет иметь такую ​​же производительность, что и явная запись соединения (обозначение с использованием JOIN и ON). Выполняется «реальное» соединение, однако оно просто не указано в явной записи соединения (например, ANSI SQL 92), которую вы ожидаете.

+0

Я не уверен, вы говорите, что синтаксис «join on» такой же, как и во всем «где»? Существует большая разница в производительности. Все вокруг, где сравнивает все со всем, и это замедляет работу. Я могу сказать это с ответом на базу данных, где медленнее, с «join on» быстро – user3263327

+0

@ user3263327 Что вы не знаете? –

+0

все в порядке, поэтому вы правы, http://en.wikipedia.org/wiki/Join_(SQL)#Inner_join Мне нужно прочитать немного больше о объединениях. Я думаю, что мне нужно изменить тип соединения (нет более внутреннего соединения) – user3263327

0

Вы выбираете из Root с Product.class, но вам нужно выбрать соединение. И я думаю, что результат присоединения должен быть сопоставлен некоторому классу, содержащему оба объекта Product и Category. Если вы хотите получить только продукт от присоединения, вы можете написать примерно следующее:

CriteriaBuilder 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(); 
Смежные вопросы