Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将“IN”子句休眠为ALL而不是ANY_Java_Hibernate_Orm_Hql - Fatal编程技术网

Java 将“IN”子句休眠为ALL而不是ANY

Java 将“IN”子句休眠为ALL而不是ANY,java,hibernate,orm,hql,Java,Hibernate,Orm,Hql,首先,我想为我不熟悉Hibernate而道歉。我只是最近才进入这一领域,我还远远不是一个专家 我有三个表:合同、产品和它们之间的链接表,用于定义多对多关系 我试图编写一个HQL查询来返回包含一系列产品的所有合同。不幸的是,IN语法的工作方式类似于Any而不是All。因此,如果我想要所有包含ProductA、ProductB和ProductC的合同,IN关键字将返回包含这些产品中任何一个的合同,而不是包含所有这些产品的合同 我应该如何构造HQL查询 你为什么期望IN表现得像个AND?据我所知,IN

首先,我想为我不熟悉Hibernate而道歉。我只是最近才进入这一领域,我还远远不是一个专家

我有三个表:合同、产品和它们之间的链接表,用于定义多对多关系

我试图编写一个HQL查询来返回包含一系列产品的所有合同。不幸的是,IN语法的工作方式类似于Any而不是All。因此,如果我想要所有包含ProductA、ProductB和ProductC的合同,IN关键字将返回包含这些产品中任何一个的合同,而不是包含所有这些产品的合同

我应该如何构造HQL查询

你为什么期望IN表现得像个AND?据我所知,IN是一种OR,而不是一种AND。因此,可能不是您所要寻找的。看看Hibernate的,尤其是:

采用集合值路径表达式的HQL函数:size、minelement、maxelement、minindex、maxindex,以及可以使用中的某些、全部、exists、any进行量化的特殊元素和索引函数。 [……]

当传递集合元素和索引函数的元素或索引集或子查询的结果时,将支持中的SQL函数any、some、all、exists,如下所示:

[……]

您可以使用:

或者,您可以使用以下方法避免列出组中的所有属性:

显然,3必须替换为您在子句中提供的产品名称的实际数量。

在我讨论过的hibernate查询中,请看示例4

下面是一个快照,将文章替换为合同,将标签替换为产品:

String[] tags = {"Java", "Hibernate"};
String hql = "select a from Article a " +
                "join a.tags t " +
                "where t.name in (:tags) " +
                "and a.id in (" +
                    "select a2.id " +
                    "from Article a2 " +
                    "join a2.tags t2 " +
                    "group by a2 " +
                    "having count(t2)=:tag_count) " +
                "group by a " +
                "having count(t)=:tag_count";
Query query = session.createQuery(hql);
query.setParameterList("tags", tags);
query.setInteger("tag_count", tags.length);
List<Article> articles = query.list();

对于in子句中超过2000个id,请使用子查询,如[from group where groupid inselect id from elemtable]

否则,请使用条件来克服stackoverflow错误

例如:

 Session session = getHibernateTemplate().getSessionFactory().openSession();

 Criteria criteriaEaquals = session.createCriteria(Elements.class);
 criteriaEaquals.add(Restrictions.in("elementId", elemIds));
 criteriaEaquals.setProjection(Projections.distinct(Projections.property("type")));
 List list = criteriaEaquals.list();

 session.close();
 System.out.println("typelistis--->"+list.toString());

 return list;

那么我要寻找什么呢?你能详细说明一下上面的查询如何解决OP的问题吗?索引不会返回实体集合元素的属性值AFAIK;即使它这样做了,也不能保证所有有问题的产品都在收集中。有人知道是否有办法使用ALL操作符吗?执行如下操作:从t1中选择s1,其中s1>ALL从t2中选择s1;它不会退回有3种关联产品的合同吗?其中一种是A、B或C?不会。然而,它将退回与产品A、A和B相关的合同;如果这种情况下关系允许重复,那么解决这个问题的唯一方法就是生成带有3个显式连接的嵌套查询。您的选择所有产品中至少有A、B、C的合同,因此它将选择ABCD和XYZABC,而我的选择正好是ABC。这个问题不清楚需要哪一个,所以这两个都适用于不同的任务。我想我误解了你之前的评论。是的,我的查询将返回所有包含A、B、C产品的合同,无论它们是否还有其他与之关联的产品。这就是我认为OP want.groupby a是非法的:你可以编写group by a.id,这是一样的,但是当前的一个也可以,只是在MySQL下测试了一下。MySQL并不是因为严格处理group by子句而出名的。在Postgres或Oracle上尝试同样的技巧:-group by a.id同样是非法的,因为SQL标准不允许在带有聚合函数的select子句中包含非聚合列,除非它们也在group by子句中。在您的情况下,文章名称将不可用。请注意,我并不是说你的问题不好;只是需要显式列出所有列。
from Contract c where c.id in (
select c.id
  from Contract c join c.products p
 where p.name in ('A', 'B', 'C')
 group by c.id
 having count(*) = 3
)
String[] tags = {"Java", "Hibernate"};
String hql = "select a from Article a " +
                "join a.tags t " +
                "where t.name in (:tags) " +
                "and a.id in (" +
                    "select a2.id " +
                    "from Article a2 " +
                    "join a2.tags t2 " +
                    "group by a2 " +
                    "having count(t2)=:tag_count) " +
                "group by a " +
                "having count(t)=:tag_count";
Query query = session.createQuery(hql);
query.setParameterList("tags", tags);
query.setInteger("tag_count", tags.length);
List<Article> articles = query.list();
 Session session = getHibernateTemplate().getSessionFactory().openSession();

 Criteria criteriaEaquals = session.createCriteria(Elements.class);
 criteriaEaquals.add(Restrictions.in("elementId", elemIds));
 criteriaEaquals.setProjection(Projections.distinct(Projections.property("type")));
 List list = criteriaEaquals.list();

 session.close();
 System.out.println("typelistis--->"+list.toString());

 return list;