2011-04-16 44 views
14

我用下面的查询来获取与指数idtextobject一个java.util.Map如何逃脱保留字在Hibernate的HQL

Query q = mySession.createQuery(
    "SELECT u.id AS id, u.name AS text, u AS object FROM User u") 
    .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); 

...但object似乎是一个保留字。例如obj即可。目前在HQL中使用反斜杠转义的方式逃脱别名的方式是什么?

使用反引号提供了以下错误:

Exception in thread "main" org.hibernate.QueryException: unexpected char: 
'`' [SELECT u.id AS id, u.name AS text, u AS `object` FROM User u] 

回答

10

你可以使用自定义“的别名,以图”变压器,因此您的代码将变为像这样

Query q = mySession.createQuery(
    "SELECT u.id AS id, u.name AS text, u AS obj FROM User u") 
    .setResultTransformer(
     AliasToMapTransformer.renameAlias("obj", "object").build() 
    ); 

,然后使用这个类的一个解决方法实现它:

public class AliasToMapTransformer extends BasicTransformerAdapter { 

    private Map<String, String> renameAliasMap; 


    public AliasToMapTransformer(Map<String, String> renameAliasMap) { 
     this.renameAliasMap = (renameAliasMap == null) ? Collections.<String, String>emptyMap() : renameAliasMap; 
    } 


    @Override 
    public Object transformTuple(Object[] tuple, String[] aliases) { 
     Map<String, Object> result = new HashMap<String, Object>(tuple.length); 
     for (int i = 0; i < tuple.length; i++) { 
      String alias = aliases[i]; 
      if (alias != null) { 
       String newAlias = renameAliasMap.get(alias); 

       result.put((newAlias != null) ? newAlias : alias, tuple[i]); 
      } 
     } 
     return result; 
    } 


    public static Builder renameAlias(String alias, String newAlias) { 
     return new Builder().renameAlias(alias, newAlias); 
    } 


    public static class Builder { 

     private Map<String, String> aliasConversionMap = new HashMap<String, String>(); 


     public Builder renameAlias(String alias, String newAlias) { 
      aliasConversionMap.put(alias, newAlias); 
      return this; 
     } 


     public AliasToMapTransformer build() { 
      return new AliasToMapTransformer(aliasConversionMap); 
     } 
    } 
} 
+0

感谢这是迄今为止最好的解决方案。 – vbence 2011-04-22 18:01:39

+0

这只适用于以非常特定的方式选择名称。如果你想解决写在“where”子句或其他地方的关键字怎么办? – 2012-11-19 22:29:59

0

不要反引号不是别名工作? Hibernate documentation说他们用于领域。

其他问题:

  • 是另一种价值可能吗?
  • 为什么地图(它也包含原始值)而不是列表? 可以从原始对象中检索Id和Name。
+0

我试过了。他们惊人地不能在查询中工作。我想使用map,因为它非常易于使用,并且数据被输入到其他API。 – vbence 2011-04-16 14:03:58

2

后抽动概念作品在休眠..可惜这只是作品,如果你已经做了注解配置...

你可以尝试这样做以不同的方式(不包括注释)。

Query q = session.createQuery("select new User (u.id, u.name, u.object) from User u").list(); 

在这里你需要创建使用构造函数接受一个I​​D,名称,顺序对象元素&。

+0

Backtics也可以在XML映射文件中使用。但我想在HQL中转义。别名的主要观点是它们可以任意分配。我使用'Map'作为系统解耦部分之间的最小公分母。只要他们工作,它将非常方便。 – vbence 2011-04-17 09:06:27

5

在相关主题上,转义列名中的保留字就像预先使用表别名一样容易。无反引号,括号,等只需更换

select where from mytable 

由:

select t.where from mytable t 

(注:我不是说这是一个好主意,有“里”为列名;-)