简体   繁体   中英

Case insensitive query using Spring @Query annotation

I have a Spring JPA repository where I have a custom query:

@Query("select aif from AssetInFolder aif "
        + "where (aif.asset.name like %:name% "
        + "or aif.folder.name like %:name% "
        + "or aif.asset.assetCode like :code%) "
        + "and aif.folder.assetVersion.id = :version")
public List<AssetInFolder> searchForAsset(@Param("name") String name, @Param("code") String code,  @Param("version") int version);

I would like to make sure that the the first part of the query (before the 'and') is case in sensitive. I have tried changing it to:

@Query("select aif from AssetInFolder aif "
            + "where (UPPER(aif.asset.name) like UPPER(%:name%) "
            + "or UPPER(aif.folder.name) like UPPER(%:name%) "
            + "or UPPER(aif.asset.assetCode) like UPPER(:code%)) "
            + "and aif.folder.assetVersion.id = :version")

But I get a NullPointer when Spring attempt to initialise the application context:

Caused by: java.lang.NullPointerException: null
    at org.hibernate.hql.internal.antlr.HqlBaseParser.identPrimary(HqlBaseParser.java:4285) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.primaryExpression(HqlBaseParser.java:980) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.atom(HqlBaseParser.java:3609) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.unaryExpression(HqlBaseParser.java:3387) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.multiplyExpression(HqlBaseParser.java:3259) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.additiveExpression(HqlBaseParser.java:2964) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.concatenation(HqlBaseParser.java:597) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.relationalExpression(HqlBaseParser.java:2898) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.equalityExpression(HqlBaseParser.java:2591) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.negatedExpression(HqlBaseParser.java:2555) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.logicalAndExpression(HqlBaseParser.java:2471) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.logicalOrExpression(HqlBaseParser.java:2436) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.expression(HqlBaseParser.java:2146) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.expressionOrVector(HqlBaseParser.java:4632) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.primaryExpression(HqlBaseParser.java:942) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.atom(HqlBaseParser.java:3609) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.unaryExpression(HqlBaseParser.java:3387) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.multiplyExpression(HqlBaseParser.java:3259) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.additiveExpression(HqlBaseParser.java:2964) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.concatenation(HqlBaseParser.java:597) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.relationalExpression(HqlBaseParser.java:2730) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.equalityExpression(HqlBaseParser.java:2591) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.negatedExpression(HqlBaseParser.java:2555) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.logicalAndExpression(HqlBaseParser.java:2471) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.logicalOrExpression(HqlBaseParser.java:2436) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.expression(HqlBaseParser.java:2146) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.logicalExpression(HqlBaseParser.java:1922) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.whereClause(HqlBaseParser.java:481) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.queryRule(HqlBaseParser.java:737) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.selectStatement(HqlBaseParser.java:323) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.antlr.HqlBaseParser.statement(HqlBaseParser.java:186) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:279) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:187) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:142) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:76) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:150) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:298) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:236) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1825) ~[hibernate-core-5.0.2.Final.jar:5.0.2.Final]
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:291) ~[hibernate-entitymanager-5.0.2.Final.jar:5.0.2.Final]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_05]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_05]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_05]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_05]
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:344) ~[spring-orm-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at com.sun.proxy.$Proxy48.createQuery(Unknown Source) ~[na:na]
    at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:86) ~[spring-data-jpa-1.9.0.RELEASE.jar:na]
    ... 80 common frames omitted

However, more curiously, if I write remove a few of the UPPER calls I can get it to start:

@Query("select aif from AssetInFolder aif "
            + "where (UPPER(aif.asset.name) like UPPER(%:name%) "
            + "or aif.folder.name like %:name% "
            + "or aif.asset.assetCode like :code%) "
            + "and aif.folder.assetVersion.id = :version")

Anyone got any ideas? I'm on Spring 4.2.2 and Spring Data JPA 1.9.0

I ended up only calling UPPER on the column names and relying on the caller to pass in the parameters in upper case. So my query ended up as:

@Query("select aif from AssetInFolder aif "
            + "where (UPPER(aif.asset.name) like %:name% "
            + "or UPPER(aif.folder.name) like %:name% "
            + "or UPPER(aif.asset.assetCode) like :code%) "
            + "and aif.folder.assetVersion.id = :version")

This fixed the issue, however I'm still unsure as to why the original query didn't work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM