I'm having an issue with JPA and json querying. My JPA is Eclipselink and I use Postgres DB.
My query is
with values as(select id, inputspecifications as spec from process where commercial = True and inputspecifications #> '[{\"type\":\"raster\"}]') select id from values where (spec -> 'platforms' is null or (spec -> 'platforms' -> 'satellites' is not null and (spec -> 'platforms' -> 'satellites' ?& array['310802']))
The query works fine until the array inclusion comparison (last bit). It seems JPA is seeing ?& as a positional argument, as per the fine logs
[EL Warning]: sql: 2022-11-07 10:22:05.336--ServerSession(65586123)--Missing Query parameter for named argument: & "null" will be substituted.
[EL Fine]: sql: 2022-11-07 10:22:05.336--ServerSession(65586123)--Connection(1463355115)--with values as(select id, inputspecifications as spec from process where commercial = True and inputspecifications #> '[{"type":"raster"}]') select id from values where (spec -> 'platforms' is null or (spec -> 'platforms' -> 'satellites' is not null and (spec -> 'platforms' -> 'satellites' ? array['310802']))
bind => [null]
[EL Fine]: sql: 2022-11-07 10:22:05.343--ServerSession(65586123)--SELECT 1
[EL Warning]: 2022-11-07 10:22:05.344--UnitOfWork(446445803)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.6.v20200131-b7c997804f): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: syntax error at or near "$1"
Position: 293
Error Code: 0
I have tried escaping in various ways, ie \?&, \?\&,... all fail one way or another...
Any idea how to make jpa NOT see ?& as a positional parameter?
Related
I am using Quill with Doobie and PostgreSQL (org.tpolecat.doobie-quill artifact with version 0.13.1).
This code
case class SomeRecord(id: Int, order: Int, name: String)
val record = SomeRecord(0, 0, "test")
run(
quote(
querySchema[SomeRecord]("some_table")
).insert(lift(record))
)
Will end up in error message in runtime:
org.postgresql.util.PSQLException: ERROR: syntax error at or near "order"
Position: 46
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2553)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2285)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:323)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:481)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:401)
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:164)
at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:130)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java)
at doobie.free.KleisliInterpreter$PreparedStatementInterpreter.$anonfun$executeUpdate$5(kleisliinterpreter.scala:955)
at doobie.free.KleisliInterpreter$PreparedStatementInterpreter.$anonfun$executeUpdate$5$adapted(kleisliinterpreter.scala:955)
at doobie.free.KleisliInterpreter.$anonfun$primitive$2(kleisliinterpreter.scala:109)
It seems that Quill does not escape keyword-like column names, so "order" (and other keywords) columns in it's query will always fail. See Escaping keyword-like column names in Postgres . The workaround is to rename the column in table (and corresponding case classes).
This following is the query i am using for setting BigDecimal value in Query but failing as error in SQL Syntax
#Query(value="Select f.id,s.student_id,f.feesPaid,f.fees_pending,f.paid_datetime from Fees f inner join Student s where f.feesPaid > :amt")
List<Fees> findFirst3ByFeesPaidGreaterThan( #Param(value = "amt") BigDecimal amt);
the following is the error
Hibernate: select fees0_.id as col_0_0_, student1_.student_id as col_1_0_, fees0_.fees_paid as col_2_0_, fees0_.fees_pending as col_3_0_, fees0_.paid_datetime as col_4_0_ from fees fees0_ inner join student student1_ on where fees0_.fees_paid>?
2019-05-07 20:06:16.779 WARN 21752 --- [nio-8082-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1064, SQLState: 42000
2019-05-07 20:06:16.779 ERROR 21752 --- [nio-8082-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where fees0_.fees_paid>500' at line 1
I am able to use the query method name but i wanted to do it using Query as mentioned above.
I have an issue with my native query.
I've got:
#Query(value="SELECT * from orders where orders.house in ((:houseArray))", nativeQuery = true)
List<Order> findByHouseId(#Param("houseArray") List<Long> houseArray);
And when I am trying to execute, I get the following:
2017-04-18 14:19:49,736 DEBUG org.hibernate.SQL: SELECT * from orders where orders.house in ((?, ?, ?, ?, ?))
2017-04-18 14:19:49,737 TRACE o.h.t.d.s.BasicBinder: binding parameter [2] as [BIGINT] - [4]
2017-04-18 14:19:49,737 TRACE o.h.t.d.s.BasicBinder: binding parameter [3] as [BIGINT] - [5]
2017-04-18 14:19:49,737 TRACE o.h.t.d.s.BasicBinder: binding parameter [1] as [BIGINT] - [3]
2017-04-18 14:19:49,737 TRACE o.h.t.d.s.BasicBinder: binding parameter [4] as [BIGINT] - [6]
2017-04-18 14:19:49,737 TRACE o.h.t.d.s.BasicBinder: binding parameter [5] as [BIGINT] - [7]
2017-04-18 14:19:49,738 ERROR o.h.e.j.s.SqlExceptionHelper: ERROR: operator does not exist: bigint = record
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Position: 49
2017-04-18 14:19:49,756 ERROR o.a.c.c.C.[.[.[.[dispatcherServlet]: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause
org.postgresql.util.PSQLException: ERROR: operator does not exist: bigint = record
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
However, if I run the following query in console:
SELECT * from orders where orders.house in (1,15,2,4,5,3,6,7);
It returns proper list of orders.
How can I fix this?
Try removing one set of brackets from ((:houseArray)) so it looks like that:
#Query(value="SELECT * from orders where orders.house in (:houseArray)", nativeQuery = true)
List<Order> findByHouseId(#Param("houseArray") List<Long> houseArray);
(value, value, value) is a record, so when you do column in ((value, value, value)) you compare column vs record.
I want to let the persistence provider (EclipseLink 2.5.0) automatically create the tables in the, already existing, database by using the persistence unit property "javax.persistence.schema-generation.create-script-source" and a valid SQL-DDL-script.
persistence.xml:
<property name="javax.persistence.schema-generation.create-script-source" value="data/ddl.sql"/>
ddl.sql:
USE myDatabase;
CREATE TABLE MyTable (
id INTEGER NOT NULL AUTO_INCREMENT,
myColumn VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8 DEFAULT COLLATE = utf8_bin;
But I got the following error:
[EL Warning]: 2014-02-12 13:31:44.778--ServerSession(768298666)--Thread(Thread[main,5,main])--Local Exception Stack:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
Error Code: 1064
Call: CREATE TABLE MyTable (
Query: DataModifyQuery(sql="CREATE TABLE MyTable (")
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:331)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:895)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:957)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:630)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:558)
at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1995)
at org.eclipse.persistence.sessions.server.ServerSession.executeCall(ServerSession.java:570)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeNoSelectCall(DatasourceCallQueryMechanism.java:271)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeNoSelect(DatasourceCallQueryMechanism.java:251)
at org.eclipse.persistence.queries.DataModifyQuery.executeDatabaseQuery(DataModifyQuery.java:85)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
at org.eclipse.persistence.internal.sessions.AbstractSession.internalExecuteQuery(AbstractSession.java:3207)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1797)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1779)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1730)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeNonSelectingCall(AbstractSession.java:1499)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeNonSelectingSQL(AbstractSession.java:1517)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.writeSourceScriptToDatabase(EntityManagerSetupImpl.java:4065)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.writeDDL(EntityManagerSetupImpl.java:3910)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.writeDDL(EntityManagerSetupImpl.java:3783)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:724)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getAbstractSession(EntityManagerFactoryDelegate.java:204)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getDatabaseSession(EntityManagerFactoryDelegate.java:182)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getDatabaseSession(EntityManagerFactoryImpl.java:527)
at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactoryImpl(PersistenceProvider.java:140)
at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:177)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
at nl.tent.competent.data.access.Main.main(Main.java:22)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1054)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4187)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4119)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2815)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2375)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2359)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:885)
... 29 more
It seems that the carriage return line feed (newline) is the problem. And if I change the SQL-DDL-script, so that one SQL-statement only takes one line, everything is working fine.
adjusted ddl.sql:
USE myDatabase;
CREATE TABLE MyTable (id INTEGER NOT NULL AUTO_INCREMENT, myColumn VARCHAR(255) NOT NULL, PRIMARY KEY (id) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8 DEFAULT COLLATE = utf8_bin;
But I don't want to reformat my SQL-DDL-script for readability. Please help!
If someone still faces this problem, it can be solved by adding following parameter (found here):
<property name="hibernate.hbm2ddl.import_files_sql_extractor" value="org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor" />
[SQL]2010/12/07 20:18:32:184 : 0.0010 [update REG_COMP_DEF set OrderNo = Cast(Cast(SUBSTR(orderno,1,10) as numeric(10,0))+10 as varchar(10))||NVL(SUBSTR(orderno,10+1,length(orderno)-10),'') where length(OrderNo)>10 and OrderNo>='3000600050' and OrderNo like '300060%' and OrderNo not like '999999%']
com.ibm.db2.jcc.c.SqlException: DB2 SQL error: SQLCODE: -461, SQLSTATE: 42846, SQLERRMC: SYSIBM.DECIMAL;SYSIBM.VARCHAR
inner cast is ok
I can run it on my DB2 for i system (without the NVL(); not supported in my version).
Can you see if the outer cast will run when the inner one is cast to Decimal() instead of Numeric()?
ref: SQLState 42846 = "Cast from source type to target type is not supported."