【问题标题】:Hibernate seems to create wrong SQL Query from HQL QueryHibernate 似乎从 HQL 查询创建了错误的 SQL 查询
【发布时间】:2014-11-11 04:14:30
【问题描述】:

我正在尝试使用执行任何 hql 查询的函数来扩展我的数据库程序。我几乎完成了,但在以下过程中出现错误。

select p.reviews, p.title from Product p

这个 hql 查询在 sql 查询中转换如下:

Hibernate: select . as col_0_0_, product0_.title as col_1_0_, reviews1_.account_number as account_1_2_, reviews1_.product_id as product_2_2_, reviews1_.points as points3_2_, reviews1_.review as review4_2_ from dbprak12.view_product_meta product0_ inner join dbprak12.view_customer_evaluates reviews1_ on product0_.product_id=reviews1_.product_id

如您所见,将抛出 sql 状态代码 42601 的错误。因为“. as col_0_0_...”的语法不正确。但是我不明白为什么hibernate会创建这个sql查询。

我使用以下两个xml映射:

Product.hbm.xml

<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<class name="media.definitions.Product" table="dbprak12.view_product_meta">
  <id name="asin" column="product_id">
     <generator class="native" />
  </id>
  <property name="title" column="title" />
  <property name="avgRating" column="rating" />
  <property name="salesRank" column="sales_rank" />
  <property name="picUrl" column="picture" />
  <set name="reviews" cascade="all" inverse="true" lazy="true">
      <key column="product_id" />
      <one-to-many class="media.definitions.Review" />
   </set>
  <set name="categories" table="dbprak12.view_product_in_category" inverse="false" lazy="true" fetch="select" cascade="all">
     <key column="product_id" />
     <many-to-many column="category_id" class="media.definitions.Category" />
  </set>
  <joined-subclass name="media.definitions.Book" table="dbprak12.view_book">
     <key column="product_id" />
     <property name="isbn" column="isbn" />
     <property name="publishers" column="publisher" />
     <property name="pubDate" column="publication" />
     <property name="pages" column="pages" />
  </joined-subclass>
  <joined-subclass name="media.definitions.DVD" table="dbprak12.view_dvd">
     <key column="product_id" />
     <property name="format" column="fformat" />
     <property name="regionCode" column="region_code" />
     <property name="runningTime" column="running_time" />
  </joined-subclass>
  <joined-subclass name="media.definitions.Music" table="dbprak12.view_cd">
     <key column="product_id" />
     <property name="labels" column="label" />
     <property name="releaseDate" column="release_date" />
  </joined-subclass>
</class>

</hibernate-mapping>

review.hbm.xml

<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<class name="media.definitions.Review" table="dbprak12.view_customer_evaluates">
 <composite-id>
    <key-property name="accountNumber" column="account_number" />
    <key-many-to-one name="product" class="media.definitions.Product" lazy="false">
       <column name="product_id"></column>
    </key-many-to-one>
 </composite-id>
 <property name="rating" column="points" />
 <property name="content" column="review" />
</class>

</hibernate-mapping>

编辑:我的 Hibernate 配置文件: hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>

    <session-factory>
        <property name="hibernate.connection.pool_size">10</property>
        <property name="show_sql">true</property>
        <property name="hibernate.current_session_context_class">thread</property>

        <mapping resource="Product.hbm.xml"/>
        <mapping resource="Category.hbm.xml"/>
        <mapping resource="Review.hbm.xml"/>
        <mapping resource="Person.hbm.xml"/>
        <mapping resource="Offer.hbm.xml"/>

    </session-factory>
</hibernate-configuration>

db2Module.properties

#
# Database module to load
#
middleware.module:media.mediadbimpl.DB2Module

#
# Database properties
#

db.jdbc.dialect:org.hibernate.dialect.DB2Dialect
db.jdbc.driver:com.ibm.db2.jcc.DB2Driver
db.jdbc.url:jdbc:db2://anyurl.de:50001/datasource
db.user:dbuser
db.password:.dbpass.

【问题讨论】:

  • 请同时发布您的hibernate.cfg.xml 文件?
  • 编辑了我的帖子 :) 还有一个属性文件,它只设置连接数据和方言(DB2)
  • 尝试明确声明您正在使用的方言
  • 我已经这样做了。在我的属性文件中声明它
  • 您为什么不简单地选择产品。你会得到你想要的:一系列产品,每个都有一个名字和一组评论:select distinct p from Product p left join fetch p.reviews。当然,它会加载 3 个额外的列,但这可能不会产生明显的差异。

标签: java sql hibernate hql


【解决方案1】:

注意:这不是经过研究的答案,因此可能不正确。

我认为你的错误可能在这里:

<column name="product_id"></column>

我觉得应该是这样的

<column name="product_id" />

在标签中包含正文内容(甚至是 0 个字符)与没有正文内容不同。 (相当于字符串的 "" 和 null)

文档说您可以在键中使用嵌套列元素

<key-many-to-one name="product" class="media.definitions.Product" lazy="false">
   <column name="product_id" />
</key-many-to-one>

但你似乎没有使用它,所以你可以简单地这样做:

<key-many-to-one name="product" class="media.definitions.Product" lazy="false" column="product_id" />

子标签通常用于非标准列。

还是试试吧

【讨论】:

  • 元素很好。那应该不是问题。 OP 没有说明正在使用哪个版本的 Hibernate,但我知道有些旧版本存在标量查询问题,这些查询也检索集合,这正是他在这里用“SELECT p.reviews, p.title"... p.reviews 是一个集合,p.title 是一个标量。
  • @JoshuaDavis 可能值得在答案中制定:)
  • 如果我能理解查询的目标,我会的。获得一个集合和一个标量是一件很奇怪的事情。不妨只获取实体并导航对象图以获得您想要的。尽管我同意您的映射 XML 更好/更清晰,但问题中的映射应该是一样的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-31
  • 2012-02-19
  • 1970-01-01
  • 2016-02-28
  • 1970-01-01
  • 2017-10-01
  • 2020-09-22
相关资源
最近更新 更多