2015-02-02 2 views
3

Postgres DB의 JSONB 열에 대해 JPA로 쿼리를 작성하려고합니다. 쿼리는 거의 Postgres JSON Documentation에서이 예를 다음과 같이 표시됩니다Postgres의 JSONB 열에 대한 JPA 쿼리

-- Find documents in which the key "company" has value "Magnafone" 
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"company": "Magnafone"}'; 

jdoc 테이블 api에서 JSONB의 열입니다.

지금까지이 쿼리를 실행하는 것은 쉽고 문제가되지 않습니다. 그러나 쿼리를 매개 변수화하려고하면 막혔습니다. 때문에,

1)이 작동하지 않습니다 여기에

내가 시도한 몇 가지 질의입니까? '-signs 사이에 인식되지 않습니다 :

String name= "Magnafone"; 

JPA.em().createNativeQuery("SELECT jdoc FROM api 
WHERE jdoc @> '{\"name\": ?}'", Record.class) 
.setParameter(1, name) 

오류 :

play.api.Application$$anon$1: Execution exception[[IllegalArgumentException: org.hibernate.QueryParameterException: Position beyond number of declared ordinal p 
arameters. Remember that ordinal parameters are 1-based! Position: 2]] 
     at play.api.Application$class.handleError(Application.scala:293) ~[play_2.10-2.2.3.jar:2.2.3] 
     at play.api.DefaultApplication.handleError(Application.scala:399) [play_2.10-2.2.3.jar:2.2.3] 
     at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$3.apply(PlayDefaultUpstreamHandler.scala:264) [play_2.10-2.2.3.jar: 
2.2.3] 
     at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$3.apply(PlayDefaultUpstreamHandler.scala:264) [play_2.10-2.2.3.jar: 
2.2.3] 
     at scala.Option.map(Option.scala:145) [scala-library-2.10.3.jar:na] 
     at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3.applyOrElse(PlayDefaultUpstreamHandler.scala:264) [play_2.10-2.2.3.jar:2.2.3] 
Caused by: java.lang.IllegalArgumentException: org.hibernate.QueryParameterException: Position beyond number of declared ordinal parameters. Remember that ordin 
al parameters are 1-based! Position: 2 
     at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:451) ~[hibernate-entitymanager-4.1.8.Final.jar:4.1.8.Final] 
     at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:72) ~[hibernate-entitymanager-4.1.8.Final.jar:4.1.8.Final] 
     at models.lol.player.IPlayer.getPlayerByName(IPlayer.java:22) ~[na:na] 
     at controllers.LoadTeamController.loadTeamData(LoadTeamController.java:23) ~[na:na] 
     at Routes$$anonfun$routes$1$$anonfun$applyOrElse$2$$anonfun$apply$2.apply(routes_routing.scala:57) ~[na:na] 
     at Routes$$anonfun$routes$1$$anonfun$applyOrElse$2$$anonfun$apply$2.apply(routes_routing.scala:57) ~[na:na] 
Caused by: org.hibernate.QueryParameterException: Position beyond number of declared ordinal parameters. Remember that ordinal parameters are 1-based! Position: 
2 
     at org.hibernate.engine.query.spi.ParameterMetadata.getOrdinalParameterDescriptor(ParameterMetadata.java:80) ~[hibernate-core-4.1.8.Final.jar:4.1.8.Fina 
l] 
     at org.hibernate.engine.query.spi.ParameterMetadata.getOrdinalParameterExpectedType(ParameterMetadata.java:86) ~[hibernate-core-4.1.8.Final.jar:4.1.8.Fi 
nal] 
     at org.hibernate.internal.AbstractQueryImpl.determineType(AbstractQueryImpl.java:450) ~[hibernate-core-4.1.8.Final.jar:4.1.8.Final] 
     at org.hibernate.internal.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:422) ~[hibernate-core-4.1.8.Final.jar:4.1.8.Final] 
     at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:445) ~[hibernate-entitymanager-4.1.8.Final.jar:4.1.8.Final] 
     at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:72) ~[hibernate-entitymanager-4.1.8.Final.jar:4.1.8.Final]</code> 

2) 다른 SO-스레드에서 이것을 발견했습니다. 그래도 작동하지 않습니다. 왜냐하면 || 질의에 나타나고 SQL Exception을 던집니다.

JPA.em().createNativeQuery("SELECT jdoc FROM api 
WHERE jdoc @> '{\"name\": ' || :name ||'}'", Record.class) 
.setParameter("name", name) 

오류 : 나는 파라미터를 사용하는 동안 포스트 그레스 또는 JPA가 하나 또는 다른 방법으로 던져 만든 및 JSON 매개 변수를 얻기 위해 관리하지 않은 몇 가지 다른 일을 시도했습니다

play.api.Application$$anon$1: Execution exception[[IllegalArgumentException: org.hibernate.QueryParameterException: Position beyond number of declared ordinal p 
arameters. Remember that ordinal parameters are 1-based! Position: 2]] 
     at play.api.Application$class.handleError(Application.scala:293) ~[play_2.10-2.2.3.jar:2.2.3] 
     at play.api.DefaultApplication.handleError(Application.scala:399) [play_2.10-2.2.3.jar:2.2.3] 
     at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$3.apply(PlayDefaultUpstreamHandler.scala:264) [play_2.10-2.2.3.jar: 
2.2.3] 
     at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$3.apply(PlayDefaultUpstreamHandler.scala:264) [play_2.10-2.2.3.jar: 
2.2.3] 
     at scala.Option.map(Option.scala:145) [scala-library-2.10.3.jar:na] 
     at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3.applyOrElse(PlayDefaultUpstreamHandler.scala:264) [play_2.10-2.2.3.jar:2.2.3] 
Caused by: java.lang.IllegalArgumentException: org.hibernate.QueryParameterException: Position beyond number of declared ordinal parameters. Remember that ordin 
al parameters are 1-based! Position: 2 
     at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:451) ~[hibernate-entitymanager-4.1.8.Final.jar:4.1.8.Final] 
     at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:72) ~[hibernate-entitymanager-4.1.8.Final.jar:4.1.8.Final] 
     at models.lol.player.IPlayer.getPlayerByName(IPlayer.java:22) ~[na:na] 
     at controllers.LoadTeamController.loadTeamData(LoadTeamController.java:23) ~[na:na] 
     at Routes$$anonfun$routes$1$$anonfun$applyOrElse$2$$anonfun$apply$2.apply(routes_routing.scala:57) ~[na:na] 
     at Routes$$anonfun$routes$1$$anonfun$applyOrElse$2$$anonfun$apply$2.apply(routes_routing.scala:57) ~[na:na] 
Caused by: org.hibernate.QueryParameterException: Position beyond number of declared ordinal parameters. Remember that ordinal parameters are 1-based! Position: 
2 
     at org.hibernate.engine.query.spi.ParameterMetadata.getOrdinalParameterDescriptor(ParameterMetadata.java:80) ~[hibernate-core-4.1.8.Final.jar:4.1.8.Fina 
l] 
     at org.hibernate.engine.query.spi.ParameterMetadata.getOrdinalParameterExpectedType(ParameterMetadata.java:86) ~[hibernate-core-4.1.8.Final.jar:4.1.8.Fi 
nal] 
     at org.hibernate.internal.AbstractQueryImpl.determineType(AbstractQueryImpl.java:450) ~[hibernate-core-4.1.8.Final.jar:4.1.8.Final] 
     at org.hibernate.internal.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:422) ~[hibernate-core-4.1.8.Final.jar:4.1.8.Final] 
     at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:445) ~[hibernate-entitymanager-4.1.8.Final.jar:4.1.8.Final] 
     at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:72) ~[hibernate-entitymanager-4.1.8.Final.jar:4.1.8.Final] 

JPA에서.

3)

JPA.em().createNativeQuery("SELECT jdoc FROM api 
WHERE jdoc @> '{\"name\": ' || ? ||'}'", Record.class) 
.setParameter(1", name) 

오류 : 참고로

play.api.Application$$anon$1: Execution exception[[PersistenceException: org.hibernate.exception.DataException: FEHLER: ung³ltige Eingabesyntax f³r Typ json 
    Detail: Die Eingabezeichenkette endete unerwartet. 
    Position: 62 
    Where: JSON-Daten, Zeile 1: {"name": ]] 
     at play.api.Application$class.handleError(Application.scala:293) ~[play_2.10-2.2.3.jar:2.2.3] 
     at play.api.DefaultApplication.handleError(Application.scala:399) [play_2.10-2.2.3.jar:2.2.3] 
     at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$3.apply(PlayDefaultUpstreamHandler.scala:264) [play_2.10-2.2.3.jar: 
2.2.3] 
     at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$3.apply(PlayDefaultUpstreamHandler.scala:264) [play_2.10-2.2.3.jar: 
2.2.3] 
     at scala.Option.map(Option.scala:145) [scala-library-2.10.3.jar:na] 
     at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3.applyOrElse(PlayDefaultUpstreamHandler.scala:264) [play_2.10-2.2.3.jar:2.2.3] 
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.DataException: FEHLER: ung³ltige Eingabesyntax f³r Typ json 
    Detail: Die Eingabezeichenkette endete unerwartet. 
    Position: 62 
    Where: JSON-Daten, Zeile 1: {"name": 
     at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1377) ~[hibernate-entitymanager-4.1.8.Final.jar:4.1.8.Final] 
     at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300) ~[hibernate-entitymanager-4.1.8.Final.jar:4.1.8.Final] 
     at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:266) ~[hibernate-entitymanager-4.1.8.Final.jar:4.1.8.Final] 
     at models.lol.player.IPlayer.getPlayerByName(IPlayer.java:24) ~[na:na] 
     at controllers.LoadTeamController.loadTeamData(LoadTeamController.java:23) ~[na:na] 
     at Routes$$anonfun$routes$1$$anonfun$applyOrElse$2$$anonfun$apply$2.apply(routes_routing.scala:57) ~[na:na] 
Caused by: org.hibernate.exception.DataException: FEHLER: ung³ltige Eingabesyntax f³r Typ json 
    Detail: Die Eingabezeichenkette endete unerwartet. 
    Position: 62 
    Where: JSON-Daten, Zeile 1: {"name": 
     at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:134) ~[hibernate-core-4.1.8.Final.jar:4.1.8.Final 
] 
     at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49) ~[hibernate-core-4.1.8.Final.jar:4.1.8. 
Final] 
     at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125) ~[hibernate-core-4.1.8.Final.jar:4.1.8.Final] 
     at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110) ~[hibernate-core-4.1.8.Final.jar:4.1.8.Final] 
     at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129) ~[hibernate-core-4. 
1.8.Final.jar:4.1.8.Final] 
     at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81) ~[hibernate-core-4.1.8.Final.jar:4.1.8.Final] 
Caused by: org.postgresql.util.PSQLException: FEHLER: ung³ltige Eingabesyntax f³r Typ json 
    Detail: Die Eingabezeichenkette endete unerwartet. 
    Position: 62 
    Where: JSON-Daten, Zeile 1: {"name": 
     at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2157) ~[postgresql-9.2-1003-jdbc4.jar:na] 
     at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1886) ~[postgresql-9.2-1003-jdbc4.jar:na] 
     at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255) ~[postgresql-9.2-1003-jdbc4.jar:na] 
     at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:555) ~[postgresql-9.2-1003-jdbc4.jar:na] 
     at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:417) ~[postgresql-9.2-1003-jdbc4.jar:na] 
     at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:302) ~[postgresql-9.2-1003-jdbc4.jar:na] 

:

JPA.em().createNativeQuery("SELECT jdoc->'guid', jdoc->'name' FROM api 
WHERE jdoc @> '{\"company\": \""+company+"\"}'", Record.class) 

을 또한 :이, 나는) 그것을 사용하지 않는 걱정하지 마십시오 (작동 I '@> - 오페라가 JPA에 의해 인식되지 않기 때문에 createNativeQuery을 사용 중입니다.

감사합니다.

티모

+0

은'|| '접근 방식을 시도하지만,'같은 것을해야한다 '{\ "회사 \"\ "'| |? || '\ "}' '. 물론'setParameter (1, company)'를 사용하십시오. – RealSkeptic

+0

작동하지 않습니다 :/그는 "-symbol"에 대해 불평합니다. ''{\ "company \": '||? ||'} ''오류는 입력 문자열이 예기치 않게 종료된다고 말합니다 .. – Timo

+0

It 실제로 사용 가능한 경우 전체 스택 추적을 사용하여 실제 오류 메시지를 추가 할 경우 도움이 될 것입니다. 위의 예제에서 문자열을' "로 닫지 않는 것 같습니다. 이것은 실제 코드입니까? – RealSkeptic

답변

0

pozs는 주석으로 대답을 게시 :

Try "... WHERE jdoc @> cast('{\"company\":' || to_json(cast(? as text)) || '}' as json)" (or jsonb at the last cast, if that's appropriate).