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

HHH-17956 Criteria multiselect ignores type of the criteria query and always returns list of Object[] #8247

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

beikov
Copy link
Contributor

@beikov beikov commented Apr 25, 2024

@beikov beikov force-pushed the HHH-17956 branch 2 times, most recently from 0f890cd to ac4cae6 Compare April 25, 2024 10:02
@gavinking
Copy link
Member

gavinking commented Apr 25, 2024

@beikov please also consider what happens with the following code:

var query = factory.getCriteriaBuilder().createQuery(String[].class);
var bookRoot = query.from(Book.class);
query.multiselect(bookRoot.get("isbn"), bookRoot.get("title"), bookRoot.get("pages"));
var resultList = entityManager.createQuery(query).getResultList();

This should throw a meaningful error stating that Book.pages is not of type String.

If we're going to allow this sort of thing, then we need to check upfront that the type of the Selections passed to multiselect() are actually assignable to the element type of the array.

This was previously not necessary because we assumed that the array type was always Object[].

@gavinking
Copy link
Member

A second item of feedback is: even the javadoc of multiselect() doesn't suggest that primitive arrays should be supported here. Quote:

If the type of the criteria query is CriteriaQuery<X[]> for some class X, an instance of type X[] will be returned for each row.

And I don't think primitive arrays make sense because it's pretty hard for us to validate that a Selection<Integer> is non-null.

Furthermore, it seems that the support for primitive arrays is leading to most of the complexity in this PR. If support for primitive arrays were removed, I guess this would be a whole lot simpler, no?

@beikov
Copy link
Contributor Author

beikov commented Apr 25, 2024

And I don't think primitive arrays make sense because it's pretty hard for us to validate that a Selection<Integer> is non-null.

If users requests an int[] as result type, they must ensure the values are non-null.

Furthermore, it seems that the support for primitive arrays is leading to most of the complexity in this PR. If support for primitive arrays were removed, I guess this would be a whole lot simpler, no?

Of course handling primitive arrays requires more code, but I think it's useful and our session with @franz1981 has shown that performance is not an issue, so we might as well do it IMO.

EDIT: ... requires more code to be efficient, ...

@gavinking
Copy link
Member

gavinking commented Apr 25, 2024

I think it's useful

It seems to me that the complexity/usefulness ratio here is really quite high.

}
else {
throw new IllegalArgumentException( "Criteria has multiple query roots" );
if ( getQueryString() == CRITERIA_HQL_STRING ) {

Check warning

Code scanning / CodeQL

Reference equality test on strings Warning

String values compared with == .
@@ -298,7 +271,12 @@

private void validateStatement(SqmStatement<R> sqmStatement, Class<R> resultType) {
if ( sqmStatement instanceof SqmSelectStatement<?> ) {
SqmUtil.verifyIsSelectStatement( sqmStatement, hql );
final SqmQueryPart<R> queryPart = ( (SqmSelectStatement<R>) sqm ).getQueryPart();
if ( hql == CRITERIA_HQL_STRING ) {

Check warning

Code scanning / CodeQL

Reference equality test on strings Warning

String values compared with == .
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants