You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL数据库数据正确却返回空ResultSet的排查求助

问题排查与解决方案

我仔细梳理了你遇到的问题:同一个数据库连接能正常加载ActionBlock数据,但加载关联的PermanentLocation时却返回空ResultSet,而且直接在DBMS执行相同逻辑的SQL能拿到结果。结合你提供的代码和排查记录,我整理了几个最可能的问题点和修复方案:

1. 优先排查:ServerID的取值不一致(最可能的根源)

我注意到两段代码中获取ServerID的方式不一样:

  • 在loadBlocksFromDatabase里,你用的是 KaranteeniCore.getServerIdentificator()
  • 在loadLocation里,你用的是 KaranteeniPlugin.getServerIdentificator()

这两个方法大概率返回了不同的服务器标识字符串!如果location表中存储的serverID和loadLocation传入的不匹配,自然查不到任何数据。

修复步骤:
把loadLocation里的ServerID获取逻辑改成和ActionBlock一致,比如:

// 修改PermanentLocation.loadLocation中的这一行
st.setString(2, KaranteeniCore.getServerIdentificator());

2. 修正PermanentLocation中的世界判断逻辑

虽然这不是ResultSet为空的直接原因,但这段代码逻辑明显写反了,会导致后续出现错误:

if(world == null) return null;
else Bukkit.getLogger().log(Level.SEVERE, "Could not find world " + w);

正确的逻辑应该是当世界不存在时打印日志并返回null,否则继续创建Location:

if(world == null) {
    Bukkit.getLogger().log(Level.SEVERE, "Could not find world " + w);
    return null;
}
// 继续执行Location创建逻辑...

3. 验证UUID字符串的大小写匹配

部分数据库(比如PostgreSQL)对字符串大小写敏感,Java中UUID.toString()生成的字符串包含大写字母(比如-分隔后的段),如果location表的id字段存储的是小写UUID,就会导致匹配失败。

验证与修复:
在loadLocation中添加日志,打印实际传入的UUID和ServerID:

Bukkit.getLogger().info("Querying location: UUID=" + uuid.toString() + ", ServerID=" + KaranteeniPlugin.getServerIdentificator());

对比数据库中location表的对应字段,如果大小写不一致,可以统一转为小写后查询:

st.setString(1, uuid.toString().toLowerCase());

4. 再次确认PreparedStatement的参数绑定顺序

虽然你的代码看起来参数顺序是对的(先id,再serverID),但还是建议再核对一次:
SQL语句是 SELECT ... FROM location WHERE id = ? AND serverID = ?;
参数绑定顺序是先id(st.setString(1, uuid.toString())),再serverID(st.setString(2, ...)),确保没有搞反。

5. 排查事务状态影响

如果当前连接处于未提交的事务中,可能导致查询看不到最新数据。可以尝试在查询Location前添加自动提交设置:

conn.setAutoCommit(true);

或者如果之前有手动事务,先提交再执行Location查询。


内容的提问来源于stack exchange,提问作者Nuubles

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:44:24