-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Criteria vs. HQL vs. SQL
PostPosted: Sun Aug 27, 2006 2:57 pm 
Newbie

Joined: Tue Apr 18, 2006 9:36 pm
Posts: 6
Location: Los Angeles, CA
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version: Hibernate 3.1

Mapping documents:

Code between sessionFactory.openSession() and session.close():

Full stack trace of any exception that occurs:

Name and version of the database you are using: Oracle 9

The generated SQL (show_sql=true):

Debug level Hibernate log excerpt:

I have a rather complex query that I would LOVE to be able to use Criteria or even HQL for. I have tried several ways to get this to work, but without success. I am joining (and would like it to fetch) 8 tables. I need it to order by fields that are not in the parent class, but in these other tables. I also need to be able to limit the number of rows returned from one of the tables (also not the parent) as well as limit the number coming from the parent.

This is the detail on what I need the query to return. I have two queries at this time. The first query is listed at the end and works exactly how it should. I am able to get back 100 customers based on the fields in the where clause (from different tables).

The main issues are really in the second query. I need to be able to join these 8 tables (fetch) and order by different fields in these additional tables. First, when I use criteria I am able to get back all of the data (it does the fetch correctly), but I can only use order by with the fields in the Customer (parent) table. When I use HQL I am able to order by an of the fields in any of the tables, but even with a fetch join I get a lazy loading, no session found error once I leave the data tier. I am using JUnit for unit testing and it works perfectly in my tests, but when I integrate it into the rest of the application, it will not pull back all of the data. I will only fetch all of the data from the last table joined.

In addition to this limitation is the following business requirement. In the second query the where clause includes all of the Customer Id's from the first query. I need to be able to limit the amount of rows coming back for each customer for one of the tables. Specifically, I want a max of 50 Vehicles per Customer.

Here are the following queries that I have tried (Note: neither of them include the max of 50 vehicles per customer -- as I am at a loss of how to do that with either Criteria or HQL.

Criteria:
Session session = this.getSession();
boolean orderBy = true;
boolean conditionFound = false;
List customerDetail = new ArrayList();
StringBuilder sbQuery = new StringBuilder();

Criteria custDetailCriteria = session.createCriteria(Customer.class);
custDetailCriteria.setFetchMode("customerPostalAddressSet",
FetchMode.JOIN);
custDetailCriteria.setFetchMode(
"customerPostalAddressSet.postalAddress", FetchMode.JOIN);
custDetailCriteria.setFetchMode("customerEmailAddressSet",
FetchMode.JOIN);
custDetailCriteria.setFetchMode("customerPhoneNumberSet",
FetchMode.JOIN);
custDetailCriteria.setFetchMode("customerProductAssociationSet",
FetchMode.JOIN);
custDetailCriteria.setFetchMode(
"customerProductAssociationSet.serializedProduct",
FetchMode.JOIN);

Disjunction disjunction = Restrictions.disjunction();

Iterator iCustomer = customerList.iterator();
while (iCustomer.hasNext())
{
Customer cust = (Customer) iCustomer.next();
Criterion custId = Restrictions.eq("customerId", cust
.getCustomerId());
if (cust.getCustomerId() != null)
{
disjunction.add(custId);
custDetailCriteria.add(disjunction);
}
}
custDetailCriteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

custDetailCriteria.addOrder(Order.asc("firstNm"));
//Unable to addOrder for other tables (i.e. addressLine1 from the address table)

customerDetail = custDetailCriteria.list();

HQL:

sbQuery.append("select distinct c from Customer c ");
sbQuery.append("inner join fetch c.customerPostalAddressSet cpa ");
sbQuery.append("inner join fetch cpa.postalAddress pa ");
sbQuery.append("inner join fetch c.customerPhoneNumberSet cpn ");
sbQuery.append("inner join fetch c.customerEmailAddressSet cea ");
sbQuery.append("inner join fetch c.customerProductAssociationSet cpta ");
sbQuery.append("inner join fetch cpta.serializedProduct sp ");
sbQuery.append("where ");
sbQuery.append("cpn.phoneRole = 'PRIMARY' ");
sbQuery.append("and ");

Iterator iCustomer = customerList.iterator();
int counter = 0;
while (iCustomer.hasNext())
{
Customer cust = (Customer) iCustomer.next();
if (cust.getCustomerId() != null)
{
if (conditionFound)
{
sbQuery.append("or ");
}
sbQuery.append("c.customerId = ? ");
conditionFound = true;
}
}


* Add order by

if (ciDto.getOrderByList() != null && ciDto.getOrderByList().size() > 0)
{
boolean orderByFound = false;
Iterator iOrderBy = ciDto.getOrderByList().iterator();
while (iOrderBy.hasNext())
{
OrderByDto field = (OrderByDto) iOrderBy.next();
if (orderByFound)
{
sbQuery.append(", ");
sbQuery.append(field.getAlias());
sbQuery.append(".");
sbQuery.append(field.getField());
sbQuery.append(" asc");
orderByFound = true;
}
else
{
sbQuery.append("order by ");
sbQuery.append(field.getAlias());
sbQuery.append(".");
sbQuery.append(field.getField());
sbQuery.append(" asc");
orderByFound = true;
}
}
}

Query query = session.createQuery(sbQuery.toString());
Iterator cIterator = customerList.iterator();
int count = 0;
while (cIterator.hasNext())
{
Customer customer = (Customer) cIterator.next();
query.setString(count,
(customer.getCustomerId().toString()));
count++;
}
customerDetail = query.list();*/

Like I stated before I am able to perform the order by without an issue, but I am not able to get back all of the data needed (outside of the test case) and get lazy loading, no session found whenever I try to access the data outside of the data tier.

I really want to be able to use Criteria or HQL for this. Please, please, please help!



*******************************************************
Start first Query
*******************************************************
Session session = this.getSession();
List customerList = new ArrayList();
List returnList = new ArrayList();
boolean conditionFound = false;
StringBuilder sbQuery = new StringBuilder();

sbQuery.append("select distinct c from Customer c ");
sbQuery.append("inner join c.customerPostalAddressSet cpa ");
sbQuery.append("inner join cpa.postalAddress pa ");
sbQuery.append("inner join c.customerPhoneNumberSet cpn ");
sbQuery.append("inner join c.customerEmailAddressSet cea ");
sbQuery.append("inner join c.customerProductAssociationSet cpta ");
sbQuery.append("inner join cpta.serializedProduct sp ");
sbQuery.append("where ");

if (ciDto.getCustomerId() != null
&& !(ciDto.getCustomerId().equals("")))
{
sbQuery.append("c.customerId = :customerId "); //Should this be like? or =?
conditionFound = true;
}
if (ciDto.getOriginalFirstNm() != null
&& !(ciDto.getOriginalFirstNm().equals("")))
{
if (conditionFound)
{
sbQuery.append("and ");
}
sbQuery.append("c.firstNm like :firstNm ");
conditionFound = true;
}
if (ciDto.getOriginalLastNm() != null
&& !(ciDto.getOriginalLastNm().equals("")))
{
if (conditionFound)
{
sbQuery.append("and ");
}
sbQuery.append("c.lastNm like :lastNm ");
conditionFound = true;
}
if (ciDto.getOriginalOrganizationNm() != null
&& !(ciDto.getOriginalOrganizationNm().equals("")))
{
if (conditionFound)
{
sbQuery.append("and ");
}
sbQuery.append("c.organizationNm like :organizationNm ");
conditionFound = true;
}
if (ciDto.getAddressLine1() != null
&& !(ciDto.getAddressLine1().equals("")))
{
if (conditionFound)
{
sbQuery.append("and ");
}
sbQuery.append("pa.addressLine1 = :addressLine1 ");
conditionFound = true;
}
if (ciDto.getCity() != null && !(ciDto.getCity().equals("")))
{
if (conditionFound)
{
sbQuery.append("and ");
}
sbQuery.append("pa.city = :city ");
conditionFound = true;
}
if (ciDto.getStateProvinceCd() != null
&& !(ciDto.getStateProvinceCd().equals("")))
{
if (conditionFound)
{
sbQuery.append("and ");
}
sbQuery.append("pa.stateProvinceCd = :stateProvinceCd ");
conditionFound = true;
}
if (ciDto.getPostalCd() != null && !(ciDto.getPostalCd().equals("")))
{
if (conditionFound)
{
sbQuery.append("and ");
}
sbQuery.append("pa.postalCd = :postalCd ");
conditionFound = true;
}
if (ciDto.getVin() != null && !(ciDto.getVin().equals("")))
{
if (conditionFound)
{
sbQuery.append("and ");
}
sbQuery.append("sp.vin = :vin ");
conditionFound = true;
}
Query query = session.createQuery(sbQuery.toString());
if (ciDto.getCustomerId() != null && !ciDto.getCustomerId().equals(""))
{
query.setString("customerId",
(ciDto.getCustomerId().toUpperCase() + "%"));
}
if (ciDto.getOriginalFirstNm() != null
&& !(ciDto.getOriginalFirstNm().equals("")))
{
query.setString("firstNm", (ciDto.getOriginalFirstNm()
.toUpperCase() + "%"));
}
if (ciDto.getOriginalLastNm() != null
&& !(ciDto.getOriginalLastNm().equals("")))
{
query.setString("lastNm",
(ciDto.getOriginalLastNm().toUpperCase() + "%"));
}
if (ciDto.getOriginalOrganizationNm() != null
&& !(ciDto.getOriginalOrganizationNm().equals("")))
{
query.setString("organizationNm", (ciDto
.getOriginalOrganizationNm().toUpperCase() + "%"));
}
if (ciDto.getAddressLine1() != null
&& !(ciDto.getAddressLine1().equals("")))
{
query.setString("addressLine1", (ciDto.getAddressLine1()
.toUpperCase() + "%"));
}
if (ciDto.getCity() != null && !(ciDto.getCity().equals("")))
{
query.setString("city", (ciDto.getCity().toUpperCase() + "%"));
}
if (ciDto.getStateProvinceCd() != null
&& !(ciDto.getStateProvinceCd().equals("")))
{
query.setString("stateProvinceCd", (ciDto.getStateProvinceCd()
.toUpperCase() + "%"));
}
if (ciDto.getPostalCd() != null && !(ciDto.getPostalCd().equals("")))
{
query.setString("postalCd",
(ciDto.getPostalCd().toUpperCase() + "%"));
}
if (ciDto.getVin() != null && !(ciDto.getVin().equals("")))
{
query.setString("vin", (ciDto.getVin().toUpperCase() + "%"));
}

query.setMaxResults(100);
customerList = query.list();
*******************************************************
End first Query
*******************************************************
Problems with Session and transaction handling?

Read this: http://hibernate.org/42.html


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.