Skip to content

Query Parser Regression Bug in 3.3.5 #3661

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
MartinHaeusler opened this issue Nov 6, 2024 · 2 comments
Closed

Query Parser Regression Bug in 3.3.5 #3661

MartinHaeusler opened this issue Nov 6, 2024 · 2 comments
Labels
status: duplicate A duplicate of another issue

Comments

@MartinHaeusler
Copy link

Spring Data 3.3.5 has a regression bug in its HQL query parser.

The following query:

    @Modifying
    @Query(
        value = """
        DELETE
        FROM
            MyEntity AS me
        WHERE
            me.deleted IS NOT NULL
        """
    )
    public void deleteAllSoftDeleted();

... creates an error during application startup:

org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract void com.example.demo.repository.MyEntityRepository.deleteAllSoftDeleted(); Reason: Cannot invoke "org.antlr.v4.runtime.ParserRuleContext.getParent()" because "ctx" is null
	at app//org.springframework.data.repository.query.QueryCreationException.create(QueryCreationException.java:101)
	at app//org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lookupQuery(QueryExecutorMethodInterceptor.java:119)
	at app//org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.mapMethodsToQuery(QueryExecutorMethodInterceptor.java:103)
	at app//org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lambda$new$0(QueryExecutorMethodInterceptor.java:92)
	at [email protected]/java.util.Optional.map(Optional.java:260)
	at app//org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.<init>(QueryExecutorMethodInterceptor.java:92)
	at app//org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:357)
	at app//org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:290)
	at app//org.springframework.data.util.Lazy.getNullable(Lazy.java:135)
	at app//org.springframework.data.util.Lazy.get(Lazy.java:113)
	at app//org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:296)
	at app//org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:132)
	at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1853)
	at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1802)
	... 52 more
Caused by: java.lang.NullPointerException: Cannot invoke "org.antlr.v4.runtime.ParserRuleContext.getParent()" because "ctx" is null
	at org.springframework.data.jpa.repository.query.HqlQueryTransformer.isSubquery(HqlQueryTransformer.java:105)
	at org.springframework.data.jpa.repository.query.HqlQueryTransformer.isSubquery(HqlQueryTransformer.java:105)
	at org.springframework.data.jpa.repository.query.HqlQueryTransformer.isSubquery(HqlQueryTransformer.java:105)
	at org.springframework.data.jpa.repository.query.HqlQueryTransformer.isSubquery(HqlQueryTransformer.java:105)
	at org.springframework.data.jpa.repository.query.HqlQueryTransformer.isSubquery(HqlQueryTransformer.java:105)
	at org.springframework.data.jpa.repository.query.HqlQueryTransformer.isSubquery(HqlQueryTransformer.java:105)
	at org.springframework.data.jpa.repository.query.HqlQueryTransformer.visitVariable(HqlQueryTransformer.java:362)
	at org.springframework.data.jpa.repository.query.HqlQueryRenderer.visitVariable(HqlQueryRenderer.java:1)
	at org.springframework.data.jpa.repository.query.HqlParser$VariableContext.accept(HqlParser.java:10200)
	at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:18)
	at org.springframework.data.jpa.repository.query.HqlQueryRenderer.visitTargetEntity(HqlQueryRenderer.java:481)
	at org.springframework.data.jpa.repository.query.HqlQueryRenderer.visitTargetEntity(HqlQueryRenderer.java:1)
	at org.springframework.data.jpa.repository.query.HqlParser$TargetEntityContext.accept(HqlParser.java:2018)
	at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:18)
	at org.springframework.data.jpa.repository.query.HqlQueryRenderer.visitDeleteStatement(HqlQueryRenderer.java:526)
	at org.springframework.data.jpa.repository.query.HqlQueryRenderer.visitDeleteStatement(HqlQueryRenderer.java:1)
	at org.springframework.data.jpa.repository.query.HqlParser$DeleteStatementContext.accept(HqlParser.java:2198)
	at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:18)
	at org.springframework.data.jpa.repository.query.HqlQueryRenderer.visitQl_statement(HqlQueryRenderer.java:46)
	at org.springframework.data.jpa.repository.query.HqlQueryRenderer.visitQl_statement(HqlQueryRenderer.java:1)
	at org.springframework.data.jpa.repository.query.HqlParser$Ql_statementContext.accept(HqlParser.java:303)
	at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:18)
	at org.springframework.data.jpa.repository.query.HqlQueryRenderer.visitStart(HqlQueryRenderer.java:35)
	at org.springframework.data.jpa.repository.query.HqlQueryRenderer.visitStart(HqlQueryRenderer.java:1)
	at org.springframework.data.jpa.repository.query.HqlParser$StartContext.accept(HqlParser.java:247)
	at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:18)
	at org.springframework.data.jpa.repository.query.HqlQueryParser.doFindAlias(HqlQueryParser.java:101)
	at org.springframework.data.jpa.repository.query.JpaQueryParserSupport.findAlias(JpaQueryParserSupport.java:96)
	at org.springframework.data.jpa.repository.query.JpaQueryEnhancer.detectAlias(JpaQueryEnhancer.java:124)
	at org.springframework.data.jpa.repository.query.StringQuery.<init>(StringQuery.java:90)
	at org.springframework.data.jpa.repository.query.DeclaredQuery.of(DeclaredQuery.java:40)
	at org.springframework.data.jpa.repository.query.JpaQueryMethod.assertParameterNamesInAnnotatedQuery(JpaQueryMethod.java:168)
	at org.springframework.data.jpa.repository.query.JpaQueryMethod.<init>(JpaQueryMethod.java:149)
	at org.springframework.data.jpa.repository.query.DefaultJpaQueryMethodFactory.build(DefaultJpaQueryMethodFactory.java:44)
	at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:94)
	at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lookupQuery(QueryExecutorMethodInterceptor.java:115)
	... 64 more

I had a quick look at the code. At first glance to me it seems that HqlQueryTransformer.isSubquery is either missing a case in its instanceof cascade, or should not have been called in the first place.

The same code works fine in 3.3.4.

A minimal reproducer is available here: https://github.com/MartinHaeusler/springDataParseErrorReproducer

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Nov 6, 2024
@MartinHaeusler
Copy link
Author

Potentially a duplicate of this (not sure though, the query is different): #3649

@christophstrobl
Copy link
Member

thanks for reporting - update and delete ones are affected. Fix via #3650 will be in next service release.

@christophstrobl christophstrobl added status: duplicate A duplicate of another issue and removed status: waiting-for-triage An issue we've not yet triaged labels Nov 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: duplicate A duplicate of another issue
Projects
None yet
Development

No branches or pull requests

3 participants