gpt4 book ai didi

java - 是否允许在一个 Criteria 内多次使用相同的 DetachedCriteria?

转载 作者:行者123 更新时间:2023-12-02 04:33:22 24 4
gpt4 key购买 nike

我只是想知道 Hibernate 中是否允许在一个 Criteria 中多次使用相同的 DetachedCriteria 对象。想象一下以下情况:

DetachedCriteria dCriteria = DetachedCriteria.forClass(A.class)
.add(Restrictions.eq("id", 1))
.setProjection(Projections.property("id"));

Criteria criteria = session.createCriteria(B.class)
.add(
Restrictions.or(
Restrictions.and(
Subqueries.exists(dCriteria),
Restrictions.eq("id", 1)
),
Restrictions.and(
Subqueries.notExists(dCriteria),
Restrictions.eq("id", 2)
)
)
.setProjection(Projections.property("id"));

是否在此标准允许的范围内两次使用 dCriteria?它似乎有效,但我不确定它是否可能会在更复杂的情况下导致问题(也许 DetachedCriteria 在查询生成期间保存相同的状态信息?)。我已经做了一些研究,但找不到明确的答案。

最佳答案

不,重用 DetachedCriteria 并不(总是)安全。例如:获取列表和行计数,重用 DetachedCriteria:

DetachedCriteria dc = DetachedCriteria.forClass(A.class);
Criteria c1 = dc.getExecutableCriteria(session);
c1.setProjection(Projections.rowCount());
long count = ((Number) c1.uniqueResult()).longValue();
System.out.println(count + " result(s) found:");

Criteria c2 = dc.getExecutableCriteria(session);
System.out.println(c2.list());

打印:

Hibernate: select count(*) as y0_ from A this_
4 result(s) found:
Hibernate: select count(*) as y0_ from A this_ <-- whoops
[4] <-- whoops again

不改变 DetachedCriteria 的非常简单的事情可能是安全的,但通常将生成包装在某种工厂中,并在每次您时重新生成它们需要它们。

按照官方说法,每次调用 getExecutableCriteria 时克隆 DetachedCriteria 永远不会发生。查看他们的issues ,特别是HHH-635HHH-1046其中 Brett Meyer 指出:“Criteria API 已被视为已弃用”,而 developers guide (v4.3 §12)其中指出:

Hibernate offers an older, legacy org.hibernate.Criteria API which should be considered deprecated. No feature development will target those APIs. Eventually, Hibernate-specific criteria features will be ported as extensions to the JPA javax.persistence.criteria.CriteriaQuery.

编辑:在您的示例中,您在同一查询中重复使用相同的 DetachedCriteria。因此,同样的警告也适用 - 例如,如果您将 setProjection 与其中一种用途一起使用,则第二次使用时会出现问题。例如:

DetachedCriteria dCriteria = DetachedCriteria.forClass(A.class)
.add(Restrictions.eq("id", 1))
.setProjection(Projections.property("id"));

Criteria criteria = session.createCriteria(B.class)
.add(
Restrictions.or(
Restrictions.and(
Subqueries.exists(dCriteria
.add(Restrictions.eq("text", "a1")) // <-- Note extra restriction
.setProjection(Projections.property("text"))), // <-- and projection
Restrictions.eq("idx", 1)
),
Restrictions.and(
Subqueries.notExists(dCriteria),
Restrictions.eq("idx", 2)
)
))
.setProjection(Projections.property("id"));

Object o = criteria.list();

这会产生 SQL:

select this_.idx as y0_ from B this_ 
where (
(exists
(select this_.text as y0_ from A this_ where this_.id=? and this_.text=?) and this_.idx=?)
or (not exists
(select this_.text as y0_ from A this_ where this_.id=? and this_.text=?) and this_.idx=?))

我们没有要求不存在text=?部分,但由于重用了DetachedCriteria<,我们得到了它

这会导致糟糕的情况,如果您将 .add(Restrictions.eq("text"... 应用于 dCriteria,它会在 SQL 的 existsnotists 中出现两次

关于java - 是否允许在一个 Criteria 内多次使用相同的 DetachedCriteria?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31158340/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com