【问题标题】:How do i use reserved table column in hibernate @Formula我如何在休眠@Formula中使用保留表列
【发布时间】:2019-11-13 15:31:03
【问题描述】:

我正在尝试使用作为休眠关键字的列名。 即使有引号,我仍然会遇到错误。

我需要使用@Formula 创建一个子查询。

表如下所示,注意名为“row”的列,我们正在从外部系统查询它,并且无法更改。这就是问题的根源。

CREATE TABLE MyTestTable (
    id int,
    `row` int NOT NULL,
    column1 int NOT NULL DEFAULT 0,
    column2 int NOT NULL DEFAULT 0,
    PRIMARY KEY(id, `row`)
);

实体类如下所示:

@Entity
public class MyTestTable implements Serializable {
    @Id
    private int id;

    @Id
    @Column(name = "[row]")
    private int row;

    @Formula("select o.column1 + o.column2" +
            " from MyTestTable o where o.row = `row` AND o.id = id")
    private int calculatedSum;

    ... getters and setters
}

(calculatedSum 在现实世界中使用了 20+ 列)

当试图获取计算和的值时,我得到了错误:

SQL 语句中的语法错误 "select select o.column1 + o.column2 from MyTestTable o where o.row[*] = mytesttabl0_.""row"" AND o.id = mytesttabl0_.id as col_0_0_ from MyTestTable mytesttabl0_ where mytesttabl0_.id=1 和 mytesttabl0_.""row""=1 限制?";预期的“标识符”;

这里的问题是,由于 row 是保留关键字,因此查询最终会给出语法错误(在 o.row 中)。 这就是您认为在其周围添加引号将是解决方案的地方。

@Formula("select o.column1 + o.column2" +
            " from MyTestTable o where `o.row` = `row` AND o.id = id")
    private int calculatedSum;

但这又产生了另一个错误:

16:18:30.547 [main] 错误 org.hibernate.engine.jdbc.spi.SqlExceptionHelper - 未找到列“mytesttabl0_.o.row”; SQL 语句: select select o.column1 + o.column2 from MyTestTable o where mytesttabl0_."o.row" = mytesttabl0_."row" AND o.id = mytesttabl0_.id as col_0_0_ from MyTestTable mytesttabl0_ where mytesttabl0_.id=1 and mytesttabl0_."row "=1 限制? [42122-199]

现在 o.row 的前缀是一个额外的别名,给我 mytesttabl0_.o.row 应该只是 o.row

在这种情况下如何编写对 MyTestTable.row 的工作引用?

【问题讨论】:

  • 你的底层 SQL 数据库是什么(例如 MySQL、SQL Server、Oracle、Postgres 等)?
  • 单元测试在 H2 上,生产在 MySQL 上。如果我们能在单元测试中得到这个通过,那就把它标记为答案。
  • 顺便说一句,使用两个不同的数据库进行测试和开发通常是个坏主意。因此,您可能只想在任何地方使用 MySQL。我怀疑在某些情况下您并没有真正进行单元测试,而是进行 集成 测试,实际上是在内存中运行 H2 数据库。
  • 理想情况下,这将是要走的路,但我还没有想出一种方法来运行 MySQL 作为内存数据库进行测试。确实,我们应该将这些称为集成测试,而不是单元测试。我认为这些术语可能有点混杂。

标签: hibernate hql


【解决方案1】:

根据this 接受的答案,@Formula 中出现的内容必须是有效的 SQL 片段,并且不能引用类中的任何字段;您只能参考 SQL 列和表。假设您只想让 Hibernate 使用 column1column2 的总和填充 calculatedSum 字段,您应该使用:

@Formula(" column1 + column2 ")
private int calculatedSum;

【讨论】:

  • 干得好,先生!似乎我把事情复杂化了,主键上的匹配是不必要的。
  • 是的......所以问题是,您使用的逻辑似乎只是确保总和使用当前实体中的值,但 @Formula 已经为您处理了这个。跨度>
  • 是的,我认为如果它们已经通过字段映射到实体类中,则只能这样引用它们。
猜你喜欢
  • 2012-09-01
  • 1970-01-01
  • 2014-05-04
  • 2011-12-11
  • 1970-01-01
  • 2014-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多