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