I'm trying to do a search for the nearest zip code that a sales rep is responsible for to the zip code entered by the user. I've got 3 tables, one with the sales reps, one with zips and then a join table for zips that are owned by reps. The problem I'm having is figuring out how to use the calculation in the order by clause.
What I've done is create an additional mapping class for the join table to make the query easier. So, what I have is just "select salesRepZip.salesRep, {salesRepZip.zipCode distance calcuation} as distance from SalesRepZips". That gives me the sales rep and how far they are from any of the zip codes that are assigned to them. But now I want to add an "order by distance" clause but in the generated sql it uses the name "distance" directly, rather than the identifier Hibernate generates for the calculation. Is there any way to use the calculation in the order by clause? Or is there a better way to do this query?
Thanks,
Rich
Hibernate version:
3.2
Mapping documents:
Code:
<hibernate-mapping>
<class name="com.contentconnections.spikes.SalesRepZip"
table="sales_rep_zips">
<composite-id>
<key-property name="zipCodeNumber" column="zipCode" />
<key-property name="salesRepUid" column="uid" />
</composite-id>
<many-to-one name="zipCode"
class="com.contentconnections.spikes.ZipCode" column="zipCode"
insert="false" update="false" />
<many-to-one name="salesRep"
class="com.contentconnections.spikes.SalesRep" column="uid"
insert="false" update="false" />
</class>
</hibernate-mapping>
<hibernate-mapping>
<class
name="com.contentconnections.spikes.SalesRep"
table="sales_reps">
<id name="uid" column="uid">
<generator class="native" />
</id>
<property name="name" />
<set name="zipCodes" table="sales_rep_zips">
<key column="zipCode" foreign-key="fk_sales_rep_zips_zip" />
<many-to-many column="uid" class="com.contentconnections.spikes.SalesRep" foreign-key="fk_sales_rep_zips_sales_rep"/>
</set>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class
name="com.contentconnections.spikes.ZipCode"
table="zip_codes">
<id name="zipCode" column="zipCode">
<generator class="assigned" />
</id>
<property name="latitude" />
<property name="longitude" />
</class>
</hibernate-mapping>
Code between sessionFactory.openSession()Code:
Query query = getCurrentSession ().createQuery ("select salesRepZip.salesRep, degrees(acos(sin(radians(:searchLat)) * sin(radians(salesRepZip.zipCode.latitude)) + cos(radians(:searchLat))*cos(radians(salesRepZip.zipCode.latitude))*cos(radians(:searchLong - salesRepZip.zipCode.longitude))))*69.1 as distance from SalesRepZip salesRepZip order by distance");
query.setFloat ("searchLat", zip.getLatitude ());
query.setFloat ("searchLong", zip.getLongitude());
List list = query.list ();
for (Object o : list) {
Object[] row = (Object[]) o;
System.out.println (row[0]);
System.out.println (row[1]);
System.out.println ();
}
The generated SQL (show_sql=true):Code:
select salesrepzi0_.uid as col_0_0_, degrees(acos(sin(radians(?))*sin(radians(zipcode2_.latitude))+cos(radians(?))*cos(radians(zipcode2_.latitude))*cos(radians(?-zipcode2_.longitude))))*69.1 as col_1_0_, salesrep1_.uid as uid7_, salesrep1_.name as name7_ from sales_rep_zips salesrepzi0_ inner join sales_reps salesrep1_ on salesrepzi0_.uid=salesrep1_.uid, zip_codes zipcode2_ where salesrepzi0_.zipCode=zipcode2_.zipCode order by distance