空值而不是值在LinkedHashMap中

huangapple go评论80阅读模式
英文:

Null instead of value in LinkedHashmap

问题

我正在创建一个 Android 应用程序,使用我创建的 Spring 应用程序将一些数据发送到数据库。

我用以下方法来保存数据:

public void save(LinkedHashMap<String, Object> dataCollected) {
    String sql = "INSERT INTO sys001.lm.bottle_neck_reject (" 
        + "\n col_1, col_2, col_3, col_4," 
        + "\n col_5, col_6, col_7, col_8, col_9," 
        + "\n col_10, col_11, col_12," 
        + "\n col_13)"
        + "\n VALUES (?, ?, ?, ?,"
        + "\n ?, ?, ?, convert(datetime, ? + ' ' + ?, 103), ?," 
        + "\n ?, ?, ?, ?)";

      dataCollected.forEach((key, value) -> {
        System.out.println(key + " > " + value); // output: key_one > value_one
      });

    try(Connection conn = getConnection();
        PreparedStatement saveStatement = conn.prepareStatement(sql)){
      saveStatement.setString(1, (String) dataCollected.get("key_one"));
      saveStatement.setString(2, "WH"); // this value are saved
      saveStatement.setString(3, "PC"); // this value are saved
      saveStatement.setString(4, (String) dataCollected.get("key_two"));
      saveStatement.setString(5, "UN"); // this value are saved
      saveStatement.setString(6, (String) dataCollected.get("key_three"));
      saveStatement.setString(7, (String) dataCollected.get("key_four"));
      saveStatement.setString(8, (String) dataCollected.get("date"));
      saveStatement.setString(9, (String) dataCollected.get("time"));
      saveStatement.setString(10, (String) dataCollected.get("key_five"));
      saveStatement.setString(11, (String) dataCollected.get("key_six"));
      saveStatement.setString(12, (String) dataCollected.get("key_seven"));
      saveStatement.setString(13, (String) dataCollected.get("key_eight"));
      saveStatement.setString(14, (String) dataCollected.get("key_nine"));
      saveStatement.executeUpdate();

    } catch (SQLException e) {
      e.printStackTrace();
    }
  }

问题在于,当我在 forEach 循环中使用这个方法时,我可以正确地看到并获取 keyvalues,但是当我向数据库发送查询时,记录被创建,但除了位置 2、3 和 5('WH'、'PC'、'UN')之外,所有值都是 null,这些位置的值被正确创建。

有人可以告诉我代码有什么问题吗?或者也许有一些与代码无关的其他问题吗?我一点头绪都没有,将不胜感激地接受任何建议。

英文:

I am creating android application which sending some data to database using Spring application also create by me.

Method which I am using to save data is this:

public void save(LinkedHashMap&lt;String, Object&gt; dataCollected) {
    String sql = &quot;INSERT INTO sys001.lm.bottle_neck_reject (&quot; 
        + &quot;\n col_1, col_2, col_3, col_4,&quot; 
        + &quot;\n col_5, col_6, col_7, col_8, col_9,&quot; 
        + &quot;\n col_10, col_11, col_12,&quot; 
        + &quot;\n col_13)&quot;
        + &quot;\n VALUES (?, ?, ?, ?,&quot;
        + &quot;\n ?, ?, ?, convert(datetime, ? + &#39; &#39; + ?, 103), ?,&quot; 
        + &quot;\n ?, ?, ?, ?)&quot;;

      dataCollected.forEach((key, value) -&gt; {
        System.out.println(key + &quot; &gt; &quot; + value); // output: key_one &gt; value_one
      });

    try(Connection conn = getConnection();
        PreparedStatement saveStatement = conn.prepareStatement(sql)){
      saveStatement.setString(1, (String) dataCollected.get(&quot;key_one&quot;));
      saveStatement.setString(2, &quot;WH&quot;); // this value are saved
      saveStatement.setString(3, &quot;PC&quot;); // this value are saved
      saveStatement.setString(4, (String) dataCollected.get(&quot;key_two&quot;));
      saveStatement.setString(5, &quot;UN&quot;); // this value are saved
      saveStatement.setString(6, (String) dataCollected.get(&quot;key_three&quot;));
      saveStatement.setString(7, (String) dataCollected.get(&quot;key_four&quot;));
      saveStatement.setString(8, (String) dataCollected.get(&quot;date&quot;));
      saveStatement.setString(9, (String) dataCollected.get(&quot;time&quot;));
      saveStatement.setString(10, (String) dataCollected.get(&quot;key_five&quot;));
      saveStatement.setString(11, (String) dataCollected.get(&quot;key_six&quot;));
      saveStatement.setString(12, (String) dataCollected.get(&quot;key_seven&quot;));
      saveStatement.setString(13, (String) dataCollected.get(&quot;key_eight&quot;));
      saveStatement.setString(14, (String) dataCollected.get(&quot;key_nine&quot;));
      saveStatement.executeUpdate();

    } catch (SQLException e) {
      e.printStackTrace();
    }
  }

Problem is that when I am using this method in forEach loop I can properly see and get key and values but when I am sending query to database, record is create but all values are null except position 2, 3 and 5 ('WH', 'PC', 'UN') those are created properly.

Can anyone let me know what is wrong with my code? Or maybe is some other problem, not related to the code? I have no clue, any advice will be appreciated.

答案1

得分: 2

这段代码在执行UPDATE调用后适当地关闭了连接,这就是为什么你看到了一行新数据。

你观察到几乎所有值都是NULL,这只能说明一件事。

dataCollected.get("key_one") 返回了null。你在输入映射中打印了这些值,而且你确实看到了'key_one',但是。

也许键是 " key_one"(注意空格!),或者是类似于'key_one'但不等于'key_one'的其他内容。大多数字体中都有与这些字母看起来完全相同但实际上不是那个字母的符号。例如,字母o有许多非常相似的符号。还有零宽度空格字符和其他在println语句中看不到的创造性空白字符。

以下是如何调试代码的方法:

  1. 使用断点,或者只需添加一个sysout语句,在方法的非常顶部甚至在打开任何数据库连接之前,打印该获取调用的结果:System.out.println(dataCollected.get("key_one")); - 那应该是null,这明确表明无论如何你认为你在foreach循环中看到了什么键,"key_one"都不在那个映射中。

  2. 然后,为了看看在映射中存在的类似key_one的键是什么,循环遍历其中的每个键并打印每个符号的字符值:

public void debugString(String in) {
    System.out.print(in);
    System.out.print(": ");
    for (char c : in.toCharArray()) {
        System.out.print((int) c);
        System.out.print(" ");
    }
    System.out.println();
}

...然后在你的save方法顶部:

debugString("key_one"); // 看看“真正”的key_one是什么样的
for (String key : dataCollected.keySet()) {
    debugString(key); // 现在逐个调试打印每个键
}

很可能这会通过显示不同的数字序列来显示问题。找出差异,查找ASCII表或Unicode表,然后查看哪里出了问题。

例如,如果第一个打印显示第4个数字是95,但是键的第4个数字是818,那么该键正在使用这个备用的下划线字符,它看起来完全相同,或者几乎完全相同,像下划线,但它不是相同的字符,因此不能被.get("key_one")找到。

其他奇特选项A:损坏的映射实现

也许这是LinkedHashMap的某个子类的实例(或者不是java.util.LinkedHashMap,这是有问题的)。通过打印来检查:System.out.println(dataCollected.getClass())。这应该打印出java.util.LinkedHashMap - 如果不是,这值得进一步调查。

其他奇特选项B:损坏的字符串

通过使用hack和反射,可以使字符串(通常是不可变的)包含不同的字符,当你尝试打印它时就会看到这一点。除了有意识地用来搞乱代码的练习之外,没有理由去这样做。如果是这种情况,请找到恶作剧者并告诉他们停止这样做。

英文:

This code properly 'closes' the connection after executing the UPDATE call, which is why you're witnessing a new row.

The fact that you observe the values (almost) all being NULL can only mean one thing.

dataCollected.get(&quot;key_one&quot;) is returning null. You're printing the values in the input map, and you do see 'key_one', however.

Perhaps the key is &quot; key_one&quot; (note the space!), or otherwise something that looks (almost?) exactly like "key_one" but isn't equal to "key_one". There are symbols that look exactly like these letters in most fonts but aren't that letter. For example, the o has a boatload of symbols that look very very similarly. There's also zero-width space characters and other creative whitespace that you won't see in a println statement.

Here's how to debug your code:

  1. Use a breakpoint, or just add a sysout statement, to print, right at the very top of the method before you even open any db connections, the result of that get call: System.out.println(dataCollected.get(&quot;key_one&quot;)); - that should be null, which indicates beyond any doubt that regardless of what you think you're seeing with that foreach loop to print keys, &quot;key_one&quot; is not in that map.

  2. Then, to see what key_one-esque key IS in the map, loop through each key in it and print the char values of each symbol:

public void debugString(String in) {
System.out.print(in);
System.out.print(&quot;: &quot;);
for (char c : in.toCharArray()) {
System.out.print((int) c);
System.out.print(&quot; &quot;);
}
System.out.println();
}

... and then in your save method, at the top:

debugString(&quot;key_one&quot;); // see what a &#39;real&#39; key_one looks like
for (String key : dataCollected.keySet()) {
debugString(key); // now debug-print each key
}

Likely this will show the problem by giving a different sequence of numbers. Find the difference, grab an ascii chart or unicode table, and look up what's wonky.

For example, if the first print shows that the 4th number is 95 but the key has as 4th number 818, then the key is using this alternate underscore character that will look exactly, or almost exactly, like an underscore, but it's not the same character, therefore, wouldn't be found by .get(&quot;key_one&quot;).

Other exotic option A: Broken map impl

Perhaps that is an instance of some subclass of LinkedHashMap (or not java.util.LinkedHashMap which is broken. Check by printing: System.out.println(dataCollected.getClass()). This should print java.util.LinkedHashMap - if it does not, this is worth investigating further.

Other exotic option B: Broken string

It is possible, but tricky, to use hacks and reflection to make a string (which is normally immutable) contain different characters, which you'd witness when you try to print it. There's no reason to ever do such a thing except as an intentional exercise to mess up code. If that's the case, find the prankster and tell them to cut it out.

huangapple
  • 本文由 发表于 2020年7月24日 22:35:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/63075795.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定