【问题标题】:Hibernate returns list of nulls although executed SQL returns values尽管执行的 SQL 返回值,但 Hibernate 返回空值列表
【发布时间】:2014-07-09 15:34:53
【问题描述】:

我正在使用休眠作为 ORMapper。我想执行一个实际上相当简单的 hql 查询:

SELECT a 
FROM Foo a 
WHERE a.status = :A0status 
ORDER BY a.bookingTypeCode ASC, 
         a.priority ASC

这个 hql 查询然后被转换成一个看起来像这样的 sql 查询:

select a.* 
from Foo a 
where a.status='A' 
order by a.bookingtypecode ASC, 
         a.priority ASC

当我使用 Oracle SQL Developer 在 oracle 数据库上执行 sql 时,我返回了 17 行。但是,当我执行 hql 查询时(使用 Query 的 list 方法,我得到了一个包含 17 个元素的列表,这些元素都是 null。虽然元素的数量是正确的,但实际上并没有加载一个元素.

这是我创建和执行查询的方式:

// the hql query is stored in the hqlQuery variable;
// the parameter are stored in a Map<String, Object> called params
Query hQuery = hibSession.createQuery(hqlQuery);
for (Entry<String, Object> param : params.entrySet()) {
    String key = param.getKey();
    Object value = param.getValue();
    hQuery.setParameter(key, value);
}

List<?> result = hQuery.list();

有人知道这里可能是什么问题吗?

更新 1

我最近从休眠 3.2 升级到 4.3.5。在升级之前一切正常。升级后出现此错误。

【问题讨论】:

  • 能否请您发布实体 Foo 类。
  • 您是否可能正在查询视图?必须有一个唯一的索引列,hibernate 可以使用它来映射回 Foo 实体的 id 属性。
  • @Zeus 我认为这没有帮助,因为我们不使用标准的休眠实体。它是自制的(几年前),在这里解释起来相当复杂。然而,这不应该是问题。原因在更新的问题中。谢谢
  • @skarist 是的,它可能是一个视图。感谢您的提示,我会检查一下。
  • @skarist 不,我正在从表中选择...

标签: java sql oracle hibernate


【解决方案1】:

我已经将hibernate的Log级别设置为TRACE,发现问题了。这实际上是一个映射/逻辑/数据库错误。主键由两列(根据实体类)组成,其中一列可以为空。但是,主键永远不能为空。因此hibernate总是返回null。

【讨论】:

  • 为我工作,我在我的域类中切换了我需要用 @Id 注释的列,hibernate 正在将 DB 对象映射到其中。在我的情况下,我的表没有主键,但注释仍然导致空值,因为即使在它从数据库查询结果创建的实例中,休眠也不想要空 ID,无论它是否是主键。跨度>
  • 我不得不将日志级别设置为FINEST,就我而言,这是查询的问题。对于任何想知道如何设置日志级别的人stackoverflow.com/a/847121/7769052
【解决方案2】:

如果您没有设置自定义(并且有问题)ResultTransformer,我的第二个最佳猜测是您的调试器在骗您。你的代码是否真的收到了一个 null 列表?

还要确保使用您显示的代码进行测试。太多时候,人们把事情简单化了,而魔鬼在细节中。

【讨论】:

  • 嗨,不,我没有设置自定义 ResultTransformer 并且返回的列表实际上是一个空值列表(因此我得到了 NullPointerException)。此外,我上面发布的 SQL 或多或少完全是由 hibernate 生成的 SQL(我只是通过选择 * 并更改别名来简化它)。
【解决方案3】:

这个错误发生在我身上。 MySQL 查询浏览器可以工作,但在 7 列的休眠中,只有一列总是带有所有空字段。我检查了所有的 ID,它们不为空。错误是在 SQL Native 的构建中。我不得不改变它的写作方式。艾工作了。

SELECT c.idContratoEmprestimo as idContratoEmprestimo,
c.dtOperacao as dataOperacao,
p.cpf as cpf,
p.nome as nome,
(Select count(p2.idParcelaEmprestimo) from EMP_PARCELA p2 where p2.valorPago > 0 and p2.dtPagamento is not null
and p2.idContratoEmprestimo = c.idContratoEmprestimo and p2.mesCompetencia <= '2014-08-01') as parcelasPagas, c.numeroParcelas as numeroParcelas,
pe.valorPago as valorParcela
FROM EMP_CONTRATO c inner join TB_PARTICIPANTE_DADOS_PLANO AS pp on pp.idParticipantePlano = c.idParticipantePlano
inner join TB_PARTICIPANTE as p on p.id = pp.idParticipante
inner join TB_PARTICIPANTE_INSTITUIDOR as pi on pi.PARTICIPANTE_ID = p.id
inner join EMP_PARCELA as pe on pe.idContratoEmprestimo = c.idContratoEmprestimo
where c.dtInicioContrato <= '2014-08-01' and pi.INSTITUIDOR_ID = 1
and c.avaliado is true
and pe.mesCompetencia = '2014-08-01'
and c.deferido is true
and c.dtQuitacao is null
and c.dtExclusao is null
and pe.valorPago is not null
group by c.idContratoEmprestimo
order by p.nome

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-25
    • 2017-12-01
    • 1970-01-01
    • 2020-08-04
    • 1970-01-01
    • 2021-03-18
    • 2017-06-05
    • 2023-04-11
    相关资源
    最近更新 更多