【问题标题】:How can I pass NULL value in SqlData implementation for Long typed attribute?如何在 SqlData 实现中为 Long 类型的属性传递 NULL 值?
【发布时间】:2014-04-02 13:28:49
【问题描述】:

我有大量原始数据(SqlData 对象类型)进入并尝试使用创建的用户定义类型插入 Oracle。

问题仅针对具有一些为空的 Long 属性的记录。 我得到这些记录的 NullPointer 异常 - 因为它试图在空对象上调用 toString。

有没有办法为 Long 列(在 SQLOutput 流中)写入空值?

我知道这可以通过更改为 String 类型来实现,但我无法触及 PL/SQL 函数,因为它在很多地方都使用过。

public classMyClass extends MyBaseType implements SQLData {

public void writeSQL(SQLOutput stream) throws SQLException {

    stream.writeString(getSource());
    stream.writeTimestamp(getDtm());
    stream.writeString(getUniqueId());
    stream.writeString(getType());

    stream.writeLong(getResponseCode());

当 getResponseCode() 为 null 时,最后一行会导致 NullPointer 异常。

知道如何在不改变类型(为字符串)的情况下处理这个问题吗?

最后尝试的选项是,

private void writeNullPossibleNumber(SQLOutput stream, Integer intValue) throws SQLException {

    if (intValue==null) {
        stream.writeBigDecimal(null);
    } else {
        stream.writeInt(intValue);            
    }
}

上述解决方案工作正常。

参考: http://docs.oracle.com/cd/A87860_01/doc/java.817/a81357/sampcod3.htm

感谢大家的帮助

【问题讨论】:

    标签: java spring oracle jdbc


    【解决方案1】:

    如您所见 SQLOutput.writeLong 等待 primitive long,但您似乎尝试提供包装器 Long。在这种情况下,null 当然不能转换为任何primitive

    所以,或者只是在writeLong 之前添加null check,或者更改整个逻辑,如果您根本无法将空值写入数据库。

    【讨论】:

    • 你是对的! - 它期望原始类型。我认为我只能适应这一点,但问题是它用于设置 NULL 值的早期实现(使用 PreparedStatement setLong 调用)。有些是 id 值,我不能在那些地方假设 0。
    • 很高兴知道。所以,添加我的声誉;-)
    • 谢谢!如果空检查指示空值,您可以通过指示做什么来改进答案。幸运的是,OP 用最终解决方案更新了他的问题。
    【解决方案2】:

    由于自动拆箱,您会得到 NPE。你应该明确写空值,试试这样:

    if (getResponseCode() != null) stream.writeBigDecimal(new BigDecimal(getResponseCode()));
    else stream.writeBigDecimal(null);
    

    【讨论】:

    • 我得到以下 - 错误代码 [17059];无法转换为内部表示:;嵌套异常是 java.sql.SQLException: 无法转换为内部表示:
    • 好的。试试这个stream.writeBigDecimal(null)。由于任何数字都以 NUMBER 的形式填充到数据库中(尤其是对于 Oracle),这将是null 数字的一种解决方法。
    • @ArtemBilan 我修改了答案。我实际上并没有使用SQLOutput,而是在 javadoc 中查找了发送 null 的方法。
    • 你不能混合两种类型——if(true) 相同类型,否则相同类型。我试过了。但引起:java.sql.SQLException:无法转换为内部表示:在 oracle.jdbc.oracore.OracleTypeNUMBER.toNUMBER(OracleTypeNUMBER.java:268)
    • @RajeshBalan 尝试仅使用BigDecimal。我更新了我的答案。
    【解决方案3】:

    您可以选择以下任一选项:

    • 明确使用 NULL 作为空值(使用 if 语句选择 NULL 或 toString)
    • 如果值为 null,则从插入中删除该列

    类似下面的帮助类可能对你有用。

    public class DatabaseHelper {
    private static final String CNULL = "NULL";
    
    static public String fixValue(Object value) {
        if (value == null) {
            return CNULL;
        } else {
            return value.toString();
        }
    }
    }
    

    【讨论】:

    • 这里的问题是我需要接触服务器合同来支持这一点。就像我说的,早期的实现是使用 PreparedStatement setLong 调用,其中也允许使用 null。有些值是 ID,这些是 null 我不能假设它是 0,因为在我之前的实现中它被设置为 NULL
    猜你喜欢
    • 1970-01-01
    • 2015-10-02
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    • 1970-01-01
    • 2020-05-22
    • 2011-09-24
    相关资源
    最近更新 更多