oracle使用jdbctemplate在xmltype列中插入xml批处理更新结果在ORA-01461中:只能绑定LONG值以插入LONG列

t5fffqht  于 2023-06-22  发布在  Oracle
关注(0)|答案(1)|浏览(105)

我有一个spring Boot 应用程序,它有一个实体列表,我将其传递给下面的批处理插入,但结果是ORA-01461: can bind a LONG value only for insert into a LONG column。不太清楚为什么会这样:

(...)
batchInsert(books, 100);
(...)

public int[][] batchInsert(List<Book> books, int batchSize) {
    return jdbcTemplate.batchUpdate(
            "insert into books (bookId, name, price, xml) values(?,?,?,?)",
            books,
            batchSize,
            new ParameterizedPreparedStatementSetter<Book>() {
                public void setValues(PreparedStatement ps, Book argument) 
                    throws SQLException {
                    ps.setString(1, argument.getBookId());
                    ps.setString(2, argument.getName());
                    ps.setBigDecimal(3, argument.getPrice());
                    ps.setString(4, argument.getXml());
                }
            });
}

表中xml列的oracle数据类型为:XML SYS.XMLTYPE
和模型:

@Type(type="com.sample.util.HibernateXMLType")
@Column(name = "XML", columnDefinition="XDB.XMLTYPE")
private String xml;

该错误只发生在某些特定的XML中,而不是所有XML。可能是因为那些特定XML的大小,不是很确定。
我尝试了下面的方法,但仍然得到相同的错误:

1.
SQLXML xmlObject = jdbcTemplate.getDataSource().getConnection().createSQLXML();
xmlObject.setString(argument.getXml());
ps.setSQLXML(4, xmlObject);

2.
ps.setClob(4, new StringReader(argument.getXml()));

现在,我也使用了JPA,如下所示,它使用相同的数据类型,唯一的问题是与jdbctemplate相比它非常慢,可能是因为它必须在插入之前执行一个select来检查实体是否存在:

bookRepo.saveAll(books);
y1aodyip

y1aodyip1#

xmltype应该使用ps.setSQLXMLhttps://docs.oracle.com/javase/tutorial/jdbc/basics/sqlxml.html
但是不要忘记正确初始化它:

SQLXML sqlxml = ps.getConnection().createSQLXML();
 try {
  sqlxml.setString(argument.getXml());
  ps.setSQLXML(4, sqlxml);
 } finally {
  sqlxml.free();
 }
}

相关问题