Hibernate 继承和 HQL
Posted
技术标签:
【中文标题】Hibernate 继承和 HQL【英文标题】:Hibernate inheritance and HQL 【发布时间】:2010-09-22 06:56:09 【问题描述】:我在 Hibernate 中继承了 Connection 是我的父实体,MobilePhoneConnection 是扩展实体。我为继承映射使用每个子类策略一个表。这是我的文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping schema="billing_cms" default-lazy="false" default-cascade="all">
<class name="edu.etf.fuzzy.billingcms.domain.model.Connection"
table="base_connection">
<id name="ID" type="integer" column="id" access="field">
<generator class="increment" />
</id>
<property name="contractStartDate" type="date" column="contract_start_date"
not-null="true" />
<property name="contractEndDate" type="date" column="contract_end_date" />
<property name="contractNumber" type="string" column="contract_number" not-null="true" unique="true"/>
<property name="description" type="string" column="description" />
<property name="creationDate" not-null="true" type="date"
column="date_created" />
<property name="createdBy" type="string" column="created_by" />
<property name="lastUpdatedBy" type="string" column="last_updated_by" />
<property name="lastUpdateDate" type="date" column="last_modification_date" />
<property name="isDeleted" not-null="true" type="boolean"
column="deleted_indicator" />
<property name="isFunctioning" type="boolean"
column="functioning_indicator" />
<property name="assignedUser" type="string" column="assigned_user" />
<many-to-one name="administrativeCenter"
class="edu.etf.fuzzy.billingcms.domain.model.AdministrativeCenter"
column="administrative_center_id"/>
<list name="bills" cascade="all">
<key column="connection_id" />
<index column="idx"></index>
<one-to-many class="edu.etf.fuzzy.billingcms.domain.model.Bill" />
</list>
<joined-subclass name="edu.etf.fuzzy.billingcms.domain.model.MobilePhoneConnection"
table="mobile_phone_connection">
<key column="id"/>
<property name="operator" type="string" column="operator" not-null="true"/>
<property name="userCode" type="string" column="user_code"/>
<property name="packetName" type="string" column="packet_name" not-null="true"/>
<property name="monthExpenseLimit" type="integer" column="month_expense_limit" not-null="true"/>
<property name="isPrepaid" type="boolean" column="is_prepaid" not-null="true"/>
<property name="lineNumber" type="string" column="line_number" not-null="true"/>
<property name="hasGPRS" type="boolean" column="gprs"/>
<property name="hasUMTS" type="boolean" column="umts"/>
<property name="hasEDGE" type="boolean" column="edge"/>
</joined-subclass>
<joined-subclass name="edu.etf.fuzzy.billingcms.domain.model.PSTNConnection"
table="pstn_connection">
<key column="id"/>
<property name="operator" type="string" column="operator" not-null="true"/>
<property name="userCode" type="string" column="user_code"/>
<property name="lineNumber" type="string" column="line_number" not-null="true"/>
<property name="monthExpenseLimit" type="integer" column="month_expense_limit"/>
<property name="isLocalLoop" type="boolean" column="is_local_loop" not-null="true"/>
</joined-subclass>
<joined-subclass name="edu.etf.fuzzy.billingcms.domain.model.InternetConnection"
table="internet_connection">
<key column="id"/>
<property name="provider" type="string" column="provider" not-null="true"/>
<property name="userCode" type="string" column="user_code"/>
<property name="packetName" type="string" column="packet_name" not-null="true"/>
<property name="linkThroughput" type="string" column="link_throughput" not-null="true"/>
<property name="downloadCapacity" type="string" column="download_capacity" not-null="true"/>
<property name="uploadCapacity" type="string" column="upload_capacity" not-null="true"/>
</joined-subclass>
<joined-subclass name="edu.etf.fuzzy.billingcms.domain.model.OuterConnection"
table="outer_connection">
<key column="id"/>
<property name="fromLocation" type="string" column="from_location" not-null="true"/>
<property name="toLocation" type="string" column="to_location" not-null="true"/>
<property name="userCode" type="string" column="user_code"/>
<property name="lineNumber" type="string" column="line_number"/>
<property name="monthExpenseLimit" type="integer" column="month_expense_limit" not-null="true"/>
<property name="capacity" type="string" column="capacity"/>
</joined-subclass>
</class>
<query name="getMobileConnectionByLineNumber">
<![CDATA[from MobilePhoneConnection mb where mb.lineNumber = :lineNumber]]>
</query>
</hibernate-mapping>
我的问题是如何使用 WHERE 子句在 MobilePhoneConnection 上编写 HQL 查询来检查继承属性之一(来自 Connection 的contractStartDate)?我猜我需要某种连接,但不知道如何完成这个?我想查看天气 MobilePhoneConnection 合同开始日期是在某个特定日期之前还是之后...
【问题讨论】:
【参考方案1】:我觉得就这么简单:
var query = session.CreateQuery ("from MobilePhoneConnection where contractStartDate > :p_date");
上述查询应该只返回其 contractStartDate 大于给定日期(参数)的 MobilePhoneConnection 实例。 Hibernate 应该足够聪明地找出 SQL 语句,以便只检索代表 MobilePhoneConnections 的记录。
【讨论】:
【参考方案2】:这是我真正想要的,并通过使用 .class 选项设法得到它:
from Connection c where c.contractStartDate < :afterdate and c.contractStartDate > :beforeDate and c.class = MobilePhoneConnection
当必须使用别名时,这可能很有用,但似乎 Frederik Gheysels 的解决方案也有效。第一次对我不起作用的是:
from MobilePhoneConnection mb where mb.contractStartDate < current_date
它会这样抱怨: 2010-09-22 10:56:19,495 错误主 org.hibernate.hql.PARSER - :1:72: 意外的 AST 节点:contractStartDate
【讨论】:
以上是关于Hibernate 继承和 HQL的主要内容,如果未能解决你的问题,请参考以下文章
如何将继承策略与 JPA 注释和 Hibernate 混合使用?