【问题标题】:Getting null pointer exception while mapping the jooq record into an object将jooq记录映射到对象时出现空指针异常
【发布时间】:2019-09-19 01:25:47
【问题描述】:

我有几个 JOOQ 存储库,它们从 Postgres DB 获取数据并将数据作为值对象提供。我使用的是 JOOQ 3.10.7,一切正常。我已将我的 spring-boot 版本从 2.0.3 升级到 2.1.4,从而将 JOOQ 版本升级到 3.11.10。我在映射 Jooq 记录时开始收到 NullPointerException。

    try {
       record = jooq.build()
            .select(user.name)
            .where(user.id.eq(1))
            .fetchSingle();
    } catch (NoDataFoundException e) {
      return null;
    }
    return record.into(String.class);

在上述场景中,当没有与给定条件(user.id.eq(1))匹配的记录时,fetchSingle 必须抛出 NoDataFoundException。但根据我的观察,这不是抛出异常,而是返回一个记录对象,其字段为(user.name),值为“null”。这是预期的吗?我尝试使用fetchOne().into(String.class),但同样的问题仍然存在。

这是我的 JOOQ 配置类。

public class JooQJdbcImpl implements Jooq {

private final Settings defaultSettings = new Settings()
    .withRenderNameStyle(RenderNameStyle.AS_IS);

private final RecordMapperProvider recordMapperProvider = new DefaultRecordMapperProvider();

@Autowired
DataSource dataSource;

@Override
public DSLContext build() {
    return withSettings(defaultSettings);
}

@Override
public DSLContext withSettings(Settings settings) {
    final Configuration configuration = new DefaultConfiguration()
        .set(SQLDialect.POSTGRES_9_5)
        .set(dataSource)
        .set(recordMapperProvider)
        .set(settings);
    return DSL.using(configuration);
}

}

【问题讨论】:

  • 为什么要指定RecordMapperProvider
  • private final RecordMapperProvider recordMapperProvider = new DefaultRecordMapperProvider(); 提供默认记录映射器提供程序是问题所在。如果我们不指定任何内容,则配置将采用默认记录映射器提供程序。我希望在最近的版本中,DefaultConfiguration 类中的 RecordMapper 发生了一些变化,这会破坏我的代码
  • 对不起,我不确定我是否关注。你能具体点吗?您的示例中是否存在特定错误?如果是这样,您介意在此处报告吗:github.com/jOOQ/jOOQ/issues/new

标签: postgresql spring-boot jooq


【解决方案1】:

一般情况下,您可以使用fetchOneInto(String.class),这样可以在没有找到记录时阻止NPE。

但是根据我的观察,这不是抛出异常,而是返回一个记录对象,该对象的字段为(user.name),值为“null”。这是预期的吗?

是的,这是意料之中的。当您调用into(String.class) 时,这将尝试找到最合适的String 构造函数并使用字符串参数调用它,在这种情况下,您实际上是在调用new String(null),这是不可能的。

不过,您不必依赖这种行为。只需致电:

return jooq.build()
        .select(user.name)
        .where(user.id.eq(1))
        .fetchOne(user.name);

【讨论】:

  • 感谢@Lukas-eder。但是我仍然有疑问,当数据库中没有匹配的记录时,为什么作为查询执行结果的 JOOQ 记录不为空。文档中提到fetchOne()在没有匹配记录时会返回null
  • 再观察。即使数据库中有与给定条件匹配的记录,生成的记录对象也包含所选字段的空值,当将该记录映射到相应的值对象时会抛出 NPE。有人遇到类似问题吗?
  • @NageswaraRaOMaridu:如果真的没有记录,这不太可能。你确定吗?
  • 是的@Lukas Eder。我正面临这个奇怪的问题
  • @NageswaraRaOMaridu:好吧,我可以邀请您在github.com/jOOQ/jOOQ/issues/new 报告问题吗?如果可能,请包括 MCVE。这可能取决于一些不容易重现的边缘情况:github.com/jOOQ/jOOQ-mcve
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多