JPA-2.0 Простой вопрос выбора где - PullRequest
1 голос
/ 30 августа 2010

Я застрял с проблемой, касающейся запросов JPA-2.0 со связями.Как можно было бы выбрать любой Dataset хотя бы с одним Event с помощью type = B?

@Entity
class Dataset {
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "dataset")
    public List<Event> events;
}

@Entity
class Event {
    @ManyToOne
    @JoinColumn
    public Dataset dataset;

    public Type type;
}

enum Type {
     A, B, C
}

Моя отправная точка -

CriteriaBuilder _builder = em.getCriteriaBuilder();
CriteriaQuery<Dataset> _criteria = _builder.createQuery(Dataset.class);

// select from
Root<Dataset> _root = _criteria.from(Dataset.class);
_criteria.select(_root);

// apply some filter as where-clause (visitor)
getFilter().apply(
   _root, _criteria, _builder, em.getMetamodel()
);

// how to add a clause as defined before?
...

Любые идеи на этот счет.Я пытался создать подзапросы, а также объединение, но я как-то сделал это неправильно и всегда получал все наборы данных в результате.

1 Ответ

4 голосов
/ 30 августа 2010

Попробуйте

SELECT d FROM DataSet d WHERE EXISTS 
    (SELECT e FROM Event e WHERE e.dataSet = d and e.type = :type)

РЕДАКТИРОВАТЬ: Как отметил Паскаль, похоже, что вы используете Criteria API.Не очень знаком с этим, но у меня будет удар.

CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Dataset> criteria = builder.createQuery(Dataset.class);

Root<Dataset> root = criteria.from(Dataset.class);
criteria.select(root);

// build the subquery
SubQuery<Event> subQuery = criteria.subQuery(Event.class);
Root<Event> eventRoot = subQuery.from(Event.class);
subQuery.select(eventRoot);

ParameterExpression<String> typeParameter = builder.parameter(String.class);
Predicate typePredicate = builder.equal(eventRoot.get(Event_.type), typeParameter));

// i have not tried this before but I assume this will correlate the subquery with the parent root entity
Predicate correlatePredicate = builder.equal(eventRoot.get(Event_.dataSet), root);
subQuery.where(builder.and(typePredicate, correlatePredicate);

criteria.where(builder.exists(subQuery)));

List<DataSet> dataSets = em.createQuery(criteria).getResultList();

Фу, это была тяжелая работа.Я сейчас возвращаюсь в Линк.

...