Parameter with that position [1] did not exist error when using Spring Data native query - spring-boot

I am new to spring boot and spring data jpa. I am trying to use native queries for executing search based on search attributes received from UI.
The records that are obtained based on the searchParam should search if the searchParam is contained in any of the specified columns (as mentioned in the native query)
I have written the following code but I end up receiving the error as mentioned in the title. I have tried looking up for response in stackoverflow. But i believe i have followed the suggestions as mentioned in many of the threads.
Any help in this regard would be highly appreciated.
Code snippet below
EpicController.java
#CrossOrigin
#RequestMapping(value="/search", method = RequestMethod.GET)
public Page<Epic> searchEpicsByProjectIdAndSearchParam(#RequestParam String searchParam, #RequestParam String projectId, Pageable pageable) throws Exception {
logger.info("Inside searchEpicsByAttributes() based on searchQuery API");
Page<Epic> results = null;
try {
results = epicService.searchEpicsByProjectIdAndSearchParam(searchParam, projectId, pageable);
}
catch(Exception ex) {
ex.printStackTrace();
throw new Exception("Exception occurred :: " + ex.getStackTrace());
}
return results;
}
EpicService.java (Interface)
public interface EpicService {
Page<Epic> searchEpicsByProjectIdAndSearchParam(String searchParam, String projectId, Pageable pageable);
}
EpicServiceImpl.java
#Override
public Page<Epic> searchEpicsByProjectIdAndSearchParam(String searchParam, String projectId, Pageable pageable) {
logger.info(" Inside searchEpicsByProjectIdAndSearchParam() API in EpicServiceImpl");
return epicRepository.findBySearchParamsAndProjectId(searchParam,projectId, pageable);
}
EpicRepository.java
#Repository
public interface EpicRepository extends JpaRepository<Issue, String> {
#Query(value =
"select i.* from issue i where ("
+ "upper(i.name) like upper('%?1%'))"
+ "and upper(i.project_id) = upper('%?2%')"
+ "ORDER BY i.name DESC \n-- #pageable\n",
countQuery =
"select count(i.*) from issue i where ("
+ "upper(i.name) like upper('%?1%'))"
+ "and upper(i.project_id) = upper('%?2%')",
nativeQuery = true)
Page<Epic> findBySearchParamsAndProjectId(String name, String projectId, Pageable pageable);
}
Exception:
2019-02-08 23:25:21.199 INFO 12556 --- [nio-8080-exec-1] c.a.m.A.controller.ProjectController : Inside searchEpicsByProjectIdAndSearchParam() API in EpicServiceImpl
org.springframework.dao.InvalidDataAccessApiUsageException: Parameter with that position [1] did not exist; nested exception is java.lang.IllegalArgumentException: Parameter with that position [1] did not exist
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:384)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:246)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:525)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:209)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
Caused by: java.lang.IllegalArgumentException: Parameter with that position [1] did not exist
at org.hibernate.jpa.spi.BaseQueryImpl.findParameterRegistration(BaseQueryImpl.java:502)
at org.hibernate.jpa.spi.BaseQueryImpl.setParameter(BaseQueryImpl.java:692)
at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:181)
at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:32)
at org.springframework.data.jpa.repository.query.ParameterBinder.bind(ParameterBinder.java:141)
at org.springframework.data.jpa.repository.query.StringQueryParameterBinder.bind(StringQueryParameterBinder.java:61)
at org.springframework.data.jpa.repository.query.ParameterBinder.bind(ParameterBinder.java:101)
at org.springframework.data.jpa.repository.query.SpelExpressionStringQueryParameterBinder.bind(SpelExpressionStringQueryParameterBinder.java:76)
at org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:161)
at org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:152)
at org.springframework.data.jpa.repository.query.AbstractStringBasedJpaQuery.doCreateQuery(AbstractStringBasedJpaQuery.java:81)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:202)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$PagedExecution.doExecute(JpaQueryExecution.java:188)

Skip Single Quotations "'" around params i.e. ?1 and ?2. Working query will be like:
"select i.* from issue i where ("
+ "upper(i.name) like upper(%?1%))"
+ "and upper(i.project_id) = upper(%?2%)"
+ "ORDER BY i.name DESC \n-- #pageable\n",
countQuery =
"select count(i.*) from issue i where ("
+ "upper(i.name) like upper(%?1%))"
+ "and upper(i.project_id) = upper(%?2%)"

Related

Validation failed for query for method public abstract org.springframework.data.domain.Page

I'm trying to implement a function using Page in jpa, but I keep getting an IllegalArgumentException for my Page object I don't quite understand, I know the error says I'm trying to pass something that's not supported, but I can't find exactly why.
Here's my code:
Service
public Page<VolumeMeasurerRegistries> getVolumeMeasurerRegistries(ResquestVolumeMeasurerRegistries resquestVolumeMeasurerRegistries) throws VolumeMeasurerRegisterException {
try {
return volumeMeasurerRegisterRepository.findByEquipmentIdEquipmentAndMeasuredTimeLessThanEqualAndMeasuredTimeGreaterThanEqual(
resquestVolumeMeasurerRegistries.getIdEquipment() != null ? UUID.fromString(resquestVolumeMeasurerRegistries.getIdEquipment()) : null,
format.parse(resquestVolumeMeasurerRegistries.getFilterStartDate()),
format.parse(resquestVolumeMeasurerRegistries.getFilterEndDate()),
PageRequest.of(
resquestVolumeMeasurerRegistries.getVolumeMeasurerRegisterDisplayPage(),
resquestVolumeMeasurerRegistries.getVolumeMeasurerRegisterDisplayAmount()));
} catch (Exception getSomeException) {
//Do something
}
}
And this is my repository function:
public interface VolumeMeasurerRegistriesRepository extends JpaRepository<VolumeMeasurerRegistries, UUID> {
#Query(value = "SELECT vmr FROM VolumeMeasurerRegistries vmr "
+ "WHERE (:idEquipment is null or vmr.Equipment.idEquipment = :idEquipment) "
+ "AND (:startTime is null or vmr.measuredTime >= :startTime) "
+ "AND (:endTime is null or vmr.measuredTime <= :endTime) ", nativeQuery = false)
Page<VolumeMeasurerRegistries> findByEquipmentIdEquipmentAndMeasuredTimeLessThanEqualAndMeasuredTimeGreaterThanEqual(
#Nullable #Param("idEquipment") UUID idEquipment,
#Nullable #Param("startTime") Date startTime,
#Nullable #Param("endTime") Date endTime,
#Nullable Pageable pageable);
}
And the error I get:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'volumeMeasurerRegistriesRepository':
Invocation of init method failed; nested exception is
java.lang.IllegalArgumentException: Validation failed for query for
method public abstract org.springframework.data.domain.Page
mx.ssf.sicom.repositories.VolumeMeasurerRegistriesRepository.findByEquipmentIdEquipmentAndMeasuredTimeLessThanEqualAndMeasuredTimeGreaterThanEqual(java.util.UUID,java.util.Date,java.util.Date,org.springframework.data.domain.Pageable)!

Spring Boot QueryDSL BooleanExpression - "OR" condition depending on the value in table

I use Spring Boot and QueryDSL to combine a sql query and predicate. The problem is that I have to create a predicate to fetch data from table based on email BUT:
email can be in Freight.sender.email
OR in Freight.message.senderAddress
where Freight, Message, Sender are of course tables.
In table Freight we can have empty sender_id or message_id and depending on this I have to fetch rows by email from Freight.sender.email OR Freight.message.senderAddress (if Freight.sender is null)
Is it possible to create such a predicate that compares email from request query param with Freight.sender.email and only if Freight.sender.email doesn't exist, then my predicate shold search email in Freight.message.senderAddress
public Predicate build(Map<String, String> filters) {
return new OptionalBooleanBuilder(Expressions.asBoolean(true).isTrue())
.notNullAnd(qFreight.loadingAddress::containsIgnoreCase, filters.get(LOADING_ADDRESS))
.notNullAnd(qFreight.unloadingAddress::containsIgnoreCase, filters.get(UNLOADING_ADDRESS))
.notNullAnd(qFreight.loadingDate.eq(filters.get(LOADING_DATE) != null ? LocalDate.parse(filters.get(LOADING_DATE)) : now()), filters.get(LOADING_DATE))
.notNullAnd(qFreight.unloadingDate.eq(filters.get(UNLOADING_DATE) != null ? LocalDate.parse(filters.get(UNLOADING_DATE)) : now()), filters.get(UNLOADING_DATE))
//MY ATTEMPT - NOT WORKING:
.notNullAnd(qFreight.sender.email.eq(filters.get(SENDER_EMAIL)).or(qFreight.emailMessage.senderAddress.eq(SENDER_EMAIL)), filters.get(SENDER_EMAIL))
.build();
}
public class OptionalBooleanBuilder {
private BooleanExpression predicate;
public OptionalBooleanBuilder(BooleanExpression predicate) {
this.predicate = predicate;
}
public <T> OptionalBooleanBuilder notNullAnd(Function<T, BooleanExpression> expressionFunction, T value) {
if (nonNull(value)) {
return new OptionalBooleanBuilder(predicate.and(expressionFunction.apply(value)));
}
return this;
}
public BooleanExpression build() {
return predicate;
}
public <T>OptionalBooleanBuilder notNullAnd(BooleanExpression expression, T value) {
if(nonNull(value)){
return new OptionalBooleanBuilder(predicate.and(expression));
}
return this;
}
}
UPDATE
After suggestion from:
private Predicate addPredicate(OptionalBooleanBuilder builder, String email) {
if (nonNull(email)) {
return builder.notNullAnd(qFreight.sender.email.coalesce(qFreight.emailMessage.senderAddress.eq(email)).asBoolean(), email).build();
return builder.build();
}
I get error:
antlr.NoViableAltException: unexpected AST node: (
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2169) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2089) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.whereClause(HqlSqlBaseWalker.java:827) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:621) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:325) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:273) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:276) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:192) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
2020-12-24 00:45:35.535 ERROR 16068 --- [nio-9090-exec-8] p.a.m.s.filter.JwtAuthorizationFilter : Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST node: ( near line 3, column 52 [select freight
from pl.appwise.mtf.freight.domain.model.Freight freight
where ?1 = ?1 and freight.user.id = ?2 and coalesce(freight.sender.email, freight.emailMessage.senderAddress = ?3)
order by freight.loadingDate desc]; nested exception is java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST node: ( near line 3, column 52 [select freight
from pl.appwise.mtf.freight.domain.model.Freight freight
where ?1 = ?1 and freight.user.id = ?2 and coalesce(freight.sender.email, freight.emailMessage.senderAddress = ?3)
order by freight.loadingDate desc]
2020-12-24 00:45:37.906 INFO 16068 --- [ scheduling-1] ilAccoun
Use Freight.sender.email.coalesce(Freight.message.senderAddress). Freight.message.senderAddress will be NULL if Freight.message is NULL. For optional associations left outer joins are used by default, so this should cause no issue. Otherwise, explicitly use a left join yourself.

how do I get spring to recognize the first capital letter using postgresql

I have a question how I can do so that in spring my table is recognized with the first capital letter, is made in postgresql
#Entity
#Table(name="System_user")
public class Dashboard {
#Id
#Column(name = "username")
String username;
get..
set...
}
it generates an error and I change it as shown below
#Table("\"System_user\"")
but he still doesn't recognize me
As we discussed in the comments, the issue was in dialect.
Latest dialect for now - org.hibernate.dialect.PostgreSQL95Dialect
The issue solved this dialect:
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
Answer to your HQL-code:
I would suggest using TypedQuery as it returns not just a list, but list of your object.
Furthermore, u are using the same session to transfer data. This is bad for the program. Always do like Open session - transfer data - close session.
Try this code:
public List<Vw_dh_assay> listAssayReport(double year, String project_id, String hole_id) {
List<Vw_dh_assay> list = new ArrayList<>();
Session session;
try {
session = this.sessionFactory.openSeesion();
TypedQuery<Vw_dh_assay> query = session.createQuery("from Vw_dh_assay where year = :year AND project_id = :project_id AND hole_id = :hole_id", Player.class);
query.setParameter("year", year);
query.setParameter("project_id", project_id);
query.setParameter("hole_id", hole_id);
list = query.getResultList();
System.out.println(list);
session.clear();
session.close();
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
this is my code DAO #Antonio112009
#Override
public List<Vw_dh_assay> listAssayReport(double year, String project_id, String hole_id) {
Session session = this.sessionFactory.getCurrentSession();
String query = ("SELECT DISTINCT year,project_id,hole_id from "
+ "Vw_dh_assay where year = :year AND project_id = :project_id AND hole_id = :hole_id");
List result = session.createQuery(query).setParameter("year", year).setParameter("project_id", project_id)
.setParameter("hole_id", hole_id).list();
System.out.println(result);
return result;
}

Mutation sending null parameters on Apollo-Android

I'm trying to integrate Apollo-Android with a server mounted locally, the query to show all of the entries is working fine, but when I try to create a new entry, it sends a query without the parameters.
At first I thought it was a server-side problem, but it doesn't seems like it, since it's creating the entry but with null values.
The server it's made on Spring Boot using SPQR for the schema generation, and SpringData-JPA with Hibernate for the connection to a PostGreSQL database.
This is what the server says:
Hibernate: insert into author (first_name, last_name) values (?, ?)
2018-06-25 14:48:25.479 INFO 6670 --- [nio-8080-exec-3] s.testing.controllers.GraphQLController : {data={createAuthor={__typename=Author, firstName=null, lastName=null}}}
And this is the response I get on Android Studio:
06-25 14:48:24.974 16068-16132/com.example.nburk.apollodemo D/graphcool: Executed mutation: CreateAuthor{__typename=Author, firstName=null, lastName=null}
In Android Studio this is the builder:
private void createPost(String firstname, String lastname) {
application.apolloClient().mutate(
CreateAuthorMutation.builder()
.firstName(firstname)
.lastName(lastname)
.build())
.enqueue(createPostMutationCallback);
}
That enqueue this:
private ApolloCall.Callback<CreateAuthorMutation.Data> createPostMutationCallback = new ApolloCall.Callback<CreateAuthorMutation.Data>() {
#Override
public void onResponse(#Nonnull final Response<CreateAuthorMutation.Data> dataResponse) {
Log.d(ApolloDemoApplication.TAG, "Executed mutation: " + dataResponse.data().createAuthor().toString());
fetchPosts();
}
#Override
public void onFailure(#Nonnull ApolloException e) {
Log.d(ApolloDemoApplication.TAG, "Error:" + e.toString());
}
};
If you need it, here is my mutation:
mutation CreateAuthor($firstName: String, $lastName: String){
createAuthor(firstName: $firstName, lastName: $lastName){
firstName
lastName
}
}
This project is based on this: https://github.com/graphcool-examples/android-graphql/tree/master/quickstart-with-apollo
Uploading my schema too.
Copia de schema.txt
Thanks beforehand for your help.
The problem was from SPQR, you need to add a mapper for the variables
#PostMapping(value = "/graphql", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
#ResponseBody
public Map<String, Object> indexFromAnnotated(#RequestBody Map<String, Object> request, HttpServletRequest raw) {
ExecutionResult executionResult = graphQL.execute(ExecutionInput.newExecutionInput()
.query((String) request.get("query"))
.operationName((String) request.get("operationName"))
// -------- THIS RESOLVES THE VARIABLES--------
.variables((Map<String, Object>) request.get("variables"))
.context(raw)
.build());
LOGGER.info(executionResult.toSpecification().toString());
return executionResult.toSpecification();
}

Postgres Parameter Query for SimpleJdbcTemplate

I am trying to execute a parameter query for a Postgre database using Springs SimpleJdbcTemplate. My class that calls the query looks like this:
public class GeoCodeServiceImpl extends SimpleJdbcDaoSupport implements GeoCodeServiceInterface {
public static final String SELECT_STATEMENT = "SELECT ste_code, ste_code_type, name, fips_code " +
"FROM \"steGeo\" " +
"WHERE st_contains( the_geom, ST_GeomFromText('POINT(:lon :lat)',4269))";
public List<GeoCode> getGeoResults(Double lon, Double lat) throws DataAccessException {
MapSqlParameterSource mappedParms = new MapSqlParameterSource("lon", lon.toString());
mappedParms.addValue("lat", lat.toString());
SqlParameterSource namedParms = mappedParms;
List<GeoCode> resultList = getSimpleJdbcTemplate().query(SELECT_STATEMENT, new GeoCodeRowMapper(), namedParms);
if (resultList == null || resultList.size() == 0) {
logger.warn("No record found in GeoCode lookup.");
}
return resultList;
}
protected static final class GeoCodeRowMapper implements RowMapper<GeoCode> {
public GeoCode mapRow(ResultSet rs, int i) throws SQLException {
GeoCode gc = new GeoCode();
gc.setCode(rs.getString(1));
gc.setType(rs.getString(2));
gc.setFips(rs.getString(3));
gc.setName(rs.getString(4));
return gc;
}
}
}
I am testing the query with this class:
public class GeoCodeServiceTest {
public static void main(String[] args) {
Double lat = 40.77599;
Double lon = -83.82322;
String[] cntxs = {"project-datasource-test.xml","locationService-context.xml"};
ApplicationContext ctx = new ClassPathXmlApplicationContext(cntxs);
GeoCodeServiceImpl impl = ctx.getBean("geoCodeService", GeoCodeServiceImpl.class);
List<GeoCode> geoCodes = impl.getGeoResults(lon, lat);
System.out.println(geoCodes);
}
}
I keep getting the following error:
2011-03-07 08:16:29,227 [main] DEBUG org.springframework.jdbc.support.SQLErrorCodesFactory - SQL error codes for 'PostgreSQL' found
2011-03-07 08:16:29,227 [main] DEBUG org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator - Unable to translate SQLException with SQL state 'XX000', error code '0, will now try the fallback translator
2011-03-07 08:16:29,227 [main] DEBUG org.springframework.jdbc.support.SQLStateSQLExceptionTranslator - Extracted SQL state class 'XX' from value 'XX000'
Exception in thread "main" org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [SELECT ste_code, ste_code_type, name, fips_code FROM "steGeo" WHERE st_contains( the_geom, ST_GeomFromText('POINT(:lon :lat)',4269))]; SQL state [XX000]; error code [0]; ERROR: parse error - invalid geometry
Hint: "POINT(" <-- parse error at position 6 within geometry; nested exception is org.postgresql.util.PSQLException: ERROR: parse error - invalid geometry
Hint: "POINT(" <-- parse error at position 6 within geometry
It looks like my parameters are not populated.
I haven't used Postgre before so any help would be much appreciated.
Thanks
Parameters are not handled inside quoted strings, so I guess you need to pass the whole string as a single parameter:
public static final String SELECT_STATEMENT =
"SELECT ste_code, ste_code_type, name, fips_code " +
"FROM \"steGeo\" " +
"WHERE st_contains( the_geom, ST_GeomFromText(:pt, 4269))";
...
MapSqlParameterSource mappedParms = new MapSqlParameterSource("pt",
"POINT(" + lon.toString() + " " + lat.toString() + ")");

Resources