2011-12-14 92 views
0

我想弄清楚我在Datanucleus(由Postgres DB支持)中的查询出错的地方。当表达式包含反斜杠时,即使简单查询似乎也会失败。然而,我的印象是,JDO/Datanucleus应该抽象出手动将参数转义为查询的需求,就像PreparedStatement用纯粹的JDBC一样。Datanucleus + PostgreSQL不能逃避反斜杠

这里的一个自包含例如:

package somepkg; 

import org.datanucleus.api.jdo.JDOPersistenceManager; 

import javax.jdo.*; 
import javax.jdo.annotations.*; 
import java.util.*; 

@PersistenceCapable 
public final class MyPersistentObject { 

    @Persistent(valueStrategy = IdGeneratorStrategy.INCREMENT) 
    @PrimaryKey 
    private long id; 

    @Persistent 
    private String value; 

    public MyPersistentObject(String value) { 
     this.value = value; 
    } 

    public static void main(String... args) { 
     JDOPersistenceManager pm = (JDOPersistenceManager) 
       JDOHelper.getPersistenceManagerFactory(datanucleusProperties()) 
         .getPersistenceManager(); 

     //seems to be a problem with values that contain a backspace 
     String value = "\\"; 

     //store (works fine) 
     Transaction tx = pm.currentTransaction(); 
     tx.begin(); 
     MyPersistentObject objectToStore = new MyPersistentObject(value); 
     pm.makePersistent(objectToStore); 
     tx.commit(); 

     //fetch (fails) 
     MyPersistentObject fetchedObject = pm 
       .newTypesafeQuery(MyPersistentObject.class) 
       .filter(QMyPersistentObject.candidate().value.eq(value)) 
       .executeUnique(); 

     System.out.println(fetchedObject); 
    } 

    private static Map<String, String> datanucleusProperties() { 
     Map<String, String> datanucleusProperties = new HashMap<String, String>(); 

     datanucleusProperties.put("javax.jdo.option.ConnectionDriverName", "org.postgresql.Driver"); 
     datanucleusProperties.put("javax.jdo.option.ConnectionURL", "jdbc:postgresql:test"); 
     datanucleusProperties.put("javax.jdo.option.ConnectionUserName", "postgres"); 
     datanucleusProperties.put("javax.jdo.option.ConnectionPassword", ""); 
     datanucleusProperties.put("datanucleus.autoCreateSchema", "true"); 
     datanucleusProperties.put("datanucleus.validateTables", "false"); 
     datanucleusProperties.put("datanucleus.validateConstraints", "false"); 
     return datanucleusProperties; 
    } 
} 

QMyPersistentObject通过运行注解处理器生成。这种失败,出现以下消息:

Exception in thread "main" javax.jdo.JDOException: Exception thrown when executing query 
at org.datanucleus.api.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:567) 
at org.datanucleus.api.jdo.query.JDOTypesafeQuery.executeInternalQuery(JDOTypesafeQuery.java:946) 
at org.datanucleus.api.jdo.query.JDOTypesafeQuery.executeUnique(JDOTypesafeQuery.java:770) 
at somepkg.MyPersistentObject.main(MyPersistentObject.java:52) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:601) 
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 
NestedThrowablesStackTrace: 
org.postgresql.util.PSQLException: ERROR: unterminated quoted string at or near "'\'" 
Position: 128 
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102) 
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1835) 
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257) 
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:500) 
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:388) 
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:273) 
at org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96) 
at org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96) 
at org.datanucleus.store.rdbms.SQLController.executeStatementQuery(SQLController.java:465) 
at org.datanucleus.store.rdbms.query.JDOQLQuery.performExecute(JDOQLQuery.java:625) 
at org.datanucleus.store.query.Query.executeQuery(Query.java:1789) 
at org.datanucleus.store.query.Query.executeWithArray(Query.java:1665) 
at org.datanucleus.store.query.Query.execute(Query.java:1638) 
at org.datanucleus.api.jdo.query.JDOTypesafeQuery.executeInternalQuery(JDOTypesafeQuery.java:936) 
at org.datanucleus.api.jdo.query.JDOTypesafeQuery.executeUnique(JDOTypesafeQuery.java:770) 
at somepkg.MyPersistentObject.main(MyPersistentObject.java:52) 

有谁知道有足够的了解JDO或DataNucleus将知道如果我需要采取额外的步骤,以逃避的东西,当我查询?如果没有(我会假设),我想这是Datanucleus或Postgres JDBC驱动程序中的一个错误?

回答

0

为什么不只是将参数放在那里(而不是硬编码值和获取后续问题),然后将它作为?传递给JDBC驱动程序。即JDBC总是建议处理这种事情的方式

+0

感谢您的回复。所以你说使用BooleanExpression不会为你转义文字?我原以为这是最终开发人员不需要担心的事情,因为我不是制作SQL的人。我对DN的理解是,我不必与JDBC进行很多交互。你能指出我的资源,描述你在说什么吗? – 2011-12-15 14:54:58