【问题标题】:Hibernate SQLQuery with transient properties具有瞬态属性的休眠 SQLQuery
【发布时间】:2013-12-07 00:23:17
【问题描述】:

我需要用 db2 创建一个休眠 SQLQuery,这个查询返回了一些经过计算的字段,这些字段与数据库中的任何列都没有关系。

目标是将 SQLQuery 中这些 sum() 计算的值设置在已存在的 Java 对象中的三个新瞬态字段上。

SQLQuery 使用语法:

SELECT id as {entityObject.id},
           name as {entityObject.name},
           order as {entityObject.order},
           SUM(CASE
           WHEN pv.value_id = 1 
            AND pv.value=1 THEN 1 ELSE 0 END) AS {entityObject.someCount}

问题是 Hibernate 抱怨说需要为 someCount 提供一个列。似乎没有帮助将 java 字段声明为 transient 甚至使用 javax.persistence 中的 @Transient 注释同时。

如果我只在hbm.xml映射文件中声明:

<property name="id" type="java.lang.Integer" column="someColumn" />
<!-- Some more fields here -->

<!-- THE IMPORTANT ONE -->
<property name="someCount" type="java.lang.Integer"/>

Java 对象:

public class EntityObject implements Serializable {

private static final long serialVersionUID = 1479579608940145961L;

private Integer id;
private String name;
private Integer order;

    // This is the one giving me hell. I've tried with @Transient also
private transient Integer someCount;

public Category() {
}

public Category(final String name, final Integer order) {
    this.name = name;
    this.order = order;
}

public Integer getOrder() {
    return this.order;
}

public void setOrder(final Integer order) {
    this.order = order;
}

public Integer getId() {
    return this.id;
}

public String getName() {
    return this.name;
}

public void setName(final String name) {
    this.name = name;
}


public Integer getSomeCount() {
    return someCount;
}

public void setSomeCount(final Integer count) {
    this.someCount = count;
}


}

它要求我提供一个列,我尝试插入一个假列,但它不起作用。问题是我希望这些“计数”字段仅从 SQLQuery 设置,并且在来自常规 Hibernate 查询时为空和 null。

我查看了文档并用谷歌搜索,似乎您可以通过仅不在休眠映射文件中声明它来声明一个瞬态字段,但随后它不会在具有“as {entityObject. someCount}" 即使我声明了 getter/setter。

请帮忙。 提前非常感谢。

【问题讨论】:

  • Hibernate 不会“看到”瞬态字段。在查询返回后,您必须进行聚合查询并将结果放在代码中的字段中。
  • 首先,谢谢。其次,¿如果我不能将它们直接从 SQLQuery 映射到对象,我该如何获取这些值?

标签: java sql hibernate hibernate-mapping


【解决方案1】:

可以直接从数据库执行所有这些操作而无需发出其他查询的唯一可用选项是 Hibernate 公式属性:

http://wiki.jrapid.com/w/Formula_(attribute_of_property)

<property name="someCount" formula="select count(*) from some_table where table_key = ?"/>

那个?占位符将自动填充当前实例的 ID。

【讨论】:

  • 谢谢,我想过这个,但我需要在 sql 查询中这样做以提高效率以及与风格等相关的公司规则。
【解决方案2】:

1 创建 POJO:

public class SumValue{
   private BigInteger myId; 
   private String myName;
   private BigInteger myOrder;
   private BigInteger mySum;
   ....
   getters and setters here
   ....
}

2 查询中的细微变化

SELECT id as "myId",
       name as "myName",
       order as "myOrder",
       SUM(CASE
       WHEN pv.value_id = 1 
        AND pv.value=1 THEN 1 ELSE 0 END) AS "mySum"

3 执行原生sql

     List<SumValue> jobStateViewList = (List<SumValue>)getSessionFactory().getCurrentSession()
                                   .createSQLQuery(yourQuery)
                                   .setResultTransformer(
                                        new AliasToBeanResultTransformer(SumValue.class)
                                   ).list();

【讨论】:

  • 嗯嗯嗯,恐怕我自己解释得不好。我正在编辑主要问题。但我提前向您解释...只有一个 Java 对象具有三个聚合字段,就像我发布的那个一样,还有另一个字段照常映射。如果我错了,请告诉我,但您的解决方案仅在仅包含一个值的 POJO 上设置值。我希望所有检索到的值都在同一个对象中。我刚刚通过编辑最初的帖子来澄清这一点。对此感到抱歉。
  • 我在您的帖子中没有看到任何 Java 对象。从您的 sql 查询中,我了解到您需要将 sql 返回的总和值转换为对象。因此,请再次向我展示您要使用 sql 查询中的数据填充的对象。
  • 我想现在已经完成了。对于给您带来的不便,我们深表歉意。
  • 我编辑了我的帖子。我也有一个问题。您是否将 EntityObject 映射为 Hibernate 实体?
  • 是的,我做到了。我现在正在处理其他一些更高优先级的任务。我稍后会回来。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-03
相关资源
最近更新 更多