Skip to content
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

Quarkus Hibernate 6.x throws SemanticException: Could not interpret path expression 'property_state' but column exists #42921

Closed
dhoffer opened this issue Aug 30, 2024 · 12 comments
Labels
area/hibernate-orm Hibernate ORM kind/bug Something isn't working triage/invalid This doesn't seem right

Comments

@dhoffer
Copy link

dhoffer commented Aug 30, 2024

Describe the bug

After upgrading to Quarkus 3.14.1 (from 2.16.12.Final) I get a Hibernate error where it can't interpet a column name. I'm using PostgreSQL & Panache.

2024-08-30 20:43:42,811 qsd1 /nix/store/gm0dgz25420fimf0knw4srkvzhpqrnai-openjdk-17.0.7+7/lib/openjdk/bin/java[116398] ERROR [io.qua.run.Application] (main) Failed to start application: java.lang.RuntimeException: Failed to start quarkus
at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)
at io.quarkus.runtime.Application.start(Application.java:101)
at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:119)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:71)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:44)
at com.qsd.jmb.preapprovalapp.app.Main.main(Main.java:20)
Caused by: org.hibernate.query.SemanticException: Could not interpret path expression 'property_state'
at org.hibernate.query.hql.internal.BasicDotIdentifierConsumer$BaseLocalSequencePart.resolvePathPart(BasicDotIdentifierConsumer.java:240)
at org.hibernate.query.hql.internal.BasicDotIdentifierConsumer.consumeIdentifier(BasicDotIdentifierConsumer.java:92)
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitSimplePath(SemanticQueryBuilder.java:5454)
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitGeneralPathFragment(SemanticQueryBuilder.java:5297)
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitGeneralPathExpression(SemanticQueryBuilder.java:1891)
at org.hibernate.grammars.hql.HqlParser$GeneralPathExpressionContext.accept(HqlParser.java:8268)
at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visitChildren(AbstractParseTreeVisitor.java:46)
at org.hibernate.grammars.hql.HqlParserBaseVisitor.visitBarePrimaryExpression(HqlParserBaseVisitor.java:812)
at org.hibernate.grammars.hql.HqlParser$BarePrimaryExpressionContext.accept(HqlParser.java:7726)
at org.hibernate.query.hql.internal.SemanticQueryBuilder.createComparisonPredicate(SemanticQueryBuilder.java:2548)
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitComparisonPredicate(SemanticQueryBuilder.java:2509)
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitComparisonPredicate(SemanticQueryBuilder.java:277)
at org.hibernate.grammars.hql.HqlParser$ComparisonPredicateContext.accept(HqlParser.java:6611)
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitAndPredicate(SemanticQueryBuilder.java:2378)
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitAndPredicate(SemanticQueryBuilder.java:277)
at org.hibernate.grammars.hql.HqlParser$AndPredicateContext.accept(HqlParser.java:6461)
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitWhereClause(SemanticQueryBuilder.java:2361)
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitWhereClause(SemanticQueryBuilder.java:277)
at org.hibernate.grammars.hql.HqlParser$WhereClauseContext.accept(HqlParser.java:6302)
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitQuery(SemanticQueryBuilder.java:1259)
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitQuerySpecExpression(SemanticQueryBuilder.java:1040)
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitQuerySpecExpression(SemanticQueryBuilder.java:277)
at org.hibernate.grammars.hql.HqlParser$QuerySpecExpressionContext.accept(HqlParser.java:2134)
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitSimpleQueryGroup(SemanticQueryBuilder.java:1025)
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitSimpleQueryGroup(SemanticQueryBuilder.java:277)
at org.hibernate.grammars.hql.HqlParser$SimpleQueryGroupContext.accept(HqlParser.java:2005)
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitSelectStatement(SemanticQueryBuilder.java:492)
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitStatement(SemanticQueryBuilder.java:451)
at org.hibernate.query.hql.internal.SemanticQueryBuilder.buildSemanticModel(SemanticQueryBuilder.java:324)
at org.hibernate.query.hql.internal.StandardHqlTranslator.translate(StandardHqlTranslator.java:71)
at org.hibernate.query.internal.QueryInterpretationCacheStandardImpl.createHqlInterpretation(QueryInterpretationCacheStandardImpl.java:145)
at org.hibernate.query.internal.QueryInterpretationCacheStandardImpl.resolveHqlInterpretation(QueryInterpretationCacheStandardImpl.java:132)
at org.hibernate.query.spi.QueryEngine.interpretHql(QueryEngine.java:54)
at org.hibernate.internal.AbstractSharedSessionContract.interpretHql(AbstractSharedSessionContract.java:831)
at org.hibernate.internal.AbstractSharedSessionContract.interpretAndCreateSelectionQuery(AbstractSharedSessionContract.java:809)
at org.hibernate.internal.AbstractSharedSessionContract.createSelectionQuery(AbstractSharedSessionContract.java:856)
at io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession.createSelectionQuery(TransactionScopedSession.java:1277)
at org.hibernate.engine.spi.SessionLazyDelegator.createSelectionQuery(SessionLazyDelegator.java:749)
at org.hibernate.Session_ilTHnt5-Rtrc-lcyZ-6tBgAWKh4_Synthetic_ClientProxy.createSelectionQuery(Unknown Source)
at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.createBaseQuery(CommonPanacheQueryImpl.java:387)
at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.createQuery(CommonPanacheQueryImpl.java:348)
at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.list(CommonPanacheQueryImpl.java:301)
at io.quarkus.hibernate.orm.panache.runtime.PanacheQueryImpl.list(PanacheQueryImpl.java:150)
at io.quarkus.hibernate.orm.panache.runtime.JpaOperations.list(JpaOperations.java:24)
at io.quarkus.hibernate.orm.panache.runtime.JpaOperations.list(JpaOperations.java:10)
at io.quarkus.hibernate.orm.panache.common.runtime.AbstractJpaOperations.list(AbstractJpaOperations.java:249)
at com.qsd.jmb.db.preapprovalapp.repository.TitleInsuranceRepository.list(TitleInsuranceRepository.java)
at com.qsd.jmb.db.preapprovalapp.repository.TitleInsuranceRepository_Subclass.list$$superforward(Unknown Source)
at com.qsd.jmb.db.preapprovalapp.repository.TitleInsuranceRepository_Subclass$$function$$22.apply(Unknown Source)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:73)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:62)
at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.invokeInCallerTx(TransactionalInterceptorBase.java:335)
at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired.doIntercept(TransactionalInterceptorRequired.java:40)
at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.intercept(TransactionalInterceptorBase.java:61)
at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired.intercept(TransactionalInterceptorRequired.java:32)
at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired_Bean.intercept(Unknown Source)
at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:30)
at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:27)

Here is the Enity column:

@column(name="property_state", nullable=false, length=2)
public String getPropertyState() {
return this.propertyState;
}

public void setPropertyState(String propertyState) {
    this.propertyState = propertyState;
}

The Panache query is:

return list(String.format("%s = ?1 and %s = ?2",
PROPERTY_STATE, TRANSACTION_TYPE), state, transaction);

Expected behavior

It should be able to find the column just like it used to in version 2.16.12.Final.

Actual behavior

It throws a org.hibernate.query.SemanticException: Could not interpret path expression 'property_state'

How to Reproduce?

No response

Output of uname -a or ver

No response

Output of java -version

java 17.0.9 2023-10-17 LTS

Quarkus version or git rev

3.14.1

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)

Additional information

No response

@dhoffer dhoffer added the kind/bug Something isn't working label Aug 30, 2024
@quarkus-bot quarkus-bot bot added the area/hibernate-orm Hibernate ORM label Aug 30, 2024
@quarkus-bot
Copy link

quarkus-bot bot commented Aug 30, 2024

/cc @gsmet (hibernate-orm), @yrodiere (hibernate-orm)

@dhoffer
Copy link
Author

dhoffer commented Aug 30, 2024

I went and tried all the latest service pack versions from 3.14.1 to 3.9.5 and they all have this bug. I can't go back prior to 3.9.5 w/o also reverting to the prior quarkus-rest & quarkus-rest-jackson artifact names.

Also, the DB table & column name that it fails on appears to be somewhat random, they don't all fail but eventually one does and the app crashes.

So is this a known issue that Quarkus 3.x with Hibernate 6.x with Panache and Postgres is broken? Is there any workaround? This is a huge blocker.

@gsmet
Copy link
Member

gsmet commented Sep 2, 2024

Did you try propertyState? I have a vague recollection that you need to use the property name and not the column name now. I think it was documented in one of the migration guides.

@yrodiere
Copy link
Member

yrodiere commented Sep 3, 2024

Did you try propertyState? I have a vague recollection that you need to use the property name and not the column name now. I think it was documented in one of the migration guides.

+1. property_state is a column name, used in SQL, but Panache works with HQL, which expects JPA attribute names, so in this case propertyState.

If property_state was accepted before, it was most likely a bug, and indeed I remember something about that being fixed in an earlier version, to avoid ambiguity in some models/queries.

If someone finds in which version this was fixed, we should definitely mention this change prominently in the migration guide. I think the behavior was changed in Quarkus 3.0 as part of the HQL parsing overhaul in Hibernate ORM 6.0/6.1/6.2, but we'd have to test this -- I can't find the relevant Jira issue.

But first, please confirm whether propertyState works correctly?

@dhoffer
Copy link
Author

dhoffer commented Sep 3, 2024 via email

@yrodiere
Copy link
Member

yrodiere commented Sep 3, 2024

No, I have never tried the JPA name, only the DB column name as that was what was required in Quarkus 2.x and I didn't know it changed

To be clear I'd expect Quarkus 2.x didn't require the column name, but just accepted it (incorrectly). I'd expect the JPA attribute name to work in Quarkus 2.x.

@yrodiere yrodiere added the triage/needs-feedback We are waiting for feedback. label Sep 3, 2024
@dhoffer
Copy link
Author

dhoffer commented Sep 3, 2024 via email

@yrodiere
Copy link
Member

yrodiere commented Sep 3, 2024

So if 3.x JPA names are required, this works for joined table names too?

When you use Panache, you use HQL, Hibernate Query Language, which is an extension of JPQL, JPA Query Language. Both of these query languages are working at the entity level. So there is no table or column, everything you mention there should be entity names and attribute (~ Java field) names.

e.g. Quarkus will know that a JPA field name of table2 (In the table1 entity) which is joined by column name table2_id (varchar) will just work?

I'm having trouble picturing what you mean (a precise query would help), but in general yes, joins in JPQL work. The syntax is a bit different though, as -- as always -- you give entity/attribute names, not column names. See here for more information: https://docs.jboss.org/hibernate/orm/6.6/querylanguage/html_single/Hibernate_Query_Language.html#join

@dhoffer
Copy link
Author

dhoffer commented Sep 8, 2024

I have confirmed that Hibernate 6.x does work propertly if I use the JPA names and not the column names. I think this should be stated in the Panache documentation as its a big change that is not documented anywhere as far as I know.

@yrodiere
Copy link
Member

yrodiere commented Sep 10, 2024

Thank you for confirming.

To be fair, nowhere was it documented that you could use column names instead of attribute names -- IIRC, it was considered a bug.

But yes, it should appear in the migration guide. Do you happen to know in what version of Quarkus exactly this change occurred?

@dhoffer
Copy link
Author

dhoffer commented Sep 10, 2024

No not sure of the version but I found it during upgrading from 2.16.12 to a fairly recent 3.x version. Ideally I'd like it to support both but just JPA names works.

@yrodiere
Copy link
Member

I just ran a few tests, and it's been this way since Hibernate ORM 6.0. Only 5.x and below accept column names in HQL queries -- and even then, only in some cases: in a "select" clause you'd get an error about "unknown type" since Hibernate ORM 5.x wouldn't completely understand what the column name refers to.

I'll update the migration guides, thanks for reporting.

I'll close this since it's not a bug, but feel free to comment, or open another issue if you have other problems.

@yrodiere yrodiere closed this as not planned Won't fix, can't repro, duplicate, stale Sep 11, 2024
@yrodiere yrodiere added triage/invalid This doesn't seem right and removed triage/needs-feedback We are waiting for feedback. labels Sep 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/hibernate-orm Hibernate ORM kind/bug Something isn't working triage/invalid This doesn't seem right
Projects
None yet
Development

No branches or pull requests

3 participants