【问题标题】:hibernate derived properties with xml使用 xml 休眠派生属性
【发布时间】:2015-02-07 13:57:54
【问题描述】:

我有一个名为 Student 的表格,如下所示

ID        NAME     DOB
---       ----     ---------
1         A        2009-01-28
2         B        2001-05-20

我正在使用派生属性从 hbm 文件中的 dob 获取 AGE,如下所示

<hibernate-mapping>
<class name="com.arat.derived.Person" table="person" catalog="spring_db">
    <id name="id" type="int">
        <column name="id" />
        <generator class="assigned" />
    </id>
    <property name="name" type="string">
        <column name="name" />
    </property>
    <property name="dob" type="date">
        <column name="dob" length="0" />
    </property>
    <property name="age" type="integer" column="AGE"
        formula="( select TIMESTAMPDIFF(YEAR,p.dob,NOW()) as AGE 
                     from person p where p.ID=ID)"></property>
  </class>
</hibernate-mapping>

我的 POJO 类 Student 具有所有属性 id、name、dob 和 age 以及 setter 和 getter 方法。

使用 load 或 get 方法获取数据时出现错误

 private static void loadPerson() {
    Session session = factory.openSession();
    Person person = (Person) session.get(Person.class, 0);
    System.out.println("Person : name " + person.getName() 
            + ", dob: " + person.getDob() + ", age : " + person.getAge());

}

Hibernate: 选择 person0_.id 作为 id1_8_0_, person0_.name 作为 name2_8_0_, person0_.dob 作为 dob3_8_0_, ( select TIMESTAMPDIFF(person0_.YEAR,p.dob,NOW()) as person0_.AGE from person p where p. ID=person0_.ID) as formula0_0_ from spring_db.person person0_ where person0_.id=? 2015 年 2 月 7 日晚上 7:20:22 org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions 警告:SQL 错误:1064,SQLState:42000 2015 年 2 月 7 日晚上 7:20:22 org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions 错误:您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 1 行使用 'person0_.YEAR,p.dob,NOW()) as person0_.AGE from person p where p.ID=person0_.ID)' 附近的正确语法 2015 年 2 月 7 日晚上 7:20:22 org.hibernate.event.internal.DefaultLoadEventListener onLoad 信息:HHH000327:执行加载命令时出错:org.hibernate.exception.SQLGrammarException:无法提取 ResultSe**

你能告诉我哪里错了吗?

【问题讨论】:

    标签: hibernate nhibernate-mapping derived


    【解决方案1】:

    这是一个有趣的问题,与 Hibernate 方式如何处理formula="" SQL sn-p 有关。

    幕后发生的事情是:

    使用表alias 意外注入/扩展formula="" 部分

    这意味着:

    formula="( select TIMESTAMPDIFF(YEAR, p.dob, NOW()) 
                   as AGE from person p where p.ID = ID )"
    

    被转换成那个:

    ( select TIMESTAMPDIFF(person0_.YEAR,p.dob,NOW()) 
          as person0_.AGE  from person p where p.ID=person0_.ID)
    

    首先我们要改变的是as AGE,它不是必需的,也是扩展的。

    formula="( select TIMESTAMPDIFF(YEAR, p.dob, NOW()) 
                from person p where p.ID = ID )"
    

    下一步 - 别名 person0_ 现在用于比我们需要的更多部分。

    原因是:

    Hibernate不知道,哪些部分是

    • 我们的数据库引擎的原生 SQL 词/关键字
    • 它们是列/属性名称。

    解决的办法,就是扩展方言,教它new关键字。例如。像这样

    // extend the correct dialect ... in thhis case MySql
    public class CustomMySQLDialect extends MySQL5InnoDBDialect
    {
        public CustomMySQLDialect()
        {
            super();
            registerKeyword("YEAR");
        }
    }
    

    别忘了在配置中使用这个新的方言 - CustomMySQLDialect

    【讨论】:

    • 没有运气,在创建此自定义方言并将此方言添加到 hibernate.cfg.xml 文件中后,它会引发相同的异常。
    • 嗯,它确实对我有用。你确定,你改变了你的配置?现在使用的是新的自定义方言吗?如果是,“YEAR”将是关键字,并且永远不会用别名“扩展”...
    • 我在这里添加了它:&lt;property name="hibernate.dialect"&gt;com.dialect.CustomMySQLDialect&lt;/property&gt;
    • 干得好,但我们还必须调整公式 - 我更新了我的答案。我想说这次你的例外不一样...检查真实的细节...我希望问题出在 AS AGE
    • 删除 as AGE 后也没有运气。
    【解决方案2】:

    这是对 Radim Köhler 的 https://stackoverflow.com/a/28383566/2576551 答案的一个小补充。对于某些休眠版本,自定义方言中的关键字注册似乎区分大小写。我正在运行休眠 4.3.8.Final 并且关键字必须是小写的。

    //doesn't work
    registerKeyword("YEAR");
    
    //works
    registerKeyword("year");
    

    建议使用小写关键字的相关线程Hibernate mapped property to SQL formula fails after update to 3.6.5

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 2021-09-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多