JPA Native Query设置空参数

46scxncf  于 12个月前  发布在  其他
关注(0)|答案(5)|浏览(144)

下面是我的代码部分:

Query q = em.createNativeQuery("insert into table_name (value_one, value_two, value_three) values (?,?,?)");
q.setParameter(1, value1);
q.setParameter(2, value2);
q.setParameter(3, value3);
q.executeUpdate();

字符串
value3有时可以为null(Date类对象)。如果它为null,则会抛出以下异常:

Caused by: org.postgresql.util.PSQLException: ERROR: column "value_three" is of type timestamp without time zone but expression is of type bytea
  Hint: You will need to rewrite or cast the expression.
  Position: 88
    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.executeUpdate(AbstractJdbc2Statement.java:334)
    at org.hibernate.engine.query.NativeSQLQueryPlan.performExecuteUpdate(NativeSQLQueryPlan.java:189)
    ... 11 more


如何让这段代码工作并将空值持久化到数据库中?

envsm3lx

envsm3lx1#

我在使用EntityManager.createNamedQuery时也遇到过同样的问题(我猜NativeQuery也是这样)。
如果你要传递nullable参数到Query,那么使用TypedParameterValue,它允许传递类型。
例如:

setParameter("paramName", new TypedParameterValue(StandardBasicTypes.LONG, paramValue));

字符串
在这里,你显式地设置了传递值的类型,当你传递空值时,处理器知道确切的类型。

ut6juiuv

ut6juiuv2#

你正在使用postgresql(栈已经告诉你了),可能还有Hibernate,几乎肯定会遇到这个问题:PostgreSQL JDBC Null String taken as a bytea
我使用了这个特殊的解决方案:https://stackoverflow.com/a/23501509/516188
所以这意味着转义到Hibernate API,这样你就可以给予表达式的类型。
在我的情况下,它是一个可空的短,所以我使用:
第一个月
shortValue的类型为Short

zed5wv10

zed5wv103#

如果你没有使用Hibernate,但是你使用的是MyseLink,你可以使用查询提示:https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/Query_Hints
示例查询:

String insert = "INSERT INTO mytable VALUES ( ?, ?, ?, ?)";

em = getEntityManager();
em.getTransaction().begin();
Query u = em.createNativeQuery(insert);
u.setHint(QueryHints.BIND_PARAMETERS, HintValues.FALSE);//<--the hint
u.setParameter(1, "value1");
u.setParameter(2, "value2");
u.setParameter(4, "value4");//just skipped the null element
u.executeUpdate();
em.getTransaction().commit();

字符串
结果将是一个插入:

mytable
column1    column2    column3   column4
value1     value2               value4


当然,如果“column3”在数据库中是可空的...
我不知道Hibernate是否也能用,但它可以。我用PostgreSQL做了测试。

ddhy6vgd

ddhy6vgd4#

在我的例子中,使用Oracle 12和jboss 7.3,我解决了使用空String作为参数值。我不明白为什么,但它工作。这是我的代码:

String sql = "insert into customer (id,name,age) values (?1,?2,?3);
em = getEntityManager();
Query query = em.createNativeQuery(sql);
query.setParameter(1, getId());
query.setParameter(2, getName());
if (getAge() != null) {//getAge() return BigDecimal and map a NUMBER column type
    query.setParameter(3, getAge());
} else {
   query.setParameter(3, "");
}

字符串

elcex8rz

elcex8rz5#

我在使用javax.persistence.Query对Postgresql进行本机查询时遇到了类似的问题,
我找到的最简单的解决方案:

Query q = em.createNativeQuery("insert into table_name (value_one, value_two, value_three) values (?,?,? ::decimal)");
q.setParameter(1, value1);
q.setParameter(2, value2);
q.setParameter(3, value3);
q.executeUpdate();

字符串
注意 insert 语句中的类型转换。
备选方案:

Query q = em.createNativeQuery("insert into table_name (value_one, value_two, value_three) values (?,?,cast(cast(? as text) as decimal))");
q.setParameter(1, value1);
q.setParameter(2, value2);
q.setParameter(3, value3);
q.executeUpdate();


参见:https://stackoverflow.com/a/62321877/13108438

相关问题