2013-04-23 3 views
0

검색 텍스트로 개체 목록을 가져 오려고합니다.PostgreSQL에 특수 문자가있는 전체 텍스트 검색 예외

: 나는

searchText ="Agenya\\&\&"; 

쿼리이 같이, 전 특수 문자 문자열이 진행하면

select object from Object object where object.Id = :Id and fts('english',object.searchColumn,'Agenya\\&\&') = true order by object.objectName asc 

이 같은 예외를 얻고있다 (나는 포스트 그레스의 전체 텍스트 검색 방법을 사용하고 있습니다)

javax.ejb.EJBException: org.hibernate.exception.SQLGrammarException: could not execute query 
    at org.jboss.ejb3.tx.Ejb3TxPolicy.handleExceptionInOurTx(Ejb3TxPolicy.java:63) 
    at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:83) 
    at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:191) 
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) 
    at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:95) 
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) 
    at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62) 
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) 
    at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77) 
    at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:110) 
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) 
    at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46) 
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) 
    at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106) 
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) 
    at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:304) 
    at org.jboss.ejb3.remoting.IsLocalInterceptor.invokeLocal(IsLocalInterceptor.java:81) 
    at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:72) 
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) 
    at org.jboss.ejb3.stateless.StatelessRemoteProxy.invoke(StatelessRemoteProxy.java:107) 
    at $Proxy1152.getAllOpportunitiesBySearchText(Unknown Source) 

Caused by: org.hibernate.exception.SQLGrammarException: could not execute query 
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67) 
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43) 
    at org.hibernate.loader.Loader.doList(Loader.java:2223) 
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104) 
    at org.hibernate.loader.Loader.list(Loader.java:2099) 
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:378) 
    at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338) 
    at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172) 
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121) 
    at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79) 

이 문제를 해결하는 데 도움을주십시오.

답변

0

오히려 날짜가 오래된 Postgres 8.4를 실행하고 있습니다. 이 버전의 standard_conforming_strings의 기본 설정은 off입니다.

이것은 무엇을 제공합니까?

SHOW standard_conforming_strings; 

off을 얻으면 문자열의 백 슬래시가 이스케이프 문자로 처리됩니다. 이스케이프 문자가 무엇인지와 리터럴 백 슬래시가 무엇인지에 대한 질문에서 나에게 명확하지 않습니다. 그에 따라 문자열을 살균하십시오.

리터럴 백 슬래시를 두 배로 늘리고 스위치를 사용한 후에도 계속 작동하도록 문자열을 E 앞에 붙입니다. 또는 on으로 전환하십시오. 결과에 대해 먼저 읽어보십시오.

또한 소프트웨어 계층에서 \을 이스케이프 문자로 처리하는지 확인하십시오. 다시 두 번 다시해야 할 수도 있습니다. 의심 스럽다면 데이터베이스 로그에 log_statement = on이라는 문을 기록하고 Postgres가 실제로 얻는 것을 확인하십시오.

일반적으로 Postgres의 최신 버전으로 업그레이드하는 것이 좋습니다.

두 가지 이상의 음 : 이중 -하지 않을 경우 포스트 그레스에서

  • WHERE 절에

    fts(...) = true 
    

    같은 표현은 항상

    fts(...) 
    
  • Identifiers are cast to lower case로 단순화 될 수있다 인용했다. 따라서 :

    더블 인용 작성시에, 당신은 그들을 두 번 인용 유지하기 위해 실제로 필요한 테이블 및 열 이름이되었다
    from object 
    

    경우

    from Object object 
    

    효과적으로 말하는 단지 시끄러운 방법 그들의 존재의 나머지. 필자의 조언 : PostgreSQL의 CaMeL 사례 식별자에서 벗어나 문제를 해결하십시오.