Validation failed for query for method public abstract java.util.List

50,072

Solution 1

I was getting this error as I was using table name in @Query(), but you have to use class name in @Query():

Incorrect:

@Transactional
@Modifying
@Query("from SHIPPING_DOC e where e.fulfillmentId in ?1")
List<ShippingDocumentsJsonEntity> deleteByFulfillmentIdIn(List<String> fulfillmentIds);

Correct:

@Transactional
@Modifying
@Query("from ShippingDocumentsJsonEntity e where e.fulfillmentId in ?1")
List<ShippingDocumentsJsonEntity> deleteByFulfillmentIdIn(List<String> fulfillmentIds);

Solution 2

Since priceAlertsTapas is Set you can't use dot-path.

@Query("select us.priceAlertsTapas.tapa from User us")

First you need to join it

@Query("select pat.tapa from User us join us.priceAlertsTapas pat")

Solution 3

You have no reason to use a left (outer) join if your are only interested in the rightmost entity - although I'm not sure that this is the reason for which the validation of your query fails.

I would try this:

@Query("select tapa fom PriceAlertsTapas pat join pat.tapa tapa where pat.priceAlert = ?1")
List<Tapa> tapasByUserPriceAlert (PriceAlert pa);

If a given "tapa" can have multiple association to a "price alert" (eg one per user) then you will find it multiple times in your return List. The solution is either to change the return type to Set<Tapa> or to use "select distinct...." in your query.

If, on the other hand, your PriceAlertsTapas is a simple many-to-many association, it might be better to use the @ManyToMany JPA annotation, eventually with @JoinTable. See, for example, here.

Share:
50,072
en Peris
Author by

en Peris

No em toqueu gaire els cullons que els tinc plens i grossos i els buidaré a la vostra cara

Updated on July 09, 2022

Comments

  • en Peris
    en Peris almost 2 years

    I have a basic SpringBoot app. using Spring Initializer, JPA, embedded Tomcat, Thymeleaf template engine, and package as an executable JAR file. The version of SpringBoot is 2.0.1.RELEASE. I've created a class repository that extends from CrudRepository with this method

    @Query("select us.priceAlertsTapas.tapa from User us left join us.priceAlertsTapas  pat left join pat.tapa tapa where pat.priceAlert = ?1")
        List<Tapa> tapasByUserPriceAlert (PriceAlert pa);
    

    But when I init the project I got this error:

    Validation failed for query for method public abstract java.util.List
    
    
    
        at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:93)
        at org.springframework.data.jpa.repository.query.SimpleJpaQuery.<init>(SimpleJpaQuery.java:63)
        at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromMethodWithQueryString(JpaQueryFactory.java:76)
        at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromQueryAnnotation(JpaQueryFactory.java:56)
        at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:139)
        at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:206)
        at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:79)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lookupQuery(RepositoryFactorySupport.java:553)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$mapMethodsToQuery$1(RepositoryFactorySupport.java:546)
        at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
        at java.util.Iterator.forEachRemaining(Iterator.java:116)
        at java.util.Collections$UnmodifiableCollection$1.forEachRemaining(Collections.java:1049)
        at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
        at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
        at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.mapMethodsToQuery(RepositoryFactorySupport.java:548)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$new$0(RepositoryFactorySupport.java:538)
        at java.util.Optional.map(Optional.java:215)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:538)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:317)
        at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$3(RepositoryFactoryBeanSupport.java:287)
        at org.springframework.data.util.Lazy.getNullable(Lazy.java:141)
        at org.springframework.data.util.Lazy.get(Lazy.java:63)
        at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:290)
        at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:102)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1761)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1698)
        ... 47 common frames omitted
    Caused by: java.lang.NullPointerException: null
        at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromJoinElement(HqlSqlWalker.java:424)
        at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.joinElement(HqlSqlBaseWalker.java:3931)
        at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3717)
        at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3595)
        at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:720)
        at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:576)
        at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:313)
        at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:261)
        at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:266)
        at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:189)
        at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:141)
        at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115)
        at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
        at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153)
        at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:553)
        at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:662)
        at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:23)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:350)
        at com.sun.proxy.$Proxy105.createQuery(Unknown Source)
        at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:87)
        ... 76 common frames omitted
    

    With the solution proposed I got the same error

    With this query I have also the same error (?!?)

     @Query("select us.priceAlertsTapas.tapa from User us ")
    

    Here the User object:

    @Entity
    @Table(name="t_user")
    public class User implements Serializable, UserDetails {
    
    ...
    
    @ManyToMany
        @JoinTable(
            name="t_user_price_alert_tapa",
            joinColumns=@JoinColumn(name="user_id", referencedColumnName="id"),
            inverseJoinColumns=@JoinColumn(name="price_alert_tapa_id", referencedColumnName="id"))
        private Set<PriceAlertTapa> priceAlertsTapas = new HashSet<>();
    }
    

    and

    @Entity
    @Table(name="t_price_alert")
    public class PriceAlert implements Serializable {
    
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
    
    
        public PriceAlert(int id) {
            super();
            this.id = id;
        }
    
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Integer id; 
    
        private String name;
    
    ...
    
        }
    

    and

    @Entity
    @Table(name="t_price_alert_tapa")
    public class PriceAlertTapa  implements Serializable {
    
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
    
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private long id;
    
    
        public PriceAlertTapa(PriceAlert priceAlert, Tapa tapa) {
            super();
            this.tapa = tapa;
            this.priceAlert = priceAlert;
        }
    
        private Tapa tapa;
    
        private PriceAlert priceAlert;
    ..
    }
    
  • en Peris
    en Peris about 6 years
    I use the @ManyToMany relationship in the User entity with PriceAlertsTapas
  • Vitalii Muzalevskyi
    Vitalii Muzalevskyi about 6 years
    no, try to use pat.tapa instead of us.priceAlertsTapas.tapa
  • Andriy Slobodyanyk
    Andriy Slobodyanyk about 6 years
    @enPeris..ElgothdelaCiutat If you don't specify the order and tapas are different ones it might be Set both in the relationship and the result
  • Andriy Slobodyanyk
    Andriy Slobodyanyk about 6 years
    @enPeris..ElgothdelaCiutat If my answer helped you could I accept the bounty, please?
  • en Peris
    en Peris about 6 years
    sure, sorry :-)
  • YazidEF
    YazidEF over 3 years
    Works well. Thank you.