micronaut-projects / micronaut-data

Ahead of Time Data Repositories
Apache License 2.0
467 stars 198 forks source link

Micronaut Data JDBC Criteria API multiselect fields not working #3091

Closed ralmeida7 closed 2 months ago

ralmeida7 commented 2 months ago

Expected Behavior

Retrieve only the fields requested in the CriteriaQuery multiselect.

    public static <T> QuerySpecification<T> fieldSelector() {
        return (root, query, cb) -> {
            query.multiselect(root.get("title").alias("title"), root.get("author").alias("author"));
            return query.getRestriction();
        };
    }

This works fine with Micronaut Data JPA

Actual Behaviour

Error reading object for name [id] from result set: Column "id" not found [42122-232]
io.micronaut.data.exceptions.DataAccessException: Error reading object for name [id] from result set: Column "id" not found [42122-232]
    at io.micronaut.data.jdbc.mapper.ColumnNameResultSetReader.exceptionForColumn(ColumnNameResultSetReader.java:263)
    at io.micronaut.data.jdbc.mapper.ColumnNameResultSetReader.readInt(ColumnNameResultSetReader.java:169)
    at io.micronaut.data.jdbc.mapper.ColumnNameResultSetReader.readInt(ColumnNameResultSetReader.java:43)
    at io.micronaut.data.runtime.mapper.ResultReader.readDynamic(ResultReader.java:107)
    at io.micronaut.data.jdbc.mapper.ColumnNameResultSetReader.readDynamic(ColumnNameResultSetReader.java:69)
    at io.micronaut.data.jdbc.mapper.ColumnNameResultSetReader.readDynamic(ColumnNameResultSetReader.java:43)
    at io.micronaut.data.runtime.mapper.sql.SqlResultEntityTypeMapper.readProperty(SqlResultEntityTypeMapper.java:702)
    at io.micronaut.data.runtime.mapper.sql.SqlResultEntityTypeMapper.readEntityId(SqlResultEntityTypeMapper.java:728)
    at io.micronaut.data.runtime.mapper.sql.SqlResultEntityTypeMapper.readEntity(SqlResultEntityTypeMapper.java:474)
    at io.micronaut.data.runtime.mapper.sql.SqlResultEntityTypeMapper$4.processRow(SqlResultEntityTypeMapper.java:370)
    at io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations.findAll(DefaultJdbcRepositoryOperations.java:397)
    at io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations.findAll(DefaultJdbcRepositoryOperations.java:386)
    at io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations.findAll(DefaultJdbcRepositoryOperations.java:378)
    at io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations.lambda$findAll$5(DefaultJdbcRepositoryOperations.java:530)
    at io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations.lambda$executeRead$23(DefaultJdbcRepositoryOperations.java:770)
    at io.micronaut.data.connection.support.AbstractConnectionOperations.withExistingConnectionInternal(AbstractConnectionOperations.java:128)
    at io.micronaut.data.connection.support.AbstractConnectionOperations.execute(AbstractConnectionOperations.java:92)
    at io.micronaut.data.connection.ConnectionOperations.executeRead(ConnectionOperations.java:71)
    at io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations.executeRead(DefaultJdbcRepositoryOperations.java:767)
    at io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations.findAll(DefaultJdbcRepositoryOperations.java:530)
    at io.micronaut.data.runtime.intercept.criteria.AbstractSpecificationInterceptor.findAll(AbstractSpecificationInterceptor.java:156)
    at io.micronaut.data.runtime.intercept.criteria.FindAllSpecificationInterceptor.intercept(FindAllSpecificationInterceptor.java:46)
    at io.micronaut.data.runtime.intercept.DataIntroductionAdvice.intercept(DataIntroductionAdvice.java:83)
    at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:143)
    at com.example.data.repository.BookRepository$Intercepted.findAll(Unknown Source)
    at com.example.BookRepositoryTest.testFieldSelector(BookRepositoryTest.java:45)
    at java.base/java.lang.reflect.Method.invoke(Method.java:580)
    at io.micronaut.test.extensions.junit5.MicronautJunit5Extension$2.proceed(MicronautJunit5Extension.java:142)
    at io.micronaut.test.extensions.AbstractMicronautExtension.interceptEach(AbstractMicronautExtension.java:162)
    at io.micronaut.test.extensions.AbstractMicronautExtension$3.proceed(AbstractMicronautExtension.java:174)
    at io.micronaut.test.context.TestMethodInterceptor.interceptTest(TestMethodInterceptor.java:46)
    at io.micronaut.transaction.test.DefaultTestTransactionExecutionListener.lambda$interceptTest$0(DefaultTestTransactionExecutionListener.java:93)
    at io.micronaut.transaction.support.AbstractPropagatedStatusTransactionOperations.lambda$execute$2(AbstractPropagatedStatusTransactionOperations.java:68)
    at io.micronaut.transaction.TransactionCallback.apply(TransactionCallback.java:37)
    at io.micronaut.transaction.support.AbstractTransactionOperations.executeTransactional(AbstractTransactionOperations.java:333)
    at io.micronaut.transaction.support.AbstractTransactionOperations.executeWithNewTransaction(AbstractTransactionOperations.java:318)
    at io.micronaut.transaction.support.AbstractTransactionOperations.executeNew(AbstractTransactionOperations.java:235)
    at io.micronaut.transaction.support.AbstractTransactionOperations.doExecute(AbstractTransactionOperations.java:137)
    at io.micronaut.transaction.support.AbstractTransactionOperations.lambda$doExecute$0(AbstractTransactionOperations.java:122)
    at io.micronaut.data.connection.support.AbstractConnectionOperations.executeWithNewConnection(AbstractConnectionOperations.java:143)
    at io.micronaut.data.connection.support.AbstractConnectionOperations.execute(AbstractConnectionOperations.java:90)
    at io.micronaut.transaction.support.AbstractTransactionOperations.doExecute(AbstractTransactionOperations.java:120)
    at io.micronaut.transaction.support.AbstractPropagatedStatusTransactionOperations.execute(AbstractPropagatedStatusTransactionOperations.java:65)
    at io.micronaut.transaction.test.DefaultTestTransactionExecutionListener.interceptTest(DefaultTestTransactionExecutionListener.java:91)
    at io.micronaut.test.extensions.AbstractMicronautExtension.interceptEach(AbstractMicronautExtension.java:166)
    at io.micronaut.test.extensions.AbstractMicronautExtension.interceptTest(AbstractMicronautExtension.java:119)
    at io.micronaut.test.extensions.junit5.MicronautJunit5Extension.interceptTestMethod(MicronautJunit5Extension.java:129)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "id" not found [42122-232]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:514)
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:489)
    at org.h2.message.DbException.get(DbException.java:223)
    at org.h2.message.DbException.get(DbException.java:199)
    at org.h2.jdbc.JdbcResultSet.getColumnIndex(JdbcResultSet.java:3518)
    at org.h2.jdbc.JdbcResultSet.getInt(JdbcResultSet.java:337)
    at com.zaxxer.hikari.pool.HikariProxyResultSet.getInt(HikariProxyResultSet.java)
    at io.micronaut.data.jdbc.mapper.ColumnNameResultSetReader.readInt(ColumnNameResultSetReader.java:167)
    ... 47 more

Column "id" not found [42122-232]
org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "id" not found [42122-232]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:514)
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:489)
    at org.h2.message.DbException.get(DbException.java:223)
    at org.h2.message.DbException.get(DbException.java:199)
    at org.h2.jdbc.JdbcResultSet.getColumnIndex(JdbcResultSet.java:3518)
    at org.h2.jdbc.JdbcResultSet.getInt(JdbcResultSet.java:337)
    at com.zaxxer.hikari.pool.HikariProxyResultSet.getInt(HikariProxyResultSet.java)
    at io.micronaut.data.jdbc.mapper.ColumnNameResultSetReader.readInt(ColumnNameResultSetReader.java:167)
    at io.micronaut.data.jdbc.mapper.ColumnNameResultSetReader.readInt(ColumnNameResultSetReader.java:43)
    at io.micronaut.data.runtime.mapper.ResultReader.readDynamic(ResultReader.java:107)
    at io.micronaut.data.jdbc.mapper.ColumnNameResultSetReader.readDynamic(ColumnNameResultSetReader.java:69)
    at io.micronaut.data.jdbc.mapper.ColumnNameResultSetReader.readDynamic(ColumnNameResultSetReader.java:43)
    at io.micronaut.data.runtime.mapper.sql.SqlResultEntityTypeMapper.readProperty(SqlResultEntityTypeMapper.java:702)
    at io.micronaut.data.runtime.mapper.sql.SqlResultEntityTypeMapper.readEntityId(SqlResultEntityTypeMapper.java:728)
    at io.micronaut.data.runtime.mapper.sql.SqlResultEntityTypeMapper.readEntity(SqlResultEntityTypeMapper.java:474)
    at io.micronaut.data.runtime.mapper.sql.SqlResultEntityTypeMapper$4.processRow(SqlResultEntityTypeMapper.java:370)
    at io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations.findAll(DefaultJdbcRepositoryOperations.java:397)
    at io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations.findAll(DefaultJdbcRepositoryOperations.java:386)
    at io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations.findAll(DefaultJdbcRepositoryOperations.java:378)
    at io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations.lambda$findAll$5(DefaultJdbcRepositoryOperations.java:530)
    at io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations.lambda$executeRead$23(DefaultJdbcRepositoryOperations.java:770)
    at io.micronaut.data.connection.support.AbstractConnectionOperations.withExistingConnectionInternal(AbstractConnectionOperations.java:128)
    at io.micronaut.data.connection.support.AbstractConnectionOperations.execute(AbstractConnectionOperations.java:92)
    at io.micronaut.data.connection.ConnectionOperations.executeRead(ConnectionOperations.java:71)
    at io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations.executeRead(DefaultJdbcRepositoryOperations.java:767)
    at io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations.findAll(DefaultJdbcRepositoryOperations.java:530)
    at io.micronaut.data.runtime.intercept.criteria.AbstractSpecificationInterceptor.findAll(AbstractSpecificationInterceptor.java:156)
    at io.micronaut.data.runtime.intercept.criteria.FindAllSpecificationInterceptor.intercept(FindAllSpecificationInterceptor.java:46)
    at io.micronaut.data.runtime.intercept.DataIntroductionAdvice.intercept(DataIntroductionAdvice.java:83)
    at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:143)
    at com.example.data.repository.BookRepository$Intercepted.findAll(Unknown Source)
    at com.example.BookRepositoryTest.testFieldSelector(BookRepositoryTest.java:45)
    at java.base/java.lang.reflect.Method.invoke(Method.java:580)
    at io.micronaut.test.extensions.junit5.MicronautJunit5Extension$2.proceed(MicronautJunit5Extension.java:142)
    at io.micronaut.test.extensions.AbstractMicronautExtension.interceptEach(AbstractMicronautExtension.java:162)
    at io.micronaut.test.extensions.AbstractMicronautExtension$3.proceed(AbstractMicronautExtension.java:174)
    at io.micronaut.test.context.TestMethodInterceptor.interceptTest(TestMethodInterceptor.java:46)
    at io.micronaut.transaction.test.DefaultTestTransactionExecutionListener.lambda$interceptTest$0(DefaultTestTransactionExecutionListener.java:93)
    at io.micronaut.transaction.support.AbstractPropagatedStatusTransactionOperations.lambda$execute$2(AbstractPropagatedStatusTransactionOperations.java:68)
    at io.micronaut.transaction.TransactionCallback.apply(TransactionCallback.java:37)
    at io.micronaut.transaction.support.AbstractTransactionOperations.executeTransactional(AbstractTransactionOperations.java:333)
    at io.micronaut.transaction.support.AbstractTransactionOperations.executeWithNewTransaction(AbstractTransactionOperations.java:318)
    at io.micronaut.transaction.support.AbstractTransactionOperations.executeNew(AbstractTransactionOperations.java:235)
    at io.micronaut.transaction.support.AbstractTransactionOperations.doExecute(AbstractTransactionOperations.java:137)
    at io.micronaut.transaction.support.AbstractTransactionOperations.lambda$doExecute$0(AbstractTransactionOperations.java:122)
    at io.micronaut.data.connection.support.AbstractConnectionOperations.executeWithNewConnection(AbstractConnectionOperations.java:143)
    at io.micronaut.data.connection.support.AbstractConnectionOperations.execute(AbstractConnectionOperations.java:90)
    at io.micronaut.transaction.support.AbstractTransactionOperations.doExecute(AbstractTransactionOperations.java:120)
    at io.micronaut.transaction.support.AbstractPropagatedStatusTransactionOperations.execute(AbstractPropagatedStatusTransactionOperations.java:65)
    at io.micronaut.transaction.test.DefaultTestTransactionExecutionListener.interceptTest(DefaultTestTransactionExecutionListener.java:91)
    at io.micronaut.test.extensions.AbstractMicronautExtension.interceptEach(AbstractMicronautExtension.java:166)
    at io.micronaut.test.extensions.AbstractMicronautExtension.interceptTest(AbstractMicronautExtension.java:119)
    at io.micronaut.test.extensions.junit5.MicronautJunit5Extension.interceptTestMethod(MicronautJunit5Extension.java:129)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)

Steps To Reproduce

  1. Download the example application
  2. Use the "jdbc" branch git checkout jdbc
  3. Run the test ./gradlew test --tests "com.example.BookRepositoryTest.testFieldSelector"

The same implementation with Micronaut Data JPA can be found in the branch "jpa" git checkout jpa

Environment Information

Example Application

https://github.com/ralmeida7/criteria-builder-bugs

Version

4.6.0