Flexible Search Issue SAP Hybris - java

I have a problem with a Flexible Query. This is my query:
Select
{pp.productCode} as 'Code',
{p.descriptionCics} as 'Desc CISC',
{bs.uid} as 'Store',
{evo.code} as 'Status',
{p.department} as 'Department',
{pca.name} as 'Category',
{p.grm} as 'GRM',
{p.buyerCode} as 'Code Buyer',
{p.buyerids} as 'Buyer',
{ps.planogramCode} as 'Code Planogram',
{pca.categoryCode} as 'Category Planogram',
{s.puvmBlock} as 'Blocked',
(CASE WHEN ({p.productDetailTypeList} is not null )THEN 'YES' else
'NO' END) as 'IMAGE'
from
{
Product as p
JOIN PlanogramProducts as pp on {p.code} = {pp.productCode}
JOIN StockLevel as s on {pp.productCode} = {s.productCode}
JOIN EnumerationValue as evo on {p.status} = {evo.pk}
JOIN PlanogramCategory as pc on {pp.planogramCode} =
{pc.planogramCode}
JOIN PlamnogramCategoryAnag as pca on {pc.categoryCode}=
{pca.categoryCode}
JOIN BaseStore as bs JOIN PlanogramStore as ps on {bs.storeRef} =
{ps.storeRef} AND {bs.bramchOffice} = {ps.branchOffice}
}
WHERE 1=1
and this my error when I execute it:
Can someone help me? Thanks a lot.

Your statement contains errors. You join basestore with planogramStore. But neither planogram store, nor basestore is joined with any other part of your query. You need to join basestore or planogramstore with one of the other tables.
Now you have 2 detached parts in your from statement, which is why you are getting errors
Product as p
JOIN PlanogramProducts as pp on {p.code} = {pp.productCode}
JOIN StockLevel as s on {pp.productCode} = {s.productCode}
JOIN EnumerationValue as evo on {p.status} = {evo.pk}
JOIN PlanogramCategory as pc on {pp.planogramCode} =
{pc.planogramCode}
JOIN PlamnogramCategoryAnag as pca on {pc.categoryCode}=
{pca.categoryCode}
and
JOIN BaseStore as bs JOIN PlanogramStore as ps on {bs.storeRef} =
{ps.storeRef} AND {bs.bramchOffice} = {ps.branchOffice}
you need to have a join between these 2 parts to get the correct data

Related

Spring data jpa multiple table join with subquery

This is SQL Query I have tried to join all the tables using Spring Data JPA. Some please help me out.
SELECT op.id AS "Profile ID",
op.organization_name AS "Organization name",
pav.annotation AS "legacy-sams-acc-id",
ip.subnet AS "CIDR IP range"
FROM profile.profile p
JOIN profile.organization_profile op ON op.id = p.id
JOIN profile.profile_annotation_type pat ON pat.publisher_id = p.supplier_publisher_id
LEFT OUTER JOIN
(SELECT pa.id AS id,
pa.profile_id AS profile_id,
ftpa.annotation AS annotation,
ftpa.free_text_profile_annotation_type_id AS free_text_profile_annotation_type_id
FROM profile.profile_annotation pa
JOIN profile.free_text_profile_annotation ftpa ON ftpa.id = pa.id
) AS pav ON pav.free_text_profile_annotation_type_id = pat.id AND pav.profile_id = p.id
LEFT OUTER JOIN profile.ip_range_identifier ip ON ip.organization_profile_id = op.id
WHERE pat.description = 'legacy-sams-acc-id'
AND p.supplier_publisher_id = 66
ORDER BY op.id ASC
Following will be the corresponding Java class. I'm struck with converting SQL to Java.
public Specification<OrganizationProfile> organizationProfileReportCriteria(Long publisherId) {
return (root, criteriaQuery, criteriaBuilder) -> {
Subquery<Profile> profileSubquery = criteriaQuery.subquery(Profile.class);
Root<Profile> profileRoot = profileSubquery.from(Profile.class);
Join<Profile, OrganizationProfile> profileOrganizationProfileJoin = profileRoot.join("supplierPublisher");
profileSubquery.select(profileRoot)
.where(criteriaBuilder.equal(profileOrganizationProfileJoin, root),
criteriaBuilder.equal(profileRoot.get("supplierPublisher").get("id"), publisherId));
Subquery<ProfileAnnotationType> profileAnnotationTypeSubquery = criteriaQuery.subquery(ProfileAnnotationType.class);
Root<ProfileAnnotationType> profileAnnotationTypeRoot = profileAnnotationTypeSubquery.from(ProfileAnnotationType.class);
Join<ProfileAnnotationType, OrganizationProfile> organizationProfileAnnotationTypeJoin
= profileAnnotationTypeRoot.join("publisher");
profileAnnotationTypeSubquery.select(profileAnnotationTypeRoot)
.where(criteriaBuilder.equal(organizationProfileAnnotationTypeJoin, root),
criteriaBuilder.equal(profileAnnotationTypeRoot.get("publisher").get("id"), publisherId));
Subquery<ProfileAnnotation> profileAnnotationSubquery = criteriaQuery.subquery(ProfileAnnotation.class);
Root<ProfileAnnotation> profileAnnotationRoot = profileAnnotationTypeSubquery.from(ProfileAnnotation.class);
Join<ProfileAnnotation, OrganizationProfile> profileAnnotationOrganizationJoin
= profileAnnotationRoot.join("profile");
profileAnnotationSubquery.select(profileAnnotationRoot)
.where(criteriaBuilder.equal(profileAnnotationOrganizationJoin, root),
criteriaBuilder.equal(profileAnnotationRoot.get("profile").get("supplierPublisher").get("id"), publisherId));
return criteriaBuilder.or(criteriaBuilder.exists(profileSubquery));
};
}
Basically, I'm not sure how to join multiple tables using JPA. Someone, please explain to me how to convert multiple join and Subquery for converting SQL to Java. Basically confusion about profile and Organization profile table.

H2 database: Column "U" must be in the GROUP BY list; SQL statement

My native query looks like this:
SELECT u
FROM (SELECT max(difficulty), u
FROM (SELECT sum(difficulty) AS difficulty, username AS u
FROM user_answer ua
JOIN question q ON ua.question_id = q.id
JOIN answer a ON ua.answer_id = a.id
JOIN user_quiz uq ON ua.user_quiz_id = uq.id
JOIN account ac ON uq.account_id = ac.id
WHERE a.correct = 1
AND uq.quiz_start_date_time >= (CURDATE() - INTERVAL 7 DAY)
GROUP BY ua.user_quiz_id
ORDER BY difficulty DESC) AS max_week) as d_u
Everything works fine in MySQL. I have an error in the H2 database:
org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "U" must be in the GROUP BY list; SQL statement:
SELECT u FROM (SELECT max(difficulty), u FROM (SELECT sum(difficulty) AS difficulty, username AS u FROM user_answer ua JOIN question q ON ua.question_id = q.id JOIN answer a ON ua.answer_id = a.id JOIN user_quiz uq ON ua.user_quiz_id = uq.id JOIN account ac ON uq.account_id = ac.id WHERE a.correct = 1 AND uq.quiz_start_date_time >= (CURDATE() - INTERVAL 7 DAY) GROUP BY ua.user_quiz_id ORDER BY difficulty DESC) AS max_week) as d_u [90016-200]
how to fix it?
Simply add an aggregation function around username
SELECT u
FROM (SELECT max(difficulty), u
FROM (SELECT sum(difficulty) AS difficulty, MAX(username) AS u
FROM user_answer ua
JOIN question q ON ua.question_id = q.id
JOIN answer a ON ua.answer_id = a.id
JOIN user_quiz uq ON ua.user_quiz_id = uq.id
JOIN account ac ON uq.account_id = ac.id
WHERE a.correct = 1
AND uq.quiz_start_date_time >= (CURDATE() - INTERVAL 1 MONTH)
GROUP BY ua.user_quiz_id
ORDER BY difficulty DESC
) AS max_month
GROUP BY u
) as d_u
When the option ONLY_FULL_GROUP_BY is enabled you need to have all columns with aggregation functions or have them in the GROUP By see https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html

JPA unknown column alias in 'group statement'

I got an error while running this query on java SQL but it works when I tested it on SQL editor
#Query(value = "SELECT l.loan, max(i.date) as dDate, tr.collecty, sum(i.expectedAmount) as amount,"
+ "(select CASE WHEN (br.stype = 'x') THEN br.idNumber ELSE br.np END as type from Bower br inner join Leds ld on br.id = ld.bowerId where ld.loan = :loan) as bId "
+ "FROM Loan l INNER JOIN Inst i ON l.loan = i.loan INNER JOIN TList tr ON l.loan = tr.loan WHERE l.loan = :loan GROUP BY l.loanId, tr.collecty, bId")
and got error
Caused by: java.sql.SQLSyntaxErrorException: Unknown column 'bId' in 'group statement'
how to fix it?
The order of execution of group by is before the select in a query. So, at the time you group by bId, the select query is not executed yet and it won't recognize bId column or any alias that you specify at select.
Since bId is a derived column, you can not perform aggregation using the column at the same level. You need to go one level above. Below code should work. However there is still a scope to improve the way aggregation is being performed.
#Query(value = “SELECT loan, dDate, collecty, amount, bId FROM (SELECT l.loan, max(i.date) as dDate, tr.collecty, sum(i.expectedAmount) as amount,"
+ "(select CASE WHEN (br.stype = 'x') THEN br.idNumber ELSE br.np END as type from Bower br inner join Leds ld on br.id = ld.bowerId where ld.loan = :loan) as bId ) "
+ "FROM Loan l INNER JOIN Inst i ON l.loan = i.loan INNER JOIN TList tr ON l.loan = tr.loan WHERE l.loan = :loan ) GROUP BY loan, dDate, collecty, amount, bId”)

JPA Criteria Query for Left joins

I am new to JPA and I have a Left Join scenario.
I have my native sql query as below and I am using left join to fetch the complete records from V_MONITORING table for st.id = 10001.
I have some null values for id_legislature which also needs to be selected and hence using a left join
select distinct
mv.id_set, mv.id_travel, mv.id_legislature
from
V_MONITORING mv
left join v_set st on mv.id_set = st.id
left join v_travel fg on mv.id_travel = fg.id
left join v_legislature gg on mv.id_legislature = gg.id;
The same thing I am implementing using the JPA criteria query, I am unable to fetch the null records
Below is the code
Predicate predicate = cb.conjunction();
Root<MonitoringBE> mvRoot = criteriaQuery.from(MonitoringBE.class);
mvRoot.fetch(MonitoringBE.id_set, JoinType.LEFT);
mvRoot.fetch(MonitoringBE.id_travel, JoinType.LEFT);
mvRoot.fetch(MonitoringBE.id_legislature, JoinType.LEFT);
final Path<Object> serieneinsatzterminPath= mvRoot.get(MonitoringBE.id_set);
predicate = cb.and(predicate, cb.EqualTo(serieneinsatzterminPath.get(SetBE.GUELTIG_VON_DATUM), startSetDate));
criteriaQuery.multiselect(
mvRoot.get(MonitoringBE.id_travel).alias("id_travel"),
mvRoot.get(MonitoringBE.id_set).alias("id_set"),
mvRoot.get(MonitoringBE.id_legislature).alias("id_legislature"))
.distinct(true).where(predicate);
Can some one guide me.
You have to replace the mvRoot.get(MonitoringBE.id_travel) and others in the multiselect-statement with mvRoot.join(MonitoringBE.id_travel, JoinType.LEFT). Otherwise they will end up in a inner join.

How do I write this JPQL query with subquery?

I'm trying to traduce that SQL sentence
SELECT
operationalobjective.idoperationalobjective,
pno_oo.name
FROM
public.operationalobjective,
public.policynamedobject pno_oo
WHERE
pno_oo.idpolicynamedobject = operationalobjective.idoperationalobjective AND
operationalobjective.idoperationalobjective NOT IN
(
SELECT
operationalobjective.idoperationalobjective
FROM
public.operationalobjective,
public.goal,
public.policy,
public.policynamedobject pno_oo,
public.policynamedobject pno_p
WHERE
goal.idpolicy = policy.idpolicy AND
goal.idoperationalobjective = operationalobjective.idoperationalobjective AND
pno_oo.idpolicynamedobject = operationalobjective.idoperationalobjective AND
pno_p.idpolicynamedobject = policy.idpolicy AND
policy.idpolicy = <number>
);
Having in mind Policy and OperationalObjective both extends PolicyNamedObject, I'm trying to traduce that into JPQL:
SELECT oo FROM OperationalObjective oo
WHERE oo.idoperationalobjective NOT IN
(
SELECT oo.idoperationalobjective
FROM OperationalObjective oo, Goal g, Policy p
WHERE g.policy = :policy AND g.operationalobjective = oo AND p = :policy
)
But when I execute that query via JPA, it raises an exception saying:
ERROR: missing FROM-clause entry for table <<t5>>
SELECT t7.idpolicynamedobject, t7.type, t7.description, t7.name, t0.idoperationalobjective, t0.idobjectivescategory
FROM public.OperationalObjective t0 INNER JOIN public.PolicyNamedObject t7 ON t0.idoperationalobjective = t7.idpolicynamedobject
WHERE (NOT (t0.idoperationalobjective IN
(
SELECT t5.idoperationalobjective
FROM public.OperationalObjective t1 CROSS JOIN public.Goal t2 CROSS JOIN public.policy t3
INNER JOIN public.PolicyNamedObject t4 ON t3.idpolicy = t4.idpolicynamedobject
INNER JOIN public.PolicyNamedObject t6 ON t5.idoperationalobjective = t6.idpolicynamedobject, public.OperationalObjective t5
WHERE (t2.idpolicy = ? AND t2.idoperationalobjective = t5.idoperationalobjective
AND t3.idpolicy = ?) AND t6.type = ?))) AND t7.type = ?} [code=0, state=42P01]
I've executed the SQL sentence using PgAdmin and it retrieved what I wanted, but I don't know what I am doing wrong translating it into JPQL... any idea?
Thank you in advance :)
I suspect you will need to refactor your JPQL statement to use subquery 'EXISTS' as the IN statement doesn't support a sub select. Hopefully this will point you in the right direction.
SELECT oo FROM OperationalObjective oo
WHERE NOT EXISTS
(
SELECT oosub
FROM OperationalObjective oosub
JOIN oosub.goal g
JOIN g.policy p
WHERE <<where conditions>>
)
Oracle docs

Categories

Resources