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.
Related
I can not solve the error
Column 'cohort.id' is invalid in the select list because it is not contained
in either an aggregate function or the GROUP BY clause.
The log in my opinion is correct, if you do not use aggregate functions and grouping, then the query is working, but does not perform grouping.
#Query("select i, sum(r.dose) from Inspection i left join fetch i.cohort c
left join fetch c.parent left join fetch i.user left join i.personal p left
join i.result r where i.id in :inspection GROUP by i")
Tell us what the problem may be. I use SQL Server to be more recent 2008
That's what arrives in SQL Server Profiler
exec sp_executesql N'select inspection0_.id as col_0_0_, sum(result5_.dose)
as col_1_0_, cohort1_.id as id1_4_1_, cohort2_.id as id1_4_2_, personal3_.id
as id1_36_3_, inspection0_.id as id1_28_0_, inspection0_.cohort_id as
cohort_11_28_0_, inspection0_.date as date2_28_0_,
inspection0_.exposure_time as exposure3_28_0_, inspection0_.height as
height4_28_0_, inspection0_.intake as intake5_28_0_,
inspection0_.next_measurement as next_mea6_28_0_, inspection0_.note as
note7_28_0_, inspection0_.personal_id as persona12_28_0_, inspection0_.unit
as unit8_28_0_, inspection0_.updated as updated9_28_0_, inspection0_.user_id
as user_id13_28_0_, inspection0_.weight as weight10_28_0_, cohort1_.code as
code2_4_1_, cohort1_.name as name3_4_1_, cohort1_.parent_id as
parent_i6_4_1_, cohort1_.type as type4_4_1_, cohort1_.updated as
updated5_4_1_, cohort1_.user_id as user_id7_4_1_, cohort2_.code as
code2_4_2_, cohort2_.name as name3_4_2_, cohort2_.parent_id as
parent_i6_4_2_, cohort2_.type as type4_4_2_, cohort2_.updated as
updated5_4_2_, cohort2_.user_id as user_id7_4_2_, personal3_.birth_date as
birth_da2_36_3_, personal3_.first_name as first_na3_36_3_,
personal3_.last_name as last_nam4_36_3_, personal3_.middle_name as
middle_n5_36_3_, personal3_.sex as sex6_36_3_, personal3_.tab_number as
tab_numb7_36_3_, personal3_.transfer_id as transfer8_36_3_
from inspection
inspection0_ left outer join cohort cohort1_ on
inspection0_.cohort_id=cohort1_.id left outer join cohort cohort2_ on
cohort1_.parent_id=cohort2_.id left outer join personal personal3_ on
inspection0_.user_id=personal3_.id left outer join person person4_ on
inspection0_.personal_id=person4_.id left outer join inspection_result
result5_ on inspection0_.id=result5_.inspection_id where inspection0_.id in
(#P0)
group by inspection0_.id order by inspection0_.id asc ',N'#P0 int',1
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));
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.
I`m having some trouble translating this SQL to Hibernate Criteria. I have seached it for some time, but couldnt get any ideas as how to do it.
SELECT * FROM tableA a
INNER JOIN (
SELECT tableA_nr AS cod, max(tableA_status) as sit
FROM tableA
GROUP BY (tableA_nr)
) status_nr_list
ON a.tableA_nr = status_nr_list.cod and a.tableA_status = status_nr_list.sit
ORDER BY tableA_nr;
Here´s what I´ve accomplished so far.
criteria.setProjection(
Projections.projectionList()
.add(Projections.groupProperty("tableA_nr"))
.add(Projections.max("tableA_status.id")));
Thanks in advance!
Not sure if this works but the hint is you can use Detached Criteria for subquery.
Sub query
DetachedCriteria status_nr_list = DetachedCriteria.forClass(tableA_nr.class, "tableA_nr");
status_nr_list.setProjection(Projections.max("tableA_status"));
status_nr_list.setProjection(Projections.property("tableA_nr"));
Main query
session.createCriteria(tableA_nr.class)
.add( Subqueries.propertyIn("tableA_nr", status_nr_list) )
.add( Subqueries.propertyIn("tableA_status", status_nr_list) );
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?