How to implement following multiple inner join in hibernate? - java

I hava query:
Hibernate: select this_.pName as y0_, this_.kNum as y1_, count(*) as y2_ from ALL_CPView this_ inner join ALL_AMView aID1_ on this_.agentid=aID1_.AgentID
and criteria,
Criteria crit = statelessSession.createCriteria(APRecord.class, "apr")
.createAlias("manageID", "ID", Criteria.INNER_JOIN);
crit.setProjection(Projections.projectionList()
.add(Projections.groupProperty("PName"), "PName")
.add(Projections.groupProperty("kNum"), "kNum")
.add(Projections.rowCount() , "count"));
results = crit.setResultTransformer(Transformers.aliasToBean(APStat.class)).list();
How can I add another projection with distinct count for aID with the inner join?

Related

Hibernate, dealing with Criteria and left outer join condition

I've an existing piece of code like follow:
Criteria crit = session.createCriteria(myClass);
crit.createAlias(TAB1, TAB1, JoinType.LEFT_OUTER_JOIN);
crit.createAlias(TAB1 + ".table2", TAB2, JoinType.LEFT_OUTER_JOIN);
crit.add(Restrictions.eq(TAB1 + ".deleted", Boolean.FALSE));
crit.add(Restrictions.eq(TAB2 + ".id", someId));
This "generates" a sql query like follow:
SELECT * FROM myClass this_
LEFT OUTER JOIN TAB1 tab1_ ON this_.id=tab1_.myClass_id
LEFT OUTER JOIN TAB2 tab2_ ON tab1_.tab2_id=tab2_.id
WHERE tab1_.deleted=0
AND tab2_.id = 1234
I need to put filters in the JOIN condition rather than in the WHERE clause.
To be clear, I need to have the following query:
SELECT * FROM myClass this_
LEFT OUTER JOIN TAB1 tab1_ ON this_.id=tab1_.myClass_id AND tab1_.deleted=0
LEFT OUTER JOIN TAB2 tab2_ ON tab1_.tab2_id=tab2_.id AND AND tab2_.id = 1234
How can I do this?
Thanks
You are using:
crit.createAlias(${table}, ${alias}, ${joinType});
You should be able to use:
crit.createAlias(${table}, ${alias}, ${joinType}, ${Criterion});
Although I could not find an example in our codebase, I would expect this to work.
Here is a decent example right from Hibernates confluence page:
public class PersonDao extends HibernateDaoSupport {
public List<Person> findByName() {
Criteria criteria = getSession().createCriteria(Person.class, "p");
criteria.createCriteria("p.names", "names", JoinType.INNER_JOIN, Restrictions.eq("name", "John"));
return criteria.list();
}
}
Produces
select this_.id as y0_ from person this_
inner join debtor_info this_1_ on this_.id=this_1_.id
left outer join person_person_name personname3_ on this_.id=personname3_.person_id and ( name1_.name=? )
left outer join person_name name1_ on personname3_.person_name_id=name1_.id and ( name1_.name=? )
With that example I believe your code should look something like
Criteria crit = session.createCriteria(MyClass.class, "mine");
crit.createAlias("mine.names", "name", JoinType.LEFT_OUTER_JOIN, Restrictions.eq("name", Boolean.FALSE));
crit.createAlias("q.id", "id", JoinType.LEFT_OUTER_JOIN, Restrictions.eq("id", someId));

Data is not ordered correctly with pagination: Sql server and Hibernate 3.6.10

EDIT: the problem is related to the presence of subqueries in the select part of the translated query. This seems to mess with the numbering given by
the pagination.
We recently changed dialect from SqlServerDialect to SqlServer2008Dialect in out hibernate configuration and hibernate it's starting to translate the queries that are paginated with this sql server query:
WITH query AS (select ROW_NUMBER() OVER (order by this_.numero asc) as __hibernate_row_nr__,
this_.id as id834_0_, this_.numero as numero834_0_, this_.ragione_sociale as ragione9_834_0_, this_.anagrafica_fiscale as anagrafica10_834_0_,
this_.partita_iva as partita11_834_0_, this_.codice_fiscale as codice12_834_0_, this_.note as note834_0_, this_.data_prospect_dal as data14_834_0_,
this_.dt_inserimento as dt15_834_0_, this_.dt_modifica as dt16_834_0_, this_.nome as nome834_0_, this_.cognome as cognome834_0_,
this_.dt_nascita as dt19_834_0_, this_.fl_piva_duplicata as fl20_834_0_, this_.mail_cliente as mail21_834_0_, this_.fl_capogruppo as fl22_834_0_,
this_.fk_e2_crm_prospects as fk26_834_0_, this_.fl_duplicato as fl23_834_0_, this_.fl_a_consumo as fl4_834_0_,
this_.codice_importazione as codice24_834_0_, this_.codice_attivita as codice38_834_0_, this_.fk_e0_utente_inserimento as fk5_834_0_,
this_.fk_e0_utente_modifica as fk6_834_0_, this_.fk_e0_prof_nodo as fk7_834_0_, this_.fk_e0_decod_classe_dim_pr as fk27_834_0_,
this_.fk_e0_decod_tipo_prospect as fk28_834_0_, this_.fk_e0_decod_codice_ateco as fk29_834_0_, this_.fk_comune_di_nascita as fk30_834_0_,
this_.fk_e0_decod_gp_ind_com as fk31_834_0_, this_.fk_e0_decod_seg_com as fk32_834_0_, this_.fk_e0_decod_sotto_seg_com as fk33_834_0_,
this_.fk_e0_natura_cliente as fk34_834_0_, this_.fk_e0_nazione_nascita as fk36_834_0_, this_.fk_e0_decod_prov_pros as fk35_834_0_,
this_.fk_e2_com_punto_stradario as fk37_834_0_, replace(replace(replace(this_.ragione_sociale,'.',''),'-',''),' ','') as formula1662_0_,
( select u.user_logged from users u join e2_crm_dett_prospects p on u.id = p.fk_e0_decod_gestore_prospect
where p.fk_e2_crm_prospect = this_.id and p.fk_e0_prof_nodo = this_.fk_e0_prof_nodo) as formula1663_0_,
( select s.descrizione from e0_decod_tipi_stato_prospect s join e2_crm_dett_prospects p on s.id = p.fk_e0_decod_stato_prospect
where p.fk_e2_crm_prospect = this_.id and p.fk_e0_prof_nodo = this_.fk_e0_prof_nodo) as formula1664_0_,
( select i.num_dipendenti from e2_crm_info_camerali_prosp i where i.fk_e2_crm_prospect = this_.id
and i.dt_inserimento = ( select max(p.dt_inserimento)
from e2_crm_info_camerali_prosp p
where p.fk_e2_crm_prospect = this_.id ) ) as formula1665_0_
from e2_crm_prospects this_ where this_.fl_duplicato=? )
SELECT * FROM query WHERE __hibernate_row_nr__ BETWEEN ? AND ?
The problem is that the resulting data is not ordered by the numero column.
Using the old dialect the paginated query was translated with a TOP clause with an ORDER BY numero at the end of the query and the rows where ordered correctly.
The query is build using criteria and ordered and paginated like this:
Criteria criteria = session.createCriteria(ProspectRicerca.class,"padre");
criteria.add(Restrictions.eq(Constant.PROSPECT_FLAG_DUPLICATO, false));
criteria.addOrder(Order.asc("numero"));
criteria.setFirstResult(pageNumber*numElementForPage);
criteria.setMaxResults(numElementForPage);
lista = criteria.list();
The hibernate version is 3.6.10 and we use Sql Server 2008
This is the result of the query executed in sql server, as you can see the rows are not ordered (the __hibernate_row_nr__ column is coherent with the numero column order.

While running Hibernate Criteria, HQL query is not created in given order

While running Hibernate Criteria, HQL query is not created in given order
and shows Exception
ERROR SqlExceptionHelper:131 - Unknown column 'stsup4_.SUPPLIER_ID' in 'on clause'
The Generated HQL is not created in expected order.
When I run the same generated HQL in mysql with some changes, I get output.
Java Code is given Below
Session session = connector.getSession();
Criteria cr = session.createCriteria(ST_PRODUCTMASTER.class, "ST_PRODUCT");
cr.createCriteria("ST_PRODUCT.ST_PRODUCT_MANUFACTURER_PARENT", "STPRODMAN", JoinType.LEFT_OUTER_JOIN, Restrictions.eq("PROD_MAN_STATUS", "ACTIVE"));
cr.createCriteria("STPRODMAN.ST_MANUFACTURER", "STMAN", JoinType.LEFT_OUTER_JOIN);
cr.createCriteria("ST_PRODUCT.ST_PRODUCT_SUPPLIER_PARENT", "STPRODSUP", JoinType.LEFT_OUTER_JOIN, Restrictions.eq("PROD_SUPPLIER_STATUS", "ACTIVE"));
cr.createCriteria("STPRODSUP.ST_SUPPLIER", "STSUP", JoinType.LEFT_OUTER_JOIN);
cr.createCriteria("ST_PRODUCT.ST_PRODUCT_RATES", "ZSTPR", JoinType.LEFT_OUTER_JOIN, Restrictions.eqProperty("ST_SUPPLIER.SUPPLIER_ID", "STSUP.SUPPLIER_ID"));
cr.createCriteria("ST_PRODUCT.ST_MEDICINE_CATEGORY", "MEDI_CAT", JoinType.LEFT_OUTER_JOIN);
cr.createCriteria("ST_PRODUCT.ST_TAX_MASTER", "TAX", JoinType.INNER_JOIN);
cr.createCriteria("ST_PRODUCT.ST_UNIT", "UNIT", JoinType.INNER_JOIN);
cr.add(Restrictions.eq("ST_PRODUCT.PRODUCT_STATUS", "ACTIVE"));
ProjectionList p1 = Projections.projectionList();
p1.add(Projections.property("ST_PRODUCT.PRODUCT_ID"));
p1.add(Projections.property("ST_PRODUCT.PRODUCT_NAME"));
p1.add(Projections.property("UNIT.UNIT_DISPLAY_UNIT"));
p1.add(Projections.property("TAX.TAX_PURCHASE"));
p1.add(Projections.property("ST_PRODUCT.PRODUCT2_DISCOUNT"));
p1.add(Projections.property("ST_PRODUCT.PRODUCT2_DIS_AMOUNT"));
p1.add(Projections.property("ST_MEDICINE_CATEGORY.CAT_CATEGORY_ID"));
p1.add(Projections.property("MEDI_CAT.CAT_SHORT_NAME"));
p1.add(Projections.property("UNIT.UNIT_ID"));
p1.add(Projections.property("TAX.TAX_ID"));
//MANUFACTURER
p1.add(Projections.property("STMAN.MAN_ID"));
p1.add(Projections.property("STPRODMAN.BASE_LEVEL"));
p1.add(Projections.property("STPRODMAN.FREE_QTY"));
//SUPPLIER
p1.add(Projections.property("STSUP.SUPPLIER_ID"));
p1.add(Projections.property("STPRODSUP.BASE_LEVEL"));
p1.add(Projections.property("STPRODSUP.FREE_QTY"));
cr.setProjection(p1);
List l = cr.list();
System.out.println("Size items::" + l.size());
ERROR SqlExceptionHelper:131 - Unknown column 'stsup4_.SUPPLIER_ID' in 'on clause'
This it the SQL generated by Hibernate
select
this_.PRODUCT_ID as y0_,
this_.PRODUCT_NAME as y1_,
unit8_.UNIT_DISPLAY_UNIT as y2_,
tax7_.TAX_PURCHASE as y3_,
this_.PRODUCT2_DISCOUNT as y4_,
this_.PRODUCT2_DIS_AMOUNT as y5_,
this_.CAT_CATEGORY_ID as y6_,
medi_cat6_.CAT_SHORT_NAME as y7_,
unit8_.UNIT_ID as y8_,
tax7_.TAX_ID as y9_,
stman2_.MAN_ID as y10_,
stprodman1_.BASE_LEVEL as y11_,
stprodman1_.FREE_QTY as y12_,
stsup4_.SUPPLIER_ID as y13_,
stprodsup3_.BASE_LEVEL as y14_,
stprodsup3_.FREE_QTY as y15_
from
ST_PRODUCTMASTER this_
left outer join
ST_MEDICINE_CATEGORY medi_cat6_
on this_.CAT_CATEGORY_ID=medi_cat6_.CAT_CATEGORY_ID
left outer join
ST_PRODUCT_MANUFACTURER stprodman1_
on this_.PRODUCT_ID=stprodman1_.PRODUCT_ID
and (
stprodman1_.PROD_MAN_STATUS=?
)
left outer join
ST_MANUFACTURER stman2_
on stprodman1_.MAN_ID=stman2_.MAN_ID
left outer join
ST_PRODUCT_RATES zstpr5_
on this_.PRODUCT_ID=zstpr5_.PRODUCT_ID
and (
zstpr5_.SUPPLIER_ID=stsup4_.SUPPLIER_ID
)
left outer join
ST_PRODUCT_SUPPLIER stprodsup3_
on this_.PRODUCT_ID=stprodsup3_.PRODUCT_ID
and (
stprodsup3_.PROD_SUPPLIER_STATUS=?
)
left outer join
ST_SUPPLIER stsup4_
on stprodsup3_.SUPPLIER_ID=stsup4_.SUPPLIER_ID
inner join
ST_TAX_MASTER tax7_
on this_.TAX_ID=tax7_.TAX_ID
inner join
ST_UNIT unit8_
on this_.UNIT_ID=unit8_.UNIT_ID
where
(
this_.PRODUCT_DELETED <> 'DELETED'
)
and this_.PRODUCT_STATUS=?
zstpr5_ is generated before stsup4_
and thus zstpr5_.SUPPLIER_ID=stsup4_.SUPPLIER_ID
is not accessible
left outer join
ST_PRODUCT_RATES zstpr5_
on this_.PRODUCT_ID=zstpr5_.PRODUCT_ID
and (
zstpr5_.SUPPLIER_ID=stsup4_.SUPPLIER_ID
)
left outer join
ST_PRODUCT_SUPPLIER stprodsup3_
on this_.PRODUCT_ID=stprodsup3_.PRODUCT_ID
and (
stprodsup3_.PROD_SUPPLIER_STATUS=?
)
left outer join
ST_SUPPLIER stsup4_
on stprodsup3_.SUPPLIER_ID=stsup4_.SUPPLIER_ID
ACTUAL EXPECTED ORDER IS
left outer join
ST_PRODUCT_SUPPLIER stprodsup3_
on this_.PRODUCT_ID=stprodsup3_.PRODUCT_ID
and (
stprodsup3_.PROD_SUPPLIER_STATUS=?
)
left outer join
ST_SUPPLIER stsup4_
on stprodsup3_.SUPPLIER_ID=stsup4_.SUPPLIER_ID
left outer join
ST_PRODUCT_RATES zstpr5_
on this_.PRODUCT_ID=zstpr5_.PRODUCT_ID
and (
zstpr5_.SUPPLIER_ID=stsup4_.SUPPLIER_ID
)
Hibernate is generating a number with table name,
1_, 2_ , 3_
even though while creating SQL this order is not maintained,
it is not even created in the order we give.
Since you haven't posted your mapping file, I'll explain how Hibernate orders the joins.
Hibernate uses the mapping xml file to figure out the order of joins, so if you have a relation in it (one-to-many or any other tag) for that table, just move it above the other table's tag.
You can read more about it here.

Add count of child table to select from parent with hibernate criteria API

How can I execute this SQL query using the Hibernate Criteria API?
SELECT c.*, count(r.id) FROM COURSE c left join REFERRAL r on c.id = r.course_id group by c.id
Something like this seems close enough:
Criteria criteria = currentSession().createCriteria(Referral.class, "r");
criteria.createAlias("r.course", "course");
ProjectionList projections = Projections.projectionList();
projections.add(Projections.groupProperty("course.id"));
projections.add(Projections.count("r.id"));
return list(criteria
.setProjection(projections));

HQL to Criteria

I am trying to create a Criteria from HQL.
Simplified HQL:
SELECT
event.pkid,
add.name
FROM Event event
LEFT JOIN event.addresses adds
JOIN adds.address add
WHERE adds is null
or adds.addressType = 'EVENT'
And I use following Criteria to produce an equivalent query.
criteria.createAlias("addresses", "adds",
CriteriaSpecification.LEFT_JOIN)
.createAlias("adds.address", "add",
CriteriaSpecification.LEFT_JOIN)
.setProjection(
Projections
.projectionList()
.add(Projections.property("pkid"))
.add(Projections
.property("add.name")))
.add(Restrictions.or(Restrictions.isNull("addresses"),
Restrictions.eq(
"adds.addressType.addressType",
"EVENT")));
But it produces following query,
select
this_.pkid as y0_,
add2_.name as y1_
from event this_
left outer join event_address_map adds1_ on this_.pkid=adds1_.event_pkid
where (this_.pkid is null or adds1_.address_type=?)
Second join is not added. What am I doing wrong?
Thanks in advance.

Categories