I need to pass a BigInteger argument to SQL query. (on Postgres 9.2) I have this code in my DAO:
我需要将BigInteger参数传递给SQL查询。(Postgres 9.2)我的DAO中有这个代码:
public List<PersonInfo> select(String id) {
BigInteger bigIntId = new BigInteger(id);
JdbcTemplate select = new JdbcTemplate(dataSource);
return select
.query("SELECT * FROM PE.SUPPLIER_INPUT_DATA WHERE ID = ?",
new Object[] { bigIntId },
new PersonRowMapper());
}
I am getting the following exception:
我有以下的例外:
{"error":"Error invoking getPersonInfoById.[org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback;
bad SQL grammar [SELECT * FROM PE.SUPPLIER_INPUT_DATA WHERE ID = ?];
nested exception is org.postgresql.util.PSQLException:
Can't infer the SQL type to use for an instance of java.math.BigInteger.
Use setObject() with an explicit Types value to specify the type to use.]"}
The id is of type bigint
id为bigint类型。
Tried to pass plain String - also throws type exception. Googled the message in the exception - no relevant result. Any ideas?
尝试传递纯字符串-也抛出类型异常。在异常情况下谷歌搜索了消息——没有相关结果。什么好主意吗?
4 个解决方案
#1
5
Support for BigInteger
was added in JDBC 4.1 (Java 7), somehow I had missed that when I originally wrote this answer.
在JDBC 4.1 (Java 7)中添加了对BigInteger的支持,不知何故,我在最初编写这个答案时忽略了这一点。
Specifically section 3.1 Overview of changes of the JDBC 4.1 specification states:
具体第3.1节JDBC 4.1规范的变更概述:
- Additional Mappings to Table B-4, Mapping from Java Object to JDBC Types
[..]
Support was also added to mapjava.lang.BigInteger
to JDBCBIGINT
.- 表B-4的附加映射,从Java对象到JDBC类型的映射[..]还向map java.lang添加了支持。BigInteger JDBC BIGINT。
- Additional Mappings to Table B-5, Performed by
setObject
andsetNull
between Java Object Types and Target JDBC Types
[..]
Allow conversion ofjava.lang.BigInteger
toCHAR
,VARCHAR
,LONGVARCHAR
, andBIGINT
.- 表B-5的附加映射,由setObject和setNull在Java对象类型和目标JDBC类型之间执行。允许java.lang的转换。从大整数到CHAR, VARCHAR, LONGVARCHAR,和BIGINT。
I'm not sure how well this is supported across drivers.
我不确定它在驱动程序之间的支持程度。
Original answer
The JDBC specification does not include support for BigInteger
; you either need to use a different datatype (eg BigDecimal
with scale 0), or find out if the PostgreSQL driver offers some implementation specific way to set a BigInteger
value.
JDBC规范不包括对BigInteger的支持;您需要使用不同的数据类型(如带0刻度的BigDecimal),或者查看PostgreSQL驱动程序是否提供了设置BigInteger值的特定实现方法。
#2
1
I had the same problem, using Types.BIGINT as a refinement works. I used it in combination with BatchPreparedStatementSetter, this is simple and very readable:
我也有同样的问题,使用类型。BIGINT是一种提纯。我将它与BatchPreparedStatementSetter结合使用,这很简单,也很容易读懂:
@Transactional
public void saveStuff(List<Foo> foos) {
int batchSize = foos.size();
String sql = "INSERT INTO db.foo " +
"(sting_id, a_big_integer, bar, ..etc ) " +
"VALUES (?, ?, ?, ..etc )";
jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
FeedEntry feedEntry = feedEntries.get(i);
int index = 1;
ps.setString(index++, foo.id());
ps.setObject(index++, foo.getTheBigInteger(), Types.BIGINT);
ps.setString(index++, foo.bar())
//etc
}
@Override
public int getBatchSize() {
return foos.size();
}
});
}
#3
0
You can use java.math.BigDecimal
for conversion of BigInt
. The below code should work:
您可以使用java.math。大十进制的转换。下面的代码应该可以工作:
public List<PersonInfo> select(String id) {
BigDecimal bigDecId = new BigDecimal(id);
JdbcTemplate select = new JdbcTemplate(dataSource);
return select
.query("SELECT * FROM PE.SUPPLIER_INPUT_DATA WHERE ID = ?",
new Object[] { bigDecId },
new PersonRowMapper());
}
#4
0
I had the same problem and I updated the driver from 9.3 to 42.2.2. Then worked fine
我遇到了同样的问题,我将驱动从9.3升级到42.2.2。然后工作得很好
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
</dependency>
#1
5
Support for BigInteger
was added in JDBC 4.1 (Java 7), somehow I had missed that when I originally wrote this answer.
在JDBC 4.1 (Java 7)中添加了对BigInteger的支持,不知何故,我在最初编写这个答案时忽略了这一点。
Specifically section 3.1 Overview of changes of the JDBC 4.1 specification states:
具体第3.1节JDBC 4.1规范的变更概述:
- Additional Mappings to Table B-4, Mapping from Java Object to JDBC Types
[..]
Support was also added to mapjava.lang.BigInteger
to JDBCBIGINT
.- 表B-4的附加映射,从Java对象到JDBC类型的映射[..]还向map java.lang添加了支持。BigInteger JDBC BIGINT。
- Additional Mappings to Table B-5, Performed by
setObject
andsetNull
between Java Object Types and Target JDBC Types
[..]
Allow conversion ofjava.lang.BigInteger
toCHAR
,VARCHAR
,LONGVARCHAR
, andBIGINT
.- 表B-5的附加映射,由setObject和setNull在Java对象类型和目标JDBC类型之间执行。允许java.lang的转换。从大整数到CHAR, VARCHAR, LONGVARCHAR,和BIGINT。
I'm not sure how well this is supported across drivers.
我不确定它在驱动程序之间的支持程度。
Original answer
The JDBC specification does not include support for BigInteger
; you either need to use a different datatype (eg BigDecimal
with scale 0), or find out if the PostgreSQL driver offers some implementation specific way to set a BigInteger
value.
JDBC规范不包括对BigInteger的支持;您需要使用不同的数据类型(如带0刻度的BigDecimal),或者查看PostgreSQL驱动程序是否提供了设置BigInteger值的特定实现方法。
#2
1
I had the same problem, using Types.BIGINT as a refinement works. I used it in combination with BatchPreparedStatementSetter, this is simple and very readable:
我也有同样的问题,使用类型。BIGINT是一种提纯。我将它与BatchPreparedStatementSetter结合使用,这很简单,也很容易读懂:
@Transactional
public void saveStuff(List<Foo> foos) {
int batchSize = foos.size();
String sql = "INSERT INTO db.foo " +
"(sting_id, a_big_integer, bar, ..etc ) " +
"VALUES (?, ?, ?, ..etc )";
jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
FeedEntry feedEntry = feedEntries.get(i);
int index = 1;
ps.setString(index++, foo.id());
ps.setObject(index++, foo.getTheBigInteger(), Types.BIGINT);
ps.setString(index++, foo.bar())
//etc
}
@Override
public int getBatchSize() {
return foos.size();
}
});
}
#3
0
You can use java.math.BigDecimal
for conversion of BigInt
. The below code should work:
您可以使用java.math。大十进制的转换。下面的代码应该可以工作:
public List<PersonInfo> select(String id) {
BigDecimal bigDecId = new BigDecimal(id);
JdbcTemplate select = new JdbcTemplate(dataSource);
return select
.query("SELECT * FROM PE.SUPPLIER_INPUT_DATA WHERE ID = ?",
new Object[] { bigDecId },
new PersonRowMapper());
}
#4
0
I had the same problem and I updated the driver from 9.3 to 42.2.2. Then worked fine
我遇到了同样的问题,我将驱动从9.3升级到42.2.2。然后工作得很好
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
</dependency>