JPA-2.0 简单选择位置问题

发布于 2024-09-16 09:56:20 字数 881 浏览 5 评论 0原文

我遇到了有关 JPA-2.0 关系查询的问题。如何选择具有至少一个Eventtype = B的任何Dataset

@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?
...

对此有任何想法。我尝试创建子查询和联接,但不知何故我做错了,并且总是得到所有数据集作为结果。

I am stuck with a problem concerning JPA-2.0 queries with relationships. How would it be possible to select any Dataset with at least one Event with 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
}

My starting point is

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?
...

Any ideas on this. I tried to create a subqueries as well as a join, but I somehow did it wrong and always got all datasets as result.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

迷爱 2024-09-23 09:56:20

尝试

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

编辑:正如 Pascal 指出的那样,您似乎正在使用 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();

唷,那真是辛苦了。我现在要回到 Linq。

Try

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

EDIT: As Pascal pointed out it looks like you are using the Criteria API. Not as familiar with this, but I'll have a stab.

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();

Phew that was hard work. I'm going back to Linq now.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文