I create dao layer using spring data as follow
#Query(value="SELECT p FROM Products p INNER JOIN FETCH p.categoriesProducts cp INNER JOIN FETCH cp.categoryId c INNER JOIN FETCH p.mediasList ml ")
public List<Products> getAllProduct(Pageable pageable);
and I call it as follow
PageRequest pr = new PageRequest(0,100) ;
List<Products> ls = this.repo.getProductRepo().getAllProduct(pr) ;
my issue is I dont see the limit key word in the printed SQL in the log which is shown as follow
select products0_.id as id1_8_0_, categories1_.product_id as product_1_2_1_, categories2_.id as id1_1_2_, mediaslist3_.id as id1_4_3_, products0_.description as descript2_8_0_, products0_.discount_price as discount3_8_0_, products0_.price as price4_8_0_, products0_.prod_condition as prod_con5_8_0_, products0_.prod_number as prod_num6_8_0_, products0_.qty as qty7_8_0_, products0_.title as title8_8_0_, categories1_.category_id as category2_2_1_, categories2_.cat_name as cat_name2_1_2_, categories2_.description as descript3_1_2_, categories2_.keywords as keywords4_1_2_, categories2_.parent_id as parent_i5_1_2_, mediaslist3_.big_image_file as big_imag2_4_3_, mediaslist3_.media_type as media_ty3_4_3_, mediaslist3_.product_id as product_6_4_3_, mediaslist3_.thumb_image_file as thumb_im4_4_3_, mediaslist3_.video_file as video_fi5_4_3_, mediaslist3_.product_id as product_6_8_0__, mediaslist3_.id as id1_4_0__ from products products0_ inner join categories_products categories1_ on products0_.id=categories1_.product_id inner join categories categories2_ on categories1_.category_id=categories2_.id inner join medias mediaslist3_ on products0_.id=mediaslist3_.product_id
I am not sure what I do wrong the previous query is return 1000 rows from mysql and then it get the first 100 with the spring data but I need it to append limit 0,100 in the end of query, not sure how to do that
Related
tl;dr I have a long native query in Hibernate, that is split in multiple queries (with table as ...). This Query use inner joins that not work in hibernate (empty result), but work excellent in the SQL Console. Also if I copy/paste the query from the hibernate logs into the console.
with params as (select ca.id as calculation_id, chart_id, range_size, range_size * interval '1' minute as size
from calculation ca
inner join chart c on c.id = ca.chart_id
inner join time_range tr on tr.id = c.time_range_id
where ca.id = :calculationid),
tuple_diff as (select t.calculation_id,
t.id,
t.ohlc_id,
t.time, t.time - lag(t.time, 1) over (order by t.time) as diff
from tuple t inner join params p
on t.calculation_id = p.calculation_id),
ohlc_diff as (select o.chart_id,
o.id,
o.time,
o.time - lag(o.time, 1) over (order by o.time) as diff
from ohlc o inner join params p on o.chart_id = p.chart_id),
tuple_filtered as (select id, ohlc_id, time, diff, p.size, p.range_size
from tuple_diff t
inner join params p on chart_id = p.chart_id
where diff <> p.size),
ohlc_filtered as (select o.chart_id, o.id as ohlc_id, time
from ohlc_diff o
inner join params p on o.chart_id = p.chart_id
where o.diff <> p.size)
select t.time as time, t.range_size as size
from tuple_filtered t
left join ohlc_filtered o on t.time = o.time
where o.ohlc_id is null
order by t.time;
The long version, I have a microservice, generated with jhipster and the project runs productive with PostgreSQL and in development mode with a H2 Database. I have ohlc stockexchange time series and calculate calculations with an other microservice and store the computation in a tuple table. Sometimes I have holes in the timeline and want to recalculate them. I need to get the time difference to the last calculation. This is not an easy SQL Query, because you need to access the previous row like in Excel. I use the lag function to solve this problem. But the lag function is not the reason.
I generate a test project with an integration test to analyze the problem. The Junit Test is de.bitc.se.service.CalculationServiceIT and run with a Postgresql Testcontainer. The test also fill the SQL tables with testdata. I start to split the query in small parts.
with params as (select ca.id as ca_id,
chart_id, range_size,
range_size * interval '1' minute as size
from calculation ca
inner join chart c on c.id = ca.chart_id
inner join time_range tr on tr.id = c.time_range_id
where ca.id = :calculationid)
select ca_id, chart_id, range_size
from params
order by ca_id;
This part works like the console.
with tuple_diff as (select t.calculation_id,
t.id,
t.ohlc_id,
t.time,
t.time - lag(t.time, 1) over (order by t.time) as diff
from tuple t
where calculation_id = :calculationid)
select calculation_id, time
from tuple_diff
order by calculation_id;
The second query too, but when I try to join the query's, I got an empty result:
with params as (select ca.id as ca_id,
chart_id,
range_size, range_size * interval '1' minute as size
from calculation ca
inner join chart c on c.id = ca.chart_id
inner join time_range tr on tr.id = c.time_range_id
where ca.id = :calculationid),
tuple_diff as (select t.calculation_id,
t.id,
t.ohlc_id,
t.time,
t.time - lag(t.time, 1) over (order by t.time) as diff
from tuple t
inner join params p on p.ca_id = t.calculation_id
where calculation_id = ca_id)
select calculation_id
from tuple_diff
order by calculation_id;
When I try to join the param query (one result) with the tuple table I got no result. In the SQL console I got a result of multiple lines. I used the EntityManager to exclude Spring Data code in the splitted queries in the integration test.
I have no idea why I got no result. Is it a bug in Hibernate or a mistake?
I am constructing and running a query via this Hibernate-based code:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> criteria = cb.createTupleQuery();
Root<hisaVO> hisa = criteria.from(hisaVO.class);
Root<EstablecVO> establec = criteria.from(EstablecVO.class);
Root<DisaVO> disa = criteria.from(DisaVO.class);
Root<RedVO> red1 = criteria.from(RedVO.class);
Root<MicroredVO> microred = criteria.from(MicroredVO.class);
Root<Unidad_EjecutoraVO> ue1 = criteria.from(Unidad_EjecutoraVO.class);
Join<hisaVO,EstablecVO> j1 = hisa.join("estab");
Join<EstablecVO,DisaVO> j2 = j1.join("disa") ;
Join<EstablecVO,RedVO> j3 = j1.join("red") ;
Join<EstablecVO,MicroredVO> j4 = j1.join("microred") ;
Join<EstablecVO,Unidad_EjecutoraVO> j5 = j1.join("ue") ;
criteria.multiselect(j3.get("red_nombre"), cb.count(hisa))
.groupBy(red1.get("red_nombre"));
return em.createQuery(criteria).getResultList();
The log shows Hibernate is implementing that via this corresponding SQL:
select
redvo3_.red_nombre as col_0_0_,
count(hisavo0_.id) as col_1_0_
from
hisa hisavo0_
inner join establec establecvo6_
on hisavo0_.cod_estab=establecvo6_.COD_ESTAB
inner join disa disavo7_
on establecvo6_.cod_disa=disavo7_.id
inner join red redvo8_
on establecvo6_.cod_red=redvo8_.id
inner join microred microredvo9_
on establecvo6_.cod_mic=microredvo9_.id
inner join unidad_ejecutora unidad_eje10_
on establecvo6_.cod_ue=unidad_eje10_.id
cross join establec establecvo1_
cross join disa disavo2_
cross join red redvo3_
cross join microred microredvo4_
cross join unidad_ejecutora unidad_eje5_
group by redvo3_.red_nombre
It seems to be adding extra, unexpected cross joins at the end of the query. Why is it doing that?
You give your query multiple roots via multiple invocations of CriteriaQuery.from(). Each one after the first is reflected in the final query via a cross join. That's roughly what it means to be a query root.
You do not need to (and should not) use CriteriaQuery.from() to add entities to the query that you mean to be associated via inner joins corresponding to mapped relationships -- those you connect via a Join used as the Selection when you run your query.
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 am using hql with hibernate. I've tried to write a query over three tables. The tables are Medientyp, RaumMedientyp and Raum. I wanna read all Medientyp's from the whole table and all RaumMedientyp's from a specific raumId.
The realtions between the tables are:
Medientyp 1 <--> mc RaumMedientyp mc <--> 1 Raum
I need all as RaumMedientyp Entity.
The query i tried is:
String hql = "from RaumMedientyp rm right join rm.medientyp m inner join rm.raum r where r.id = :raumId";
Query query = getSession().createQuery(hql);
query.setInteger(":raumId", raumId);
But if i'm executing
query.list();
i've got a empty list as return.
I need to report data from 3 different tables in form of a report.
The various search combinations a user can search with are..
INS_USER_ID and DateRange
CUST_ACCT_ID
CUST_ACCT_ID and DateRange
Query..
select DISTINCT W.CUST_ACCT_ID, W.INS_USER_ID, WS.STTI_DATE, WS.STTI_AMT, WC.CMMT from T_WRK W
INNER JOIN T_WRK_STTI WS ON W.WRK_STTI_ID = WS.WRK_STTI_ID
INNER JOIN T_WRK_CMMT WC ON W.WRK_ID = WC.WRK_ID
WHERE W.CUST_ACCT_ID = 90610194 AND WS.STTI_DATE BETWEEN '01-JAN-12' AND '31-DEC-12'
select DISTINCT W.CUST_ACCT_ID, W.INS_USER_ID, WS.STTI_DATE, WS.STTI_AMT, WC.CMMT from T_WRKCS W
INNER JOIN T_WRKCS_STTI WS ON W.WRKCS_STTI_ID = WS.WRKCS_STTI_ID
INNER JOIN T_WRKCS_CMMT WC ON W.WRKCS_ID = WC.WRKCS_ID
WHERE W.INS_USER_ID = 231 AND WS.STTI_DATE BETWEEN '01-JAN-12' AND '31-DEC-12'
All are existing tables are already mapped using Hibernate/JPA.
I have read enough on the various approaches in google, can someone tell me which one of the following hibernate approaches is best suited for my scenario.
NamedQuery
NativeQuery
Criteria API
I am thinking NamedQuery, but have not seen a NamedQuery spanning across multiple tables, an example would be great. Thank you.
Example
#Entity
#NamedQuery(name="findSalaryForNameAndDepartment",
query="SELECT e.salary " +
"FROM Student e" +
"WHERE e.department.name = :deptName AND " +
" e.name = :empName")
You can as well put there an join to the department table and change the query a little bit
For date use parameters
em.createNamedQuery("xxx").setParameter("srtartDate", ...).setParameter("endDate",..)