How to check UUID null value in JPQL? - java

I am using JPA/Hibernate. So I wanna to do nullCheck in JPQL, but when I do that it does not determine dataType.
JPQL Query:
#Query("select a from Attribute a where :attributeId is null OR a.id = :attributeId")
Page<Attribute> findByAttributeId(#Param("attributeId") UUUID attributeId);
EXCEPTION:
Caused by: org.postgresql.util.PSQLException: ERROR: could not
determine data type of parameter $1
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2532)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2267)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:312)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:448)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:369)
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:153)
at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:103)
at jdk.internal.reflect.GeneratedMethodAccessor582.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114)
at com.sun.proxy.$Proxy398.executeQuery(Unknown Source)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:60)
... 114 common frames omitted
I searched a lot on Internet on this topic, but can not find soluthion.
I do not want to handle it in service layer.
I tried:
PostgreSql CAST function
check as String
#Type annotation.
Is there anyway to check UUID null Value in JPQL?

After a bit investigation on Internet, I found the solution.
As PostgreSQL can not determine dataType, we can declare it from before as TypedParameterValue.
TypedParameterValue attributeId = new TypedParameterValue(PostgresUUIDType.INSTANCE, UUIDUtil.toUUID(attributeId));
Page<Attribute> attributes = attributeRepo.findByAttributeId(attributeId);
Then in JPQL for nullChecking, cast to org.hibernate.type.PostgresUUIDType:
( In IDE, it can be shown as error, but it compiles actually)
#Query("select a from Attribute a where (cast(:attributeId as org.hibernate.type.PostgresUUIDType) OR a.id = :attributeId)")
Page<Attribute> findByAttributeId(#Param("attributeId") TypedParameterValue attributeId);
In Native Query:
#Query(value = "select * from attribute a where (cast(:attributeId as uuid) OR a.id = :attributeId)",nativeQuery = true)
List<Attribute> findByAttributeId(#Param("attributeId") TypedParameterValue attributeId);

I had a similar error with JPA 3.0 + EclipseLink + PostgreSQL and was caused because something about automatic casting of parameters. Try adding a stringtype=unspecified to your connection URL:
jdbc:postgresql://SERVER:5432/mydatabase?stringtype=unspecified

Related

Getting java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token after running query

I have this old code which uses hibernate to talk to a mySQL DB. I am trying to add a new entry to a table and in doing so this particular section of code is hit.
Query query = em.createQuery(" SELECT MAX(CAST(value,integer)) FROM StaticData where type=:type");
query.setParameter("type", type);
x = query.getResultList();
But it is throwing an exception as follows
[http-nio-8080-exec-153] StaticDataManager - java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: , near line 1, column 23 [ SELECT MAX(CAST(value,integer)) FROM StaticData where type=:type]
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:138)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:725)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:113)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:362)
at com.sun.proxy.$Proxy1064.createQuery(Unknown Source)
The Columns type and value are of type String.
What does this error mean? I don't know a lot about hibernate, sorry for asking anything stupid. Thanks in advance for any help.
From your exception message
QuerySyntaxException: unexpected token: , near line 1, column 23
it says that it received the comma token, which is not what it expects.
A quick lookup on the HQL cast function suggests that the syntax of cast is CAST( as
Perhaps try
Query query = em.createQuery(" SELECT MAX(CAST(value as integer)) FROM StaticData where type=:type");

Spring Data JPA: The data types varchar and varbinary are incompatible in the add operator exception occurs when using concat() method

In my Spring Data project I am trying to use concat operation on JPA query annotation(shown below)
#Query("SELECT a from ApiEnrollmentsView a where (:mrn is null or a.mrn=:mrn) and " +
" (:firstName is null or a.firstName like concat(:firstName, '%')) and " +
" (:lastName is null or a.lastName like concat(:lastName, '%')) ")
List<ApiEnrollmentsView> findEnrollmentsByMrnAndFirstNameAndLastName(String mrn, String firstName, String lastName);
Project compiles fine but when I access the method, I get exception data types varchar and varbinary are incompatible in the add operator
Exception:
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The data types varchar and varbinary are incompatible in the add operator.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:262)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1632)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:600)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:522)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7225)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:3053)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:247)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:222)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeQuery(SQLServerPreparedStatement.java:444)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52)
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:57)
... 174 more
I remember I had exactly the same weird error. As it is mentioned in the comments the problem solved by using coalesce function instead of concat.
use COALESCE(:lastName, '') inside CONCAT. It resolves my issue

Spring Data JPA - problem with null parameter for NUMBER column type

I want to make dynamic query in which if particular parameter is sent, the Native query should filter the result based on it. In case it's null, it should not reflect the result.
I am using Spring Data JPA with Native query mechanism + Oracle DB
For String parameters this approach works fine
:email is null or s.email = :email
but for Integer parameters when they have value, the Query works but if the parameter is null the query fails with the error
Caused by: java.sql.SQLSyntaxErrorException: ORA-00932: inconsistent datatypes: expected NUMBER got BINARY
I am using the exactly the same approach for for Integer instead of String
I am wondering whether the problem is on my side or it's some kind of bug?
In Oracle DB it's not worked this way. A workaround is using JPQL like
SELECT s FROM Entity s WHERE :id is null OR s.id = COALESCE(:id, -1)
Or for native query use TO_NUMBER function of oracle
SELECT s FROM Entity s WHERE :id is null OR s.id = TO_NUMBER(:id)

Set random seed on Postgres using hibernate

I'm not very familiar with Hibernate, but I need to set the random seed on a PostgreSQL database using Hibernate.
This is what I'm trying to run:
String seedSql = "select setseed(0.123)";
Query seedQuery = entityManager.createQuery(seedSql);
seedQuery.getSingleResult();
However, this query does not return any entity mapped by Hibernate, thus I'm receiving the following error:
org.hibernate.QueryException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode (...)
Any suggestions?
According to the docs, createQuery() takes a JPQL string, and apparently doesn't know what to do with your Postgres function call.
To run an SQL query, use createNativeQuery() instead.
After some trial and error I noticed that I had to use .createNativeQuery() since setseed() is a function from PostgreSQL:
String seedsql = "select cast(setseed(0.123) as text)";
Query seedQuery = DatabaseInterface.getEm().createNativeQuery(seedsql);
seedQuery.setMaxResults(1).getSingleResult();
I used cast(setseed(0.123) as text) to avoid another error:
org.hibernate.MappingException: No Dialect mapping for JDBC type: 1111

Hibernate Spatial - 'Invalid endian flag value encountered' Exception

I'm trying to run a simple query in Hibernate Spatial 4.0 on PostgreSQL 9.3. I have a number of objects in a table with latitude/longitude values, and I'm trying to query objects that fall within a given radius of a particular latitude/longitude. The geometry values seem to be persisted without any problem, and are defined like this in my entity class:
#Column(columnDefinition = "Geometry", nullable = true)
#Type(type = "org.hibernate.spatial.GeometryType")
private Point coordinates = null;
I don't have any errors when persisting objects with the coordinates value set. However, when I run a query, I see the following Exception:
javax.servlet.ServletException: javax.servlet.ServletException: javax.ejb.EJBTransactionRolledbackException: org.hibernate.exception.GenericJDBCException: could not extract ResultSet
<snip />
org.postgresql.util.PSQLException: ERROR: Invalid endian flag value encountered.
org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2157)
org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1886)
org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:555)
org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:417)
org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:302)
org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.executeQuery(WrappedPreparedStatement.java:462)
org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:56)
org.hibernate.loader.Loader.getResultSet(Loader.java:2031)
org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1832)
org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1811)
org.hibernate.loader.Loader.doQuery(Loader.java:899)
org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341)
org.hibernate.loader.Loader.doList(Loader.java:2516)
org.hibernate.loader.Loader.doList(Loader.java:2502)
org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2332)
org.hibernate.loader.Loader.list(Loader.java:2327)
org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:490)
org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:355)
org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:195)
org.hibernate.internal.SessionImpl.list(SessionImpl.java:1268)
org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:264)
The query I'm running looks like this:
Query query = this.entityManager
.createQuery(
"SELECT v FROM MyEntity v WHERE within(v.coordinates, :filter) = true",
MyEntity.class);
query.setParameter("filter", point);
I came across this question on StackOverflow that mentions the same error, but I'm declaring my coordinates property the same way that is mentioned in the answer and still get this error.
For the record, I've tried using PostGIS 1.5.2 and PostGIS 2.1.0. I've also tried different version of my PostgreSQL JDBC driver, from 8.4 to 9.3. Regardless of the library version I still encounter this issue.
Can anyone shed any light on what could be happening here? Is my query wrong? Is my property not defined correctly? Is there something else I should be trying? I'm completely stuck and at a loss for what could be the issue here. Any advice would be GREATLY appreciated.
Try this:
#Column(columnDefinition="Geometry")
#Type(type = "org.hibernatespatial.GeometryUserType")
private Point point;
I solved by adding the below dependency
<dependency>
<groupId>org.locationtech.jts</groupId>
<artifactId>jts-core</artifactId>
<version>1.16.1</version>
</dependency>
instead of my old dependency: com.vividsolutions

Categories