Create Page object - Spring boot - java

I'm trying to create a page object from a repository query, when return the data to a List works fine, but if i try to return the data to a Page object the query fails, getting this error
[nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [17]
2023-01-05 12:34:09.327 WARN 20644 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 42601
2023-01-05 12:34:09.331 ERROR 20644 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: syntax error at or near "WHERE"
What am i doing wrong?
LIST WAY (WORKS FINE)
Query
#Query(value ="SELECT field1 as idSolicitud, field2 as numeroRadicado, "
+ "field3 as tipoTramite, field4 as nombreTramite "
+ "FROM myTable WHERE field5 = :paramet", nativeQuery = true)
List<SolicitudesInterfaceDTO> buscarSolicitudes(#Param("paramet") Long paramet);
DTO (Interface)
public interface SolicitudesInterfaceDTO {
Long getidSolicitud();
String getnumeroRadicado();
String gettipoTramite();
String getnombreTramite();
String getestado();
}
Execute query
List<SolicitudesInterfaceDTO> solicitudesUsuario = solicitudesRepository.buscarSolicitudes(idUsuario);
PAGE WAY (Doesn't work)
Query
#Query(value ="SELECT field1 as idSolicitud, field2 as numeroRadicado, "
+ "field3 as tipoTramite, field4 as nombreTramite "
+ "FROM myTable WHERE field5 = :paramet", nativeQuery = true)
Page<SolicitudesInterfaceDTO> buscarSolicitudesPaginado(#Param("paramet") Long paramet, Pageable pageable);
Execute query
Page<SolicitudesInterfaceDTO> paginaSolicitudesUsuario = solicitudesRepository.buscarSolicitudesPaginado(idUsuario, pageable);

Related

Spring pagination exception

I'm using Spring Data JPA. Could someone say, how to fix this error: "java.sql.SQLSyntaxErrorException: Unknown column 's' in 'field list'" while executing this simple request. "s" is alias for session table. I shortened the query.
#Query(value =
"SELECT l.name as lName, c.id as clientId, c.name as clientName, s.id as sessionId, a.ss_id as ssId, " +
"u.first_name as firstName, u.last_name as lastName, s.start_date as startDate, s.end_date as endDate, " +
"sc.version as version " +
"FROM session as s " +
"join scenario sc on sc.id = s.scenario_id " +
.........
"left join client c on c.id = p.client_id " +
"WHERE s.status = 'COMPLETED' " +
"and (s.record_rejected IS NULL OR s.record_rejected = 0) " +
"and sfe.id IS NULL " +
.........
"and s.end_date between :startDate and :endDate",
nativeQuery = true)
Page<DataItem> findData(Pageable pageable, #Param("startDate") LocalDateTime startDate, #Param("endDate") LocalDateTime endDate, .......);
}
In log I see the reason of the problem, after my main request spring data executes count request for Pageable object and this request starts with: select count(s) FROM session as s, but this is wrong. You can see it below in the text:
Hibernate: SELECT l.name as lName....
Hibernate: select count(s) FROM session as s ....
2022-02-24 22:10:51.864 WARN [app,363fdd7d5edaa51c,175b13cac216908e,true] 1 --- [nio-8082-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1054, SQLState: 42S22
2022-02-24 22:10:51.864 ERROR [app,363fdd7d5edaa51c,175b13cac216908e,true] 1 --- [nio-8082-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : Unknown column 's' in 'field list'
on the second line framework tries execute select count(s), but s is an alias for the table session. And this happens only when required size is less than totalElements, if not, then request is success.
DataItem is an interface projection.
What's wrong? Why framework tries to use table alias inside count() function?
I've tried to use countQuery argument in #Query annotation, but it didn't help.

passing multiple #params to stored procedure in JPA

#Query(value = "DECLARE #StartDateTime DATETIME = DATEADD(hour,-1,GETUTCDATE()) EXEC [Fetch].[mevisio_downtimedata] " +
"#StartDateTime = :startDateTime," +
"#workCenterList = :workCenterList",nativeQuery = true)
List<DownTimeData> retriveOneHrDowntime(#Param("startDateTime") LocalDateTime startDateTime, #Param("workCenterList") List<String> workCenterList);
Getting Error:
2021-05-06 00:26:04.506 ERROR 14840 --- [ scheduling-1] o.h.engine.jdbc.spi.SqlExceptionHelper : Incorrect syntax near '('.
2021-05-06 00:26:04.513 ERROR 14840 --- [ scheduling-1] o.s.s.s.TaskUtils$LoggingErrorHandler : Unexpected error occurred in scheduled task
org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is
org.hibernate.exception.SQLGrammarException: could not extract ResultSet
You cannot execute stored procedures with a #Query
You have to define a NamedStoredProcedureQuery on an entity
#Entity
#NamedStoredProcedureQuery(name = "User.plus1", procedureName = "plus1inout", parameters = {
#StoredProcedureParameter(mode = ParameterMode.IN, name = "arg", type = Integer.class),
#StoredProcedureParameter(mode = ParameterMode.OUT, name = "res", type = Integer.class) })
public class User {}
And then you can use #Procedure to execute it
#Procedure
Integer plus1inout(#Param("arg") Integer arg);
Please read the documentation:
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.stored-procedures

My custom query with #Query and Pageable works but doesn't return results

I have this query:
public interface IProductoDao extends PagingAndSortingRepository<Producto, Long> {
#Query(value = "select * from productos p where p.nombre like %?1% and p.categoria = ?2",
countQuery = "select count(*) from productos p where p.nombre like %?1% and p.categoria = ?2",
nativeQuery = true)
public Page<Producto> findByNombreAndCategoria(String term, String cat, Pageable pageable);
}
And works succesfully, but doesn't return results and I know that there are results in my database for this query.
If I print in console the Page object, I get next:
2021-04-03 23:40:59.963 DEBUG 19724 --- [nio-8080-exec-2] org.hibernate.SQL : select * from productos p where p.nombre like ? and p.categoria = ? limit ?
Productos: Page 1 of 0 containing UNKNOWN instances
I don't understand what the query is returning. I think the query should return something like this native method(findAll(Pageable page)) of PagingAndSortingRepository interface:
#Override
#Transactional(readOnly = true)
public Page<Producto> findAll(Pageable pageable) {
return productoDao.findAll(pageable);
}
with this result:
2021-04-03 23:49:01.506 DEBUG 19724 --- [nio-8080-exec-4] org.hibernate.SQL : select producto0_.id as id1_0_, producto0_.categoria as categori2_0_, producto0_.descripcion as descripc3_0_, producto0_.imagenes as imagenes4_0_, producto0_.nombre as nombre5_0_, producto0_.precio as precio6_0_ from productos producto0_ limit ?
2021-04-03 23:49:01.509 DEBUG 19724 --- [nio-8080-exec-4] org.hibernate.SQL : select count(producto0_.id) as col_0_0_ from productos producto0_
Productos: Page 1 of 6 containing com.abril.tiendaonline.app.models.entity.Producto instances
Thanks for your time and help.

Hibernate query - username like with multiple inputs

i am tried to get user by criteria, but getting error like below
Error:
java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: '{test%,testuser6,%ana%}' near line 1, column 108 [
SELECT jpauser FROM com.abc.domain.jpa.JpaUser jpauser WHERE jpauser.username like ANY('{test%,testuser6,%ana%}'::text[]) limit 100]
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:138)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
Code:
public List<JpaUser> getUserByCriteria(String criteria)
{
Query query = getEntityManager()
.createQuery("SELECT jpauser FROM JpaUser jpauser WHERE " + criteria);
List<JpaUser> result = query.getResultList();
return result;
}
I just copied and executed the query in PostgreSQL terminal, its works fine, but through hibernate query its failed
Here is the query i have executed in PostgreSQL
SELECT * FROM users jpauser WHERE jpauser.username like ANY('{test%,testuser6,%ana%}'::text[]) limit 100
Construct the criteria like below
String value = criteria.get("username");
builder.append(TABLE_ALIAS).append("username").append(" like ")
.append(ANY).append("('{").append(value).append("}'::text[])")
Can any one help on this, how to execute hibernate query with like and multiple input ?
Use createNativeQuery for native query
Query query = getEntityManager()
.createNativeQuery("SELECT jpauser FROM JpaUser jpauser WHERE " + criteria);
In a native query, You need to use native SQL statment:
Query query = getEntityManager()
.createNativeQuery("SELECT * FROM users jpauser WHERE " + criteria)

How do I convert this JPQL to CriteriaBuilder on H2?

I'm trying to convert this query
#Query( "select l from Log l order by l.created desc, l.entry asc " )
Page<Log> findAllCustomJpql( Pageable pageable );
which generates this sql
Hibernate: select count(log0_.id) as col_0_0_ from log log0_
Hibernate: select log0_.id as id1_0_, log0_.created as created2_0_, log0_.entry as entry3_0_ from log log0_ order by log0_.created desc, log0_.entry asc limit ?
to a criteria builder query, using specifications
#RequestMapping( method = RequestMethod.GET, path = "spec")
Page<Log> getLogsBySpecification( final Pageable pageable ) {
return repository.findAll( ( root, query, cb ) -> {
query.orderBy(
cb.desc( root.get( "created" ) ),
cb.asc( root.get( "entry" ) )
);
return null;
}, pageable);
}
which is doing the following
2015-10-17 19:33:40.720 WARN 10498 --- [nio-8080-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 90016, SQLState: 90016
2015-10-17 19:33:40.721 ERROR 10498 --- [nio-8080-exec-6]
o.h.engine.jdbc.spi.SqlExceptionHelper : Column "LOG0_.ENTRY" must be in the GROUP BY list; SQL statement:
select count(log0_.id) as col_0_0_ from log log0_ order by log0_.created desc, log0_.entry asc [90016-188]
2015-10-17 19:33:40.750 ERROR 10498 --- [nio-8080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: could not extract ResultSet; nested exception is org.hibernate.exception.GenericJDBCException: could not extract ResultSet] with root cause
org.h2.jdbc.JdbcSQLException: Column "LOG0_.ENTRY" must be in the GROUP BY list; SQL statement:
select count(log0_.id) as col_0_0_ from log log0_ order by log0_.created desc, log0_.entry asc [90016-188]
I personally think the sql is valid, if ill advised, but doesn't seem to be valid for h2. How can I correct my criteria in order to generate the results I want?
This is really not the same query but I do believe it comes to the same effect.
#RequestMapping( method = RequestMethod.GET, path = "spec" )
Page<Log> getLogsBySpecification( final Pageable pageable ) {
return repository.findAll( ( root, query, cb ) -> {
query.orderBy(
cb.desc( root.get( "created" ) ),
cb.asc( root.get( "entry" ) )
);
query.groupBy( root.get( "id" ) );
return null;
}, pageable );
}
I am kind of wondering if the fact that the specification continues to apply the order by is a bug... ultimately this seems related to this bug

Categories