【问题标题】:JPA, Spring Webservice Select with NOT IN and INJPA,带有 NOT IN 和 IN 的 Spring Webservice 选择
【发布时间】:2017-02-11 20:52:53
【问题描述】:

我正在尝试执行此选择:

SELECT c FROM Incident c 
WHERE c.incidentID IN 
  ( 
   SELECT DISTINCT d.incidentID FROM TagIncident d WHERE tagName IN ( d.tagName=?1 ) 
   AND d.incidentID NOT IN 
   (SELECT a.incidentID FROM TagIncident a WHERE tagName IN (a.tagName=?2))    
  )

在我使用 JPA/Spring 的系统中出现错误:

"HTTP Status 500 - Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: An exception occurred while creating a query in EntityManager:"

我在语法上做错了什么吗? 我在我的数据库(HANA)上对其进行了测试,它工作正常。

感谢您的帮助!

编辑更多错误日志

我最近的尝试是:

SELECT c FROM Incident c WHERE c.incidentID IN 
( SELECT DISTINCT d.incidentID FROM TagIncident d WHERE d.tagName IN 
( d.tagName=?1 ) AND d.incidentID NOT IN 
( SELECT a.incidentID FROM TagIncident a WHERE a.tagName IN (a.tagName=?2) ))

编辑

Exception Description: Syntax error parsing [SELECT c FROM Incident c WHERE c.incidentID IN ( SELECT DISTINCT d.incidentID FROM TagIncident d WHERE d.tagName IN ( d.tagName=?1 ) AND d.incidentID NOT IN ( SELECT a.incidentID FROM TagIncident a WHERE a.tagName IN (a.tagName=?2) ))].  [117, 131] 
The expression at index {0} is not a valid expression. [215, 229] 
The expression at index {0} is not a valid expression.; nested exception is java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager:  Exception Description: Syntax error parsing [SELECT c FROM Incident c WHERE c.incidentID IN ( SELECT DISTINCT d.incidentID FROM TagIncident d WHERE d.tagName IN ( d.tagName=?1 ) AND d.incidentID NOT IN ( SELECT a.incidentID FROM TagIncident a WHERE a.tagName IN (a.tagName=?2) ))].  [117, 131] 
The expression at index {0} is not a valid expression. [215, 229] 
The expression at index {0} is not a valid expression.] with root cause Local Exception Stack:  Exception [EclipseLink-0] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.JPQLException Exception Description: Syntax error parsing [SELECT c FROM Incident c WHERE c.incidentID IN ( SELECT DISTINCT d.incidentID FROM TagIncident d WHERE d.tagName IN ( d.tagName=?1 ) AND d.incidentID NOT IN ( SELECT a.incidentID FROM TagIncident a WHERE a.tagName IN (a.tagName=?2) ))].  [117, 131] 
The expression at index {0} is not a valid expression. [215, 229] 
The expression at index {0} is not a valid expression.

最新尝试:

List<String> list_add_tags = new ArrayList<String>();
List<String> list_remove_tags = new ArrayList<String>();

// creating custom sql_query
String sql_query = "SELECT c FROM Incident c WHERE c.incidentID IN ( SELECT DISTINCT(d.incidentID) FROM TagIncident d WHERE d.tagName IN ( :add_tags ) AND d.incidentID NOT IN ( SELECT a.incidentID FROM TagIncident a WHERE a.tagName IN (:remove_tags)))";

TypedQuery<Incident> query = em.createQuery(sql_query, Incident.class);

query.setParameter("add_tags", list_add_tags);
query.setParameter("remove_tags", list_remove_tags);

return query.getResultList();

还是不行。 =(

错误:

You have attempted to set a value of type class java.util.ArrayList for parameter add_tags with expected type of class java.lang.String

【问题讨论】:

  • 您使用的是哪个 JPA 提供程序? Hibernate、EclipseLink、OpenJPA 还是鲜为人知的 DataNucleaus、Toplink、ObjectDB 之一?在 Hibernate 中,您可以分配列表,如 JPA 规范第 4.6.17.5 节中的示例所示,但用他们自己的话来说,他们认为他们支持它作为奖励功能。也许您应该尝试删除参数周围的括号?官方示例确实暗示您不需要它们。
  • EclipseLink 2.6.0,从列表的 IN 中删除了括号并且它有效,这样做我能理解什么?如何检查我的 JPA 版本?

标签: java sql jpa jpql notin


【解决方案1】:

通常我只使用原生查询,因为我可以更轻松地测试它们,但试试这个:

SELECT c FROM Incident c 
WHERE c.incidentID IN 
  ( 
   SELECT DISTINCT d.incidentID FROM TagIncident d WHERE tagName IN :at 
   AND d.incidentID NOT IN 
   (SELECT a.incidentID FROM TagIncident a WHERE tagName IN :rt )    
  )

这应该适用于query.setParameter("tag", theListOfTags)。请注意,5.0.7 之前的 Hibernate 版本在括号中的参数存在语法问题。

空列表也会产生语法错误。

JPA 规范在其示例中将其显示为有效语法,因此任何 JPA 提供者都应该支持它:

SELECT e
FROM Employee e
WHERE TYPE(e) IN :empTypes

【讨论】:

  • 标签不同,标签是我在最后一个选择中不想要的东西,它是我想要在第二个选择中的一些标签。我会尝试不带括号。谢谢!
  • 它不必被称为tag。这只是使用命名参数,因此您不必使用位置和调用setParameter 两次,或者在具有大量参数的复杂查询中跟踪位置。我所做的最大更正是从那里删除 [ad].tagName=?1,因为您正在与 IN (list of values) 部分进行比较。
  • 你是对的!这是一个清单!我会试试的,谢谢!
  • 如果我只是将其添加为:SELECT c FROM Incident c WHERE c.incidentID IN ( SELECT DISTINCT d.incidentID FROM TagIncident d WHERE tagName IN ( tag1,tag2,tag3 ) AND d.incidentID NOT IN (SELECT a.incidentID FROM TagIncident a WHERE tagName IN ( tag4,tag5,tag6 )) ) 它应该工作没有?
  • 更新了我的最新尝试,请检查是否可以!
【解决方案2】:

尝试使用此JPA 查询

SELECT c FROM Incident c, TagIncident t
WHERE c.incidentID = t.incidentID
AND t.tagName = ?1
AND t.tagName != ?2

此外,如果您启用休眠日志记录,那么您将能够查看生成的查询并查看它们是否在外部 SQL 程序中工作。

logging.level.org.hibernate=DEBUG

【讨论】:

  • 这条 SQL 会导致不同的结果。 =( 不等价,我在哪里设置这个 Logging?在 Bean 中?
  • 如果你使用的是spring boot,你可以把这个属性放到application.properties文件中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-23
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 2014-07-18
相关资源
最近更新 更多