【发布时间】:2020-12-14 21:14:52
【问题描述】:
我想复制一个在 MySQL 和 H2 中都能正常运行的查询:
SELECT
pedido_linha.produto_id AS material,
COALESCE(pedido_linha.unidade_medida_id, "UN") AS uom,
pedido_linha.data_pedido AS referenceDate,
SUM(COALESCE(pedido_linha.quantidade, 0)) AS totalQuantity,
SUM(COALESCE(pedido_linha.valor_total, 0)) AS totalGross,
SUM(COALESCE(pedido_linha.valor_total, 0) - COALESCE(pedido_linha.valor_descontos, 0) -
COALESCE(pedido_linha.valor_impostos, 0)) AS totalNet,
SUM(COALESCE(pedido_linha.valor_custo, 0)) AS totalCogs
FROM pedido_linha
GROUP BY pedido_linha.produto_id, pedido_linha.data_pedido, COALESCE(pedido_linha.unidade_medida_id, "UN");
例如,查询在 MySQL 中运行良好,即使某些 Group By 字段为空:
已尝试在 JPA 封闭投影中提取分组结果:
public interface AggregatedByMaterialUOMDate {
Produto getMaterial();
UnidadeMedida getUom();
LocalDate getReferenceDate();
Float getTotalQuantity();
Float getTotalGross();
Float getTotalNet();
Float getTotalCogs();
}
连同存储库查询:
@Repository
public interface PedidoLinhaRepository extends JpaRepository<PedidoLinha, PedidoLinha.PedidoLinhaCompositeKey> {
@Query("SELECT pl.produto AS material, "
+ "COALESCE(pl.unidadeMedida, :unidadeMedidaPadrao) AS uom, "
+ "pl.dataPedido AS referenceDate, "
+ "SUM(COALESCE(pl.quantidade, 0)) AS totalQuantity, "
+ "SUM(COALESCE(pl.valorTotal, 0)) AS totalGross, "
+ "SUM(COALESCE(pl.valorTotal, 0) - COALESCE(pl.valorDescontos, 0) - COALESCE(pl.valorImpostos, 0)) AS totalNet, "
+ "SUM(COALESCE(pl.valorCusto, 0)) AS totalCogs "
+ "FROM PedidoLinha pl "
+ "GROUP BY pl.produto, pl.dataPedido, COALESCE(pl.unidadeMedida, :unidadeMedidaPadrao)")
List<AggregatedByMaterialUOMDate> consolidatedSelloutByMaterialUOMDayAtLocation(@Param("unidadeMedidaPadrao") UnidadeMedida unidadeMedidaPadrao);
}
上面的 JPQL 查询返回一个包含 0 个元素的列表,因此与前面显示的本机查询不一致。
我们尝试将 COALESCE(pl.unidadeMedida, :unidadeMedidaPadrao) 更改为简单的 pl.unidadeMedida(在 SELECT 和 GROUP BY 子句中),但没有成功。
只有在从两个子句中完全删除对 pl.unidadeMedida 的所有引用时,查询才能成功返回所有值。
下面是 PedidoLinha(在查询中由 pl 引用)类的示例,显示了对 UnidadeMedida 的引用:
@Getter
@Setter
@NoArgsConstructor
@RequiredArgsConstructor
@EqualsAndHashCode(of = "pedidoLinhaCompositeKey")
@Entity
public class PedidoLinha {
@EmbeddedId
@NonNull // torna campo obrigatório e parâmetro do construtor gerado pelo @Data (lombok)
private PedidoLinhaCompositeKey pedidoLinhaCompositeKey;
@Data // lombok: @ToString, @EqualsAndHashCode, @Getter on all fields @Setter on all non-final fields, and @RequiredArgsConstructor
@NoArgsConstructor
@RequiredArgsConstructor
@Embeddable
@EqualsAndHashCode
public static class PedidoLinhaCompositeKey implements Serializable {
@NonNull // torna campo obrigatório e parâmetro do construtor gerado pelo @Data (lombok)
private String id;
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@NonNull // torna campo obrigatório e parâmetro do construtor gerado pelo @Data (lombok)
private Pedido pedido;
}
@ManyToOne(optional = false)
private Produto produto;
@ManyToOne
private UnidadeMedida unidadeMedida;
public UnidadeMedida getUnidadeMedida() {
return (unidadeMedida == null) ? new UnidadeMedida("UN") : unidadeMedida;
}
// rest of the entity code
}
UnidadeMedida 课程
@Getter
@Setter
@EqualsAndHashCode(of = "id")
@NoArgsConstructor
@Entity
public class UnidadeMedida {
@Id
private String id;
private String descricao;
public UnidadeMedida(String id) {
this.id = id;
}
}
会发生什么?我相信这可能是一个 Hibernate 错误,但找不到任何关于此问题的参考。
【问题讨论】:
-
能否请您出示
UnidadeMedida班级。 -
我已经包含了这个类:我们在所有实体中都使用了 Lombok,到目前为止没有任何问题。刚试过包括@AllArgsConstructor,没有效果
-
如果您希望有人帮助您,您需要提供所有必需的信息。未提供以下定义:
Producto、Pedido等// rest of the entity code之类的评论无济于事。一个想要帮助你的人需要自己创造一些东西,并且可能会错过一些重要的细节。 -
@dotore,感谢您的提示。最后,问题与依赖实体无关,而是与 JPQL 查询转换为 SQL 代码的方式有关
标签: spring hibernate spring-data-jpa spring-data