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

Issue 238: Clarify mixing input parameter types for queries #341

Merged
merged 1 commit into from
Dec 9, 2021

Conversation

dazey3
Copy link
Contributor

@dazey3 dazey3 commented Dec 7, 2021

fixes #238

Signed-off-by: Will Dazey dazeydev.3@gmail.com

Signed-off-by: Will Dazey <dazeydev.3@gmail.com>
@dazey3
Copy link
Contributor Author

dazey3 commented Dec 7, 2021

I decided to go with changing "undefined" with "invalid" because the EntityManager API for createQuery(String qlString) states the following:

    @throws IllegalArgumentException if the query string is found to be invalid

I tested current behavior with OpenJPA, EclipseLink, and Hibernate as well. Both OpenJPA/EclipseLink providers currently throw appropriate IllegalArgumentException from EntityManager.createQuery(...) calls when the query is parsed mixing input parameter types.
Hibernate though doesn't fail and creates a query. This seems to violate the current Section 4.6.4: Input Parameters of the specification, but they aren't the reference implementation.

OpenJPA:

org.apache.openjpa.persistence.ArgumentException: Query "SELECT a FROM Story a WHERE a.name = :name AND a.id = ?1" Contains both named and positional parameters this is not allowed by the JPA specification. Detected parameters "[name, 1]".
	at org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.validateParameters(JPQLExpressionBuilder.java:2462)
...
	at org.apache.openjpa.persistence.EntityManagerImpl.createQuery(EntityManagerImpl.java:102)

NOTE: org.apache.openjpa.persistence.ArgumentException extends java.lang.IllegalArgumentException

EclipseLink:

java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: 
Exception Description: Syntax error parsing [SELECT a FROM Story a WHERE a.name = :name AND a.id = ?1]. 
[37, 42] Named and positional input parameters must not be mixed in a single query.
[54, 56] Named and positional input parameters must not be mixed in a single query.
	at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1620)

@beikov
Copy link

beikov commented Dec 8, 2021

I don't know how you tested this with Hibernate, but there are compatibility configurations that you must set in order for Hibernate to behave fully spec compliant. I'm pretty sure that if you set those setting, Hibernate will throw an exception as well.

@dazey3
Copy link
Contributor Author

dazey3 commented Dec 8, 2021

@beikov

There are compatibility configurations that you must set in order for Hibernate to behave fully spec compliant. I'm pretty sure that if you set those setting, Hibernate will throw an exception as well.

Hibernate is knowingly not spec compliant by default and you must instead set properties to be JPA spec compliant? I have not heard of this before. Mind sharing a link to the documentation for this?

@dazey3
Copy link
Contributor Author

dazey3 commented Dec 8, 2021

Regardless, if all providers fail, that adds even more weight that the specification should in fact describe mixing of input parameter types as "invalid" rather than just "undefined"

@beikov
Copy link

beikov commented Dec 8, 2021

Here are the various JPA compliance related configurations: https://docs.jboss.org/hibernate/orm/5.6/userguide/html_single/Hibernate_User_Guide.html#configurations-jpa-compliance

@dazey3
Copy link
Contributor Author

dazey3 commented Dec 9, 2021

@beikov

Testing with the Hibernate "" property from the documentation you linked did result in Hibernate throwing an exception:

java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Cannot mix positional and named parameters: SELECT a FROM model.Story a WHERE a.name = :name AND a.id = ?1 [SELECT a FROM model.Story a WHERE a.name = :name AND a.id = ?1]
	at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:138)

NOTE: Hibernate 5.2.18 did not change behavior, but 5.5.6 did. This issue must have been fixed at some point.

I understand this Hibernate discussion is a side note to this JPA Spec issue, but does Hibernate have the ability to process the property <property name="hibernate.jpa.compliance" value="true"/>? It would be convenient to simple say "I want to run with a JPA compliant provider requiring only 1 provider specific property".

@sebersole
Copy link
Contributor

@beikov

There are compatibility configurations that you must set in order for Hibernate to behave fully spec compliant. I'm pretty sure that if you set those setting, Hibernate will throw an exception as well.

Hibernate is knowingly not spec compliant by default and you must instead set properties to be JPA spec compliant? I have not heard of this before. Mind sharing a link to the documentation for this?

Is it really that odd that a provider does things better by default? I mean really?

@sebersole
Copy link
Contributor

sebersole commented Dec 9, 2021

I understand this Hibernate discussion is a side note to this JPA Spec issue, but does Hibernate have the ability to process the property <property name="hibernate.jpa.compliance" value="true"/>? It would be convenient to simple say "I want to run with a JPA compliant provider requiring only 1 provider specific property".

Yes, I just added this for 6.0 - https://github.com/hibernate/hibernate-orm/blob/main/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java#L2035-L2051

@dazey3
Copy link
Contributor Author

dazey3 commented Dec 9, 2021

@beikov

There are compatibility configurations that you must set in order for Hibernate to behave fully spec compliant. I'm pretty sure that if you set those setting, Hibernate will throw an exception as well.

Hibernate is knowingly not spec compliant by default and you must instead set properties to be JPA spec compliant? I have not heard of this before. Mind sharing a link to the documentation for this?

Is it really that odd that a provider does things better by default? I mean really?

"Better" is a matter of opinion. Also, all I said was that I had not heard of this before for Hibernate and asked for a link to the documentation. Did I say something wrong?

@sebersole
Copy link
Contributor

"Better" is a matter of opinion.

Fair enough. I'll let usage numbers tell the tale of what the general opinion is.

Hibernate existed for many years before JPA. In fact, most parts of JPA were influenced by Hibernate. So some of this is "legacy". Well one - hibernate.jpa.compliance.list is strictly a backwards compatibility setting. Hibernate not only predates JPA, it also predates annotations, and initially there was only XML mapping. Sometimes that XML bias still comes through. This List handling is one.

But honestly, for the most part Hibernate simply does do things better by default in these particular areas.

@sebersole
Copy link
Contributor

sebersole commented Dec 9, 2021

And we really should not be having this conversation about Hibernate on the spec GitHub group. Feel free to ping us on Zulip, etc as outlined at https://hibernate.org/community/ if you want to continue discussing

@lukasj
Copy link
Contributor

lukasj commented Dec 9, 2021

Is it really that odd that a provider does things better by default? I mean really?

could we leave this sort of comments away from this place and stick to topic, please? IMHO it doesn't matter what the provider does "by default" as long as it satisfies the TCK rules

Thank you.

Copy link
Contributor

@lukasj lukasj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change looks good to me

@sebersole
Copy link
Contributor

could we leave this sort of comments away from this place and stick to topic, please? IMHO it doesn't matter what the provider does "by default" as long as it satisfies the TCK rules

I was answering a direct question asked here. But,

And we really should not be having this conversation about Hibernate on the spec GitHub group...

@dazey3
Copy link
Contributor Author

dazey3 commented Dec 9, 2021

@lukasj
Thank you for the review

@dazey3 dazey3 merged commit a59022f into jakartaee:master Dec 9, 2021
@dazey3 dazey3 deleted the 238_master branch December 9, 2021 15:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

JPA Spec contradiction on mixing input parameter types
4 participants