我正在尝试使用spring-data-jpa选择一个包含所有提供的参数值的实体。
我的实体如下:
FactoryDevice
我的方法如下
@Entity
@Table(name = "books", schema = Constants.BENCHMARKS)
@NamedEntityGraph(name = "BookEntity.all", attributeNodes = @NamedAttributeNode("aliases"))
public class BookEntity
{
@Id
private String isbn = UUID.randomUUID().toString();
@Column(name = "title")
private String title;
@Column(name = "description")
private String description;
@CollectionTable(schema = Constants.BENCHMARKS, name = "book_tags", joinColumns = @JoinColumn(name = "book_isbn"))
@ElementCollection(fetch = FetchType.EAGER)
private List<String> aliases;
}
运行该方法时,出现以下异常
@EntityGraph(value = "BookEntity.all", type = EntityGraphType.LOAD)
@Query("SELECT x FROM BookEntity x " +
"WHERE x IN (" +
" SELECT y FROM BookEntity y" +
" INNER JOIN y.aliases yt" +
" WHERE yt IN (" +
" :aliases" +
" )" +
" GROUP BY y" +
" HAVING COUNT( DISTINCT yt) = COUNT(" +
" :aliases)" +
" )")
Iterable<BookEntity> findAllByAliasesContainsAll(@Param("aliases") Collection<String> aliases);
我已经看过How do I reuse a parameter witha Spring-Data-JPA Repository?,这是我获得原始语法的地方。我也看过许多其他的文章,但是它们实际上都没有尝试在其查询中重用参数。当然,它们中的任何一个都不能作为示例的基础(我在这里甚至没有混合实体)。
我想用一个实际的问题总结一下,导致我的查询语法正确解析的问题是什么?
响应:尝试第二次添加参数
第二次传递参数并没有改变结果,它仍然抱怨冒号,使我认为这实际上不是重用问题,而是计数问题
响应:尝试使用SIZE而不是COUNT
将计数更改为SIZE会导致新的错误
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: : near line 1, column 139 [select b from org.cubrc.example.hibernate.books.BookEntity b where :aliases member of b.aliases group by b.isbn having count(b) >= count( :aliases )]
解决方法:
我尝试手动使用尺寸,如下所示
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Unexpected expression ? found for collection function size [SELECT x FROM org.cubrc.example.hibernate.books.BookEntity x WHERE x IN ( SELECT y FROM org.cubrc.example.hibernate.books.BookEntity y INNER JOIN y.aliases yt WHERE yt IN ( :aliases ) GROUP BY y HAVING COUNT( DISTINCT yt) = SIZE( :aliases) )]
这样做是可行的,所以我现在就使用它。但是,当我真的只需要一个参数时,最好避免让用户传入两个参数。
答案 0 :(得分:0)
似乎实际的问题是您试图将参数用作count()
函数的参数,这是不期望的。据我了解,想法是用参数集合的大小检查结果。为此,您可以尝试使用“ SIZE()” JPA函数或将别名的长度作为另一个参数传递。